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

· 2 浏览

回答(4)

实际调试时,用逻辑分析仪抓取中断触发时序,对比NDTR值变化。若发现丢数据,检查是否在ISR中误调用了HAL_DMA_Start,这会重置传输状态。
芯片调试员 · 2026-08-27
建议用DMA的传输完成中断配合定时器或空闲检测,半传输中断仅用于预填充下一段数据。若缓冲区较小,可改用循环DMA模式(Circular),减少中断频率。
码农小飞 · 2026-08-27
补充:竞态本质是ISR优先级和主循环访问冲突。可将DMA中断优先级设为最高,并在主循环中关中断(__disable_irq)后快速更新索引,再开中断,保证原子性。
嵌入式老周 · 2026-08-27
处理STM32 DMA半传输与传输完成中断的竞态,核心是确保中断服务程序(ISR)内对缓冲区索引的原子操作。建议采用双缓冲指针(如head和tail)并配合临界区保护:在ISR中,先读取DMA的NDTR寄存器(或使用HAL的HalfCpltCallback和CpltCallback),但不要直接修改DMA配置,而是更新软件索引(如半传输时置位标志,完成时切换缓冲区)。关键点:1)在ISR内禁止嵌套中断(NVIC优先级设为相同且不抢占),避免两个中断同时进入;2)使用volatile修饰共享索引,并在主循环或低优先级任务中消费数据;3)若使用HAL,在回调中仅做标志置位,实际数据处理放主循环,避免ISR内耗时操作。实操建议:用环形缓冲区时,将半传输和完成分别映射为读指针的两次推进,并在主循环中检查标志,确保每次DMA周期内索引只被一个上下文修改。若需更高实时性,可考虑使用DMA双缓冲模式(DBM),硬件自动切换,减少软件竞态。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器