用DMA双缓冲给PC发送串口数据 和 接收PC串口数据。

理解双缓冲概念:就是利用两个数组轮流导出或导进数据。

比如定义两个缓冲区数组usart_buffer0[USART_NUM] 和 usart_buffer1[USART_NUM],数组大小USART_NUM要设置一样。

USART DMA双缓冲给PC发送数据和接收PC数据

 

给PC发送数据时:

DMA先从usart_buffer0(先假设从usart_buffer0)缓冲区拿数据发给PC,usart_buffer0发完后,DMA再从usart_buffer1中拿数据发给PC,usart_buffer1发完后,DMA再次回到usart_buffer0拿数据发给PC,循环操作。

注意:DMA在对usart_buffer1拿数据的同时,CPU可以更新usart_buffer0中的数据,同理,DMA在对usart_buffer0拿数据的同时,CPU也可以更新usart_buffer1中的数据

 接收数据也是同样的道理。

 

先看看几个问题:

 

(1)、DMA先从哪个地址拿数据发给PC?

    答:按照正常思路,觉得是先打印Memory0中的数据,而按照下面程序的配置,实测,PC先打印的数据是Memory1,这地方让我有点迷糊,有点像“后进先出”。所以后面传数组地址时,稍微注意一下。

                              USART DMA双缓冲给PC发送数据和接收PC数据

 

 

 

 

(2)、怎么知道DMA当前在对哪个缓冲区拿数据?

    答:可通过DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx);函数获取信息,

    这里使用寄存器if (DMA1_Stream5->CR&(1<<19) ) 来判断,也就是检测CR寄存器中的第bit19位。

(3)、当DMA发送完usart_buffer0后,会不会进入中断,还是等usart_buffer1发送完后进中断?

    答:每当发送完一个缓冲就会进入一次中断。

(4)、配置DMA缓冲区大小时,是配置USART_NUM还是 2*USART_NUM?  

     答: 配置大小是 USART_NUM

(5)、DMA切换缓冲区需要每次配置吗?

    答:只需配置一次,软件会自动切换。

先是头文件

#ifndef __DEBUG_USART_H
#define    __DEBUG_USART_H

#include "stm32f4xx.h"
#include <stdio.h>

#define NEW_BOARD 1
#define OLD_BOARD 0


#if NEW_BOARD  //USART2 DMA1 µÚ6¸öÊý¾ÝÁ÷ µÚ4¸öͨµÀ
#define USART_ADDRESS 0x40004404
#define DEBUG_USART                             USART2
#define DEBUG_USART_CLK                         RCC_APB1Periph_USART2
#define DEBUG_USART_BAUDRATE                    115200

#define DEBUG_USART_RX_GPIO_PORT                GPIOD
#define DEBUG_USART_RX_GPIO_CLK                 RCC_AHB1Periph_GPIOD
#define DEBUG_USART_RX_PIN                      GPIO_Pin_6
#define DEBUG_USART_RX_AF                       GPIO_AF_USART2
#define DEBUG_USART_RX_SOURCE                   GPIO_PinSource6

#define DEBUG_USART_TX_GPIO_PORT                GPIOD
#define DEBUG_USART_TX_GPIO_CLK                 RCC_AHB1Periph_GPIOD
#define DEBUG_USART_TX_PIN                      GPIO_Pin_5
#define DEBUG_USART_TX_AF                       GPIO_AF_USART2
#define DEBUG_USART_TX_SOURCE                   GPIO_PinSource5

#define RCC_AHB1Periph_DMAx                                          RCC_AHB1Periph_DMA1
#define DMAx_Streamx                                                          DMA1_Stream6
#define Rx_DMAx_Streamx                                                  DMA1_Stream5
#define DMA_ALL_IT_FLAG                                                     DMA_IT_FEIF6|DMA_IT_DMEIF6|DMA_IT_TEIF6|DMA_IT_HTIF6|DMA_IT_TCIF6
#define DMA_Channel_x                                                         DMA_Channel_4
#define DMAx_Streamx_IRQn                                                 DMA1_Stream6_IRQn
#define DMAx_Streamx_IRQHandler                                    DMA1_Stream6_IRQHandler
#define DMA_IT_TCIFx                                                        DMA_IT_TCIF6
#endif

#if OLD_BOARD //USART1 DMA2  µÚ7¸öÊý¾ÝÁ÷ µÚ4¸öͨµÀ
#define USART_ADDRESS 0x40011004
#define DEBUG_USART                             USART1
#define DEBUG_USART_CLK                         RCC_APB2Periph_USART1
#define DEBUG_USART_BAUDRATE                    115200

#define DEBUG_USART_RX_GPIO_PORT                GPIOA
#define DEBUG_USART_RX_GPIO_CLK                 RCC_AHB1Periph_GPIOA
#define DEBUG_USART_RX_PIN                      GPIO_Pin_10
#define DEBUG_USART_RX_AF                       GPIO_AF_USART1
#define DEBUG_USART_RX_SOURCE                   GPIO_PinSource10

#define DEBUG_USART_TX_GPIO_PORT                GPIOA
#define DEBUG_USART_TX_GPIO_CLK                 RCC_AHB1Periph_GPIOA
#define DEBUG_USART_TX_PIN                      GPIO_Pin_9
#define DEBUG_USART_TX_AF                       GPIO_AF_USART1
#define DEBUG_USART_TX_SOURCE                   GPIO_PinSource9


#define RCC_AHB1Periph_DMAx                                            RCC_AHB1Periph_DMA2
#define DMAx_Streamx                                                        DMA2_Stream7
#define DMA_ALL_IT_FLAG                                                    DMA_IT_FEIF7|DMA_IT_DMEIF7|DMA_IT_TEIF7|DMA_IT_HTIF7|DMA_IT_TCIF7
#define DMA_Channel_x                                                        DMA_Channel_4
#define DMAx_Streamx_IRQn                                                DMA2_Stream7_IRQn
#define DMAx_Streamx_IRQHandler                                    DMA2_Stream7_IRQHandler
#define DMA_IT_TCIFx                                                        DMA_IT_TCIF7

#endif


#define __DEBUG     //¿ªÆô´®¿Úµ÷ÊÔ

#ifdef  __DEBUG
#define DEBUG(format,...)    printf("File:"__FILE__",Line:%03d:"format"\n",__LINE__,##__VA_ARGS__) 
#else

#define DEBUG(format,...)

#endif


void Debug_USART_Config(void);
void USART_Tx_DMA_Init(uint8_t *buffer0, uint8_t*buffer1, uint32_t num);
void USART_Rx_DMA_Init(uint8_t *buffer0, uint8_t*buffer1, uint32_t num);



#endif /* __USART1_H */
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-09-11
  • 2022-12-23
  • 2021-07-01
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-31
  • 2022-12-23
  • 2022-01-05
  • 2022-12-23
  • 2022-12-23
  • 2021-06-21
  • 2022-12-23
相关资源
相似解决方案