单片机
返回首页

STM32 USART使用DMA设置

2024-10-22 来源:cnblogs

1、外设时钟初始化

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


  1. /* DMA clock enable (USART RX using dma1) */

  2. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  3.     

  4. /* USART clock */

  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);


  6. /* Enable GPIO clock */

  7. 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'模式;

  1. GPIO_InitTypeDef GPIO_InitStructure;


  2. /* Enable the USART Pins Software Remapping, using PB6.7 as TX RX*/

  3. GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);


  4. /* Configure USARTy Rx as input floating */    

  5. GPIO_InitStructure.GPIO_Pin     =     GPIO_Pin_7;

  6. GPIO_InitStructure.GPIO_Mode    =     GPIO_Mode_IN_FLOATING;

  7. GPIO_Init(USART_GPIO, &GPIO_InitStructure);

  8.   

  9. /* Configure USART Tx as alternate function push-pull */

  10. GPIO_InitStructure.GPIO_Pin     =     GPIO_Pin_6;

  11. GPIO_InitStructure.GPIO_Speed   =     GPIO_Speed_50MHz;

  12. GPIO_InitStructure.GPIO_Mode    =     GPIO_Mode_AF_PP;

  13. GPIO_Init(USART_GPIO, &GPIO_InitStructure);

3、USART接收数据DMA配置

在第一步的RCC初始化中已经使能了DMA1的时钟,在接下来的过程中就需要配置DMA,使其USART1在接收数据的时候使用DMA。STM32 DMA的配置十分容易,主要有一下选项:

  • 传输两端(内存和外设)的起始地址;

  • 传输的数据的长度,以及是否会循环滚动(传输完指定长度的数据,又自动滚回到起点坚可以实现环形FIFO);

  • 传输方向,外设到内存或内存到外设或内存到内存;

  • 传输两端(内存和外设)的地址在每次传输后是否自增;

  • 传输两端(内存和外设)地址的数据宽度(决定每次怎样复制和写入数据);

  • 设置传输使用的优先级,以及在何时会产生中断(传输出错、传输一半、传输完成);

  1. /* Usart rx dma receive buffer, this address must be 256 aligned  */

  2. #define USART_RX_BUF_SIZE 256

  3. U8 __attribute__((aligned(256)))usart_rx_buf[USART_RX_BUF_SIZE];



  4. DMA_InitTypeDef DMA_InitStructure;

  5. memset(usart_rx_buf, 0, USART_RX_BUF_SIZE);


  6. /* Usart1 rx using dma1 channel 6 */

  7. DMA_DeInit(DMA1_Channel5); 


  8. /* Periph addr is usart rx data register address  */

  9. DMA_InitStructure.DMA_PeripheralBaseAddr    = 0x40013804;

  10. DMA_InitStructure.DMA_MemoryBaseAddr        = (uint32_t)usart_rx_buf;

  11. DMA_InitStructure.DMA_BufferSize            = USART_RX_BUF_SIZE;


  12. /* Usart rx data reg need not increment, rx buffer nned */

  13. DMA_InitStructure.DMA_PeripheralInc         = DMA_PeripheralInc_Disable;

  14. DMA_InitStructure.DMA_MemoryInc             = DMA_MemoryInc_Enable;

  15. /* Once transfer one byte and using cycle mode  */

  16. DMA_InitStructure.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_Byte;

  17. DMA_InitStructure.DMA_MemoryDataSize        = DMA_MemoryDataSize_Byte;

  18. DMA_InitStructure.DMA_Mode                  = DMA_Mode_Circular;           

  19. /* Using highest priority, transfer direction is perihp to memory(USART to memory)  */    

  20. DMA_InitStructure.DMA_Priority              = DMA_Priority_VeryHigh;

  21. DMA_InitStructure.DMA_DIR                   = DMA_DIR_PeripheralSRC;

  22. DMA_InitStructure.DMA_M2M                   = DMA_M2M_Disable;

  23. DMA_Init(DMA1_Channel5, &DMA_InitStructure);

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

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


  1. USART_InitTypeDef USART_InitStructure;


  2. /* Usart init,38400,8bit data bit,1 stop bit, No Parity and flow control, rx tx enable */

  3. USART_InitStructure.USART_BaudRate               = 38400;

  4. USART_InitStructure.USART_WordLength             = USART_WordLength_8b;

  5. USART_InitStructure.USART_StopBits               = USART_StopBits_1;

  6. USART_InitStructure.USART_Parity                 = USART_Parity_No;

  7. USART_InitStructure.USART_HardwareFlowControl    = USART_HardwareFlowControl_None;

  8. USART_InitStructure.USART_Mode                   = USART_Mode_Rx | USART_Mode_Tx;

  9. USART_Init(USAR1T, &USART_InitStructure);


  10. /* Enable USART DMA RX request */

  11. USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

 

 /* Enable USART1 RX DMA channel */

  1. DMA_Cmd(DMA1_Channel5, ENABLE);


  2. /* Enable USART */

  3. USART_Cmd(USART, ENABLE);


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 基于IC555的可变PWM振荡器电路

  • 优化电路板布局的简单方法

  • 如何使用LED驱动器LM3915制作振动计

  • 分享一个电网倾角计电路

  • 电谐波图形均衡器示意图

  • 一种构建12V和230V双直流电源的简单方法

    相关电子头条文章