基于CubeMx的STM32开启DMA空闲中断进行串口不定长收发
在main.c// 接收数据缓冲区,大小按需求自定义即可优势:CPU占用率低(DMA搬运数据),实时性强(中断响应帧结束)。应用场景:适用于物联网设备、工业控制等需处理可变长度数据的系统。扩展建议:添加帧头/帧尾校验提升鲁棒性,或结合RTOS实现多任务处理。
·
基于CubeMX的STM32开启DMA空闲中断进行串口不定长收发
在嵌入式系统中,串口通信常用于设备间数据传输。传统固定长度收发效率低,而不定长数据收发能灵活处理可变长度帧(如传感器数据或命令)。通过DMA(直接内存访问) 和空闲中断(IDLE Interrupt) 结合,STM32可高效实现此功能:DMA自动搬运数据到内存,减少CPU负担;空闲中断在串口线空闲时触发,标志一帧数据接收完成。本文基于CubeMX配置和HAL库,逐步讲解实现方法。
1. 准备工作
- 硬件:STM32开发板(主包用的是STM32F103C8T6)、USB转串口模块、PC。
- 软件:STM32CubeMX、Keil MDK或STM32CubeIDE。
- 基础知识:熟悉USART通信、DMA原理和中断机制。
2. CubeMX配置步骤
CubeMX自动生成初始化代码,确保配置正确:
-
创建新工程:
- 打开CubeMX,选择目标MCU。
- 设置时钟源(HSE 8MHz),配置时钟树至系统频率72MHz(F1系列)。
-
配置串口(USART):
-
启用USART(如USART1),模式为Asynchronous。
-
参数设置:波特率115200、数据位8、停止位1、无校验。
-
引脚分配:PA9(TX)、PA10(RX),自动路由。
-
-
启用DMA传输:
- 在USART DMA Settings中,添加DMA通道:
- Direction: Peripheral To Memory(接收方向)。
- Mode: Circular(循环模式,持续接收)。
- Increment Address: Memory(内存地址自增)。
- Data Width: Byte(字节宽度)。
- 在USART DMA Settings中,添加DMA通道:
-
启用空闲中断:
- 在NVIC Settings中:
- 勾选USART全局中断(USART1 global interrupt)。
- 启用USART IDLE Interrupt(空闲中断)。
- 设置中断优先级(如Preemption priority 0)。
- 在NVIC Settings中:
-
生成代码:
- Project Manager中设置IDE(如MDK-ARM),生成代码。
- 点击GENERATE CODE,导出Keil工程。
3. 代码实现
在生成的Keil工程中添加以下代码。关键点:
- DMA接收初始化:启动DMA接收不定长数据。
- 空闲中断处理:在中断回调中处理完整帧。
- 数据帧提取:通过计算接收长度获取有效数据。
3.1 全局变量定义
在main.c
开头添加变量:
uint8_t buf_ctl[256]; // 接收数据缓冲区,大小按需求自定义即可
3.2 初始化DMA接收
在main()
函数中,启动DMA接收:
// main函数内
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); //开启串口空闲中断
HAL_UART_Receive_DMA(&huart1,buf_ctl,256); //接收DMA使能
3.3 空闲中断处理
在stm32f4xx_it.c
中,修改USART中断处理函数:
// USART1全局中断处理
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) // 获得串口空闲中断标志
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除空闲中断标志
HAL_UART_DMAStop(&huart1); // 停止DMA传输,防止数据覆盖
len = 256 - (uint8_t)__HAL_DMA_GET_COUNTER(&hdma_usart1_rx); // 计算实际接收的数据长度
buf_ctl[len]='\n'; // 在接收数据的末尾添加字符串结束符(适用于ASCII数据)
HAL_UART_Transmit(&huart1,buf_ctl,len+1,500);
memset(buf_ctl,0,sizeof(buf_ctl)); // 清空接收缓冲区
HAL_UART_Receive_DMA(&huart1, buf_ctl, 256); // 重新开启DMA,准备接收下一帧数据。
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
4. 测试与验证
- 硬件连接:
- PC串口助手(如PuTTY)通过USB转串口连接STM32的USART1。
- 开发板供电。
- 测试步骤:
- 编译下载代码到STM32。
- PC发送不定长数据(如"Hello"、“STM32 DMA”)。
- 观察回传数据:应与发送数据一致,证明收发成功。
- 常见问题:
- 数据丢失:确保DMA缓冲区足够大(如256字节)。
- 中断不触发:检查CubeMX中空闲中断是否启用,并清除标志位。
- 性能优化:减少主循环延时,使用DMA发送进一步提高效率。
5. 总结
通过CubeMX配置DMA和空闲中断,STM32实现了高效串口不定长收发:
- 优势:CPU占用率低(DMA搬运数据),实时性强(中断响应帧结束)。
- 应用场景:适用于物联网设备、工业控制等需处理可变长度数据的系统。
- 扩展建议:添加帧头/帧尾校验提升鲁棒性,或结合RTOS实现多任务处理。
其他:
感谢XTao EmbedLogs大大,参考文章链接:https://blog.csdn.net/a1547998353/article/details/139193387
更多推荐
所有评论(0)