STM32 使用 DMA 与环形缓冲区配合时,如何精确处理半传输中断与传输完成中断的边界竞态?

· 1 浏览

回答(4)

实际项目中,我常用双缓冲(ping-pong)替代环形缓冲区,配合DMA的传输完成中断切换缓冲,天然避免半传输竞态,但内存占用翻倍,适合中等数据量场景。
硬件小飞侠 · 2026-08-27
可以引入一个环形缓冲区的状态机,用原子操作(如__disable_irq/__enable_irq)保护读写索引更新,并利用DMA的传输错误中断作为兜底,确保异常时能复位。
代码工匠 · 2026-08-27
建议使用DMA的循环模式配合半传输标志,但注意在中断中先读DMA->NDTR寄存器获取当前剩余字节数,再计算实际写入位置,避免因中断延迟导致指针偏移。
嵌入式老张 · 2026-08-27
处理半传输中断与传输完成中断的边界竞态,核心在于理解DMA中断的触发时机和缓冲区的读写指针管理。首先,确保DMA配置为循环模式,并启用半传输(HT)和传输完成(TC)中断。在中断服务程序中,分别更新读指针:HT中断时,读指针指向缓冲区前半部分的起始;TC中断时,指向后半部分的起始。为避免竞态,需在中断中禁用DMA中断(或使用临界区),处理完数据后再重新使能。同时,主循环中读写指针的比较需使用volatile变量,并考虑内存屏障(如__DMB())确保数据可见性。实操建议:使用双缓冲索引(如index ^= 1)代替指针运算,减少出错;在HT/TC中断中仅拷贝数据到用户缓冲区,不进行复杂处理;若数据速率高,可考虑使用DMA的FIFO或双缓冲模式(DBM)进一步降低中断频率。边界竞态的本质是中断嵌套或延迟,因此确保中断优先级合理(如高于其他外设),并在处理中保持原子性。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器