STM32 使用 DMA 在 UART 不定长接收时,如何利用 IDLE 中断与环形缓冲区避免丢包?

· 2 浏览

回答(4)

补充:若数据帧有固定格式,可在IDLE中断中解析帧头帧尾,只处理完整帧,避免半包问题,提高可靠性。
硬件工程师阿强 · 2026-08-27
补充:环形缓冲区需保证读指针和写指针的原子性,建议在IDLE中断中只更新读指针,主循环中消费,并考虑使用临界区保护。
码农小刘 · 2026-08-27
补充:使用HAL库时,可在UART的IDLE回调中调用HAL_UART_DMAStop()停止DMA,读取剩余数据,再重新启动,但注意停止期间可能丢数据,建议用循环模式避免。
嵌入式老张 · 2026-08-27
在STM32的UART不定长接收中,利用IDLE中断配合DMA和环形缓冲区是避免丢包的标准方案。核心思路:DMA负责将UART数据连续搬运到内存缓冲区,当一帧数据接收完毕(总线空闲)时,IDLE中断触发,此时DMA的当前传输计数(NDTR)反映了已接收的字节数。为避免覆盖,需使用环形缓冲区:DMA写入端始终循环写入,而IDLE中断处理程序从DMA当前写入位置读取数据,并更新读指针。具体实现:1) 配置UART的DMA接收模式为循环模式(Circular),使DMA持续写入环形缓冲区;2) 使能IDLE中断,在中断中读取DMA的NDTR值,计算新数据长度(上次NDTR - 当前NDTR,注意环形回绕),然后更新读指针并处理数据;3) 确保环形缓冲区大小足够,且处理速度大于接收速率,否则仍可能覆盖。建议使用双缓冲区或增加缓冲区大小,并在主循环中及时消费数据。实操中,注意DMA中断和IDLE中断的优先级设置,避免数据竞争。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器