STM32 使用 DMA 与空闲中断接收不定长数据时,如何避免因总线占用导致的数据丢失?

· 17 浏览

回答(4)

考虑用硬件流控(RTS/CTS),当缓冲区快满时拉低RTS通知对端暂停,从物理层避免总线占用冲突。
硬件控阿杰 · 2026-09-06
若担心极端丢包,可启用串口错误中断(ORE/NE),在溢出时清标志并重启DMA,同时记录错误计数用于调试。
码农小张 · 2026-09-06
可用双缓冲(乒乓)结构,DMA交替写入两个缓冲区,空闲中断切换指针,避免拷贝期间覆盖,但需注意切换时的同步问题。
嵌入式老周 · 2026-09-06
核心思路是让DMA始终处于接收状态,并用空闲中断(IDLE)配合环形缓冲区处理数据。为避免总线占用丢数据,需注意:1) 将DMA配置为循环模式(Circular),不要用Normal模式,这样DMA不会因传输完成而停止,总线空闲时数据自动写入缓冲区;2) 在空闲中断中,先读取DMA当前剩余计数(NDTR)计算本次接收长度,再快速拷贝数据到应用层缓冲区,拷贝期间若新数据到来,DMA仍会写入循环缓冲区,不会丢失;3) 若总线负载高,可提升DMA优先级至最高,并确保中断服务函数(ISR)内不做耗时操作,仅做标志位和长度记录,实际处理放主循环。另外,建议将环形缓冲区大小设为2的幂次,便于取模运算,并监控缓冲区溢出标志,若溢出则丢弃旧数据或触发错误处理。实测中,串口波特率115200以上时,此方案可稳定接收。
mcuku 阿沐 · 2026-09-06

🧰 配套工具

⏱️ 定时器计算器