STM32实现DMA接收串口数据

简介: STM32实现DMA接收串口数据

一..首先我们得配置DMA和USARAT,我们的原理是DMA1的通道5为USART1的RX引脚。

1.USART1的配置

1. void USART_Config(void)
2. {
3.  GPIO_InitTypeDef GPIO_InitStructure;
4.  USART_InitTypeDef USART_InitStructure;
5.     NVIC_InitTypeDef NVIC_InitStruct;
6.  // 打开串口GPIO的时钟
7.  DEBUG_USART_GPIO_APBxClkCmd(RCC_APB2Periph_USART1, ENABLE);
8. //打开USART1外设时钟
9.  DEBUG_USART_APBxClkCmd(USART1, ENABLE);
10. 
11.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
12.   NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
13.   NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
14.   NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
15.   NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;
16.   NVIC_Init(&NVIC_InitStruct);
17. 
18.   // 将USART Tx的GPIO配置为推挽复用模式
19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
20.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
21.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
22.   GPIO_Init(GPIOA , &GPIO_InitStructure);
23. 
24. // 将USART Rx的GPIO配置为浮空输入模式
25.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
26.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
27.   GPIO_Init(GPIOA, &GPIO_InitStructure);
28. 
29.   // 配置串口的工作参数
30.   // 配置波特率
31.   USART_InitStructure.USART_BaudRate = 115200;
32.   // 配置 针数据字长
33.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
34.   // 配置停止位
35.   USART_InitStructure.USART_StopBits = USART_StopBits_1;
36.   // 配置校验位
37.   USART_InitStructure.USART_Parity = USART_Parity_No ;
38.   // 配置硬件流控制
39.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
40.   // 配置工作模式,收发一起
41.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
42.   // 完成串口的初始化配置
43.   USART_Init(USART1, &USART_InitStructure); 
44.   //使能空闲中断
45.   USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
46.   // 使能串口
47.   USART_Cmd(USART1, ENABLE);      
48. }

2.DMA的配置

1. void USARTx_DMA_Config(void)
2. {
3.    DMA_InitTypeDef DMA_InitStructure;
4.    // 开启DMA时钟
5.    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
6. 
7.    // 设置DMA源地址:串口数据寄存器地址*/
8. //此处为USART1的DR寄存器地址为(USART1_BASE+0x04) 可以通过查询得知
9.         DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_BASE+0x04;
10.     // 内存地址(要传输的变量的指针)
11.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ReceiveBuff;//此处是我们定义的一个数组
12.     // 方向:从外设到内存  
13.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
14.     // 传输大小  我们
15.     DMA_InitStructure.DMA_BufferSize = 1024;
16.     // 外设地址不增     
17.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
18.     // 内存地址自增
19.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
20.     // 外设数据单位 
21.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
22.     // 内存数据单位
23.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;  
24.     // DMA模式,一次或者循环模式
25. //    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
26. //这里我们循环发送 因为接收上位机数据不止一次
27.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 
28.     // 优先级:中  
29.     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 
30.     // 禁止内存到内存的传输
31.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
32.     // 配置DMA通道       
33.     DMA_Init(DMA1_Channel5, &DMA_InitStructure);    
34.     // 使能DMA
35.     DMA_Cmd (DMA1_Channel5,ENABLE);
36. //USART1向DMA发送RX请求 这里对应的是DMA1的通道5
37. USART_DMACmd(USART1,  DMA1_Channel5, ENABLE);
38. }

二.中断进行数据处理(stm32f10x_it.c)

1. void USART1_IRQHandler(void)
2. {
3. 
4.  //因为是空闲中断,接收到一帧数据后才能进入中断
5.  if(USART_GetITStatus(DEBUG_USARTx,USART_IT_IDLE) == SET) //检查中断是否发生
6.  { 
7.    DMA_Cmd(DMA1_Channel5,DISABLE); //关闭DMA传输,进行数据处理,数据处理完再开启
8.      /*
9.           这里可以进行数据处理,由于是模板就没进行
10.     */
11. 
12.     DMA_Cmd(DMA1_Channel5,ENABLE);//开启DMA传输 此时开启DMA传输不耽误CPU工作
13. 
14.     USART_ReceiveData(USART1); //读取一次数据,不然会一直进中断
15.     USART_ClearFlag(USART1,USART_FLAG_IDLE);  //清除串口空闲中断标志位
16.   }
17. 
18. }

我们可以串口打印出数组中的数据,验证DMA是否正常工作。可以到数据处理那个地方进行处理。USART1在初始化中就已经波特率为115200.我们可以与上位机相连,进行测试。

然后有什么不懂的地方可以在评论区留言

目录
相关文章
|
14天前
|
存储 数据管理 数据处理
处理STM32 DMA方式下的HAL_UART_ERROR_ORE错误
通过正确配置UART和DMA、实现有效的错误处理回调函数以及优化数据处理和缓冲区管理,可以有效处理STM32中DMA方式下的 `HAL_UART_ERROR_ORE`错误。这些方法确保了数据的高效传输和处理,避免了因数据溢出导致的通信中断和数据丢失。希望这些解决方案能够帮助您在实际应用中更好地应对和解决此类问题。
88 0
|
4月前
STM32CubeMX 串口收发一帧数据
STM32CubeMX 串口收发一帧数据
56 9
|
4月前
|
芯片
STM32CubeMX 串口数据收发
STM32CubeMX 串口数据收发
139 2
|
4月前
|
监控
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
280 0
|
5月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
431 2
|
4月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
700 0
|
6月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结
|
5月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
506 4
|
5月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
676 2