STM32 串口 (DMA + 空闲中断 + 环形缓冲区)
1. 基本概念
-
UART 空闲中断(IDLE):
- 当串口 RX 线上 连续一段时间没有数据接收,USART 外设触发 空闲中断。
- 空闲中断的主要作用是通知数据传输完成或当前帧结束。
-
DMA 接收模式:
- DMA(Direct Memory Access) 自动将串口接收到的数据存储到指定缓冲区。
- CPU 不再需要逐字节处理接收数据,提高效率。
HAL_UARTEx_ReceiveToIdle_DMA
:启动 DMA 接收,支持接收数据直到触发 空闲中断。
-
环形缓冲区:
- 通过固定大小的缓冲区 + 读写指针 实现数据的循环存储。
- 用于连续接收数据,解决 DMA 数据处理问题。
- 读写指针逻辑:
- 写指针:指向新接收数据的位置。
- 读指针:指向待处理数据的位置。
2. 流程概述
-
初始化 UART 和 DMA:
- 配置 UART 和 DMA。
- 启用 DMA 接收并启动
HAL_UARTEx_ReceiveToIdle_DMA
。
-
串口接收数据:
- 数据通过 DMA 存储到 DMA 缓冲区
uart_rx_dma_buffer
。 - 串口数据未停止时,DMA 自动接收,CPU 不参与。
- 数据通过 DMA 存储到 DMA 缓冲区
-
触发空闲中断:
- 当 RX 线上 超过一个字节时间没有数据接收,触发 空闲中断(IDLE)。
- 调用
USARTx_IRQHandler
。
-
中断处理:
- 在
USARTx_IRQHandler
中调用HAL_UART_IRQHandler
。 - HAL 库检测到 IDLE 中断,触发回调函数
HAL_UARTEx_RxEventCallback
。
- 在
-
回调函数处理接收数据:
- 在
HAL_UARTEx_RxEventCallback
中:- 计算接收到的数据长度。
- 将 DMA 缓冲区的数据拷贝到 环形缓冲区。
- 清空 DMA 缓冲区,准备下一次接收。
- 重新启动 DMA 接收
HAL_UARTEx_ReceiveToIdle_DMA
。
- 在
-
主循环读取数据:
- 通过环形缓冲区的 读写指针 提取接收到的数据,进行处理。
3. 代码展示
初始化 UART 和 DMA
void MX_USART1_UART_Init(void) {
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init