处理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