打印
[应用相关]

STM32 USART使用DMA设置

[复制链接]
667|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一刀一级|  楼主 | 2021-9-6 10:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用STM32库初始化USART接收数据使用DMA

1、外设时钟初始化
首先初始化需要用到的外围设备设备的时钟,需要初始化的始终有USART RX DMA使用的DMA1、USART1、USART1使用的GPIO、AFIO(如果USART的管脚需要Remap则需要打开否则不用);


  • /* DMA clock enable (USART RX using dma1) */
  • RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  • /* USART clock */
  • RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  • /* Enable GPIO clock */
  • RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);


2、初始化需要用到的外设
初始化USART使用到的AFIO和GPIO,AFIO设置USART管脚的映射,GPIO设置管脚的输入、输出状态,USART1默认(USART1_REMAP = 0)使用PA9、10作为收发管脚,而在实际硬件连接中使用了PB6、7作为收发管脚,这就需要将USART1_REMAP置为为1来实现,RX管脚需要设置为"Input floating"模式,TX管脚需要设置为"Alternate function push-pul"模式;
  • GPIO_InitTypeDef GPIO_InitStructure;
  • /* Enable the USART Pins Software Remapping, using PB6.7 as TX RX*/
  • GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
  • /* Configure USARTy Rx as input floating */
  • GPIO_InitStructure.GPIO_Pin     =     GPIO_Pin_7;
  • GPIO_InitStructure.GPIO_Mode    =     GPIO_Mode_IN_FLOATING;
  • GPIO_Init(USART_GPIO, &GPIO_InitStructure);
  • /* Configure USART Tx as alternate function push-pull */
  • GPIO_InitStructure.GPIO_Pin     =     GPIO_Pin_6;
  • GPIO_InitStructure.GPIO_Speed   =     GPIO_Speed_50MHz;
  • GPIO_InitStructure.GPIO_Mode    =     GPIO_Mode_AF_PP;
  • GPIO_Init(USART_GPIO, &GPIO_InitStructure);


3、USART接收数据DMA配置
在第一步的RCC初始化中已经使能了DMA1的时钟,在接下来的过程中就需要配置DMA,使其USART1在接收数据的时候使用DMA。STM32 DMA的配置十分容易,主要有一下选项:
  • 传输两端(内存和外设)的起始地址;
  • 传输的数据的长度,以及是否会循环滚动(传输完指定长度的数据,又自动滚回到起点坚可以实现环形FIFO);
  • 传输方向,外设到内存或内存到外设或内存到内存;
  • 传输两端(内存和外设)的地址在每次传输后是否自增;
  • 传输两端(内存和外设)地址的数据宽度(决定每次怎样复制和写入数据);
  • 设置传输使用的优先级,以及在何时会产生中断(传输出错、传输一半、传输完成);
  • /* Usart rx dma receive buffer, this address must be 256 aligned  */
  • #define USART_RX_BUF_SIZE 256
  • U8 __attribute__((aligned(256)))usart_rx_buf[USART_RX_BUF_SIZE;
  • DMA_InitTypeDef DMA_InitStructure;
  • memset(usart_rx_buf, 0, USART_RX_BUF_SIZE);

  • /* Usart1 rx using dma1 channel 6 */
  • DMA_DeInit(DMA1_Channel5);
  • /* Periph addr is usart rx data register address  */
  • DMA_InitStructure.DMA_PeripheralBaseAddr    = 0x40013804;
  • DMA_InitStructure.DMA_MemoryBaseAddr        = (uint32_t)usart_rx_buf;
  • DMA_InitStructure.DMA_BufferSize            = USART_RX_BUF_SIZE;

  • /* Usart rx data reg need not increment, rx buffer nned */
  • DMA_InitStructure.DMA_PeripheralInc         = DMA_PeripheralInc_Disable;
  • DMA_InitStructure.DMA_MemoryInc             = DMA_MemoryInc_Enable;
  • /* Once transfer one byte and using cycle mode  */
  • DMA_InitStructure.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_Byte;
  • DMA_InitStructure.DMA_MemoryDataSize        = DMA_MemoryDataSize_Byte;
  • DMA_InitStructure.DMA_Mode                  = DMA_Mode_Circular;
  • /* Using highest priority, transfer direction is perihp to memory(USART to memory)  */
  • DMA_InitStructure.DMA_Priority              = DMA_Priority_VeryHigh;
  • DMA_InitStructure.DMA_DIR                   = DMA_DIR_PeripheralSRC;
  • DMA_InitStructure.DMA_M2M                   = DMA_M2M_Disable;
  • DMA_Init(DMA1_Channel5, &DMA_InitStructure);


4、USART通讯参数设置,时能串口和DMA

经过以上几步的设置已经完成系统时钟和各种外设以及DMA的初始化工作,最后设置串口的通讯参数,并使能串口即可通讯了。


  • USART_InitTypeDef USART_InitStructure;

  • /* Usart init,38400,8bit data bit,1 stop bit, No Parity and flow control, rx tx enable */
  • USART_InitStructure.USART_BaudRate               = 38400;
  • USART_InitStructure.USART_WordLength             = USART_WordLength_8b;
  • USART_InitStructure.USART_StopBits               = USART_StopBits_1;
  • USART_InitStructure.USART_Parity                 = USART_Parity_No;
  • USART_InitStructure.USART_HardwareFlowControl    = USART_HardwareFlowControl_None;
  • USART_InitStructure.USART_Mode                   = USART_Mode_Rx | USART_Mode_Tx;
  • USART_Init(USAR1T, &USART_InitStructure);
  • /* Enable USART DMA RX request */
  • USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

/* Enable USART1 RX DMA channel */
  • DMA_Cmd(DMA1_Channel5, ENABLE);
  • /* Enable USART */
  • USART_Cmd(USART, ENABLE);



使用特权

评论回复
沙发
nawu| | 2021-10-4 12:37 | 只看该作者
适配什么型号的芯片啊

使用特权

评论回复
板凳
qcliu| | 2021-10-4 12:43 | 只看该作者
dma和普通的速度有差别吗

使用特权

评论回复
地板
tfqi| | 2021-10-4 12:51 | 只看该作者
主要用这种形式能节省cpu 的使用率

使用特权

评论回复
5
wiba| | 2021-10-4 12:56 | 只看该作者
不太会使用dma的方式

使用特权

评论回复
6
zljiu| | 2021-10-4 12:59 | 只看该作者
这种方式用好了 大大的提高效率

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

57

主题

344

帖子

0

粉丝