核心思路是确保DMA在切换缓冲区时,CPU不会同时访问同一块内存。推荐使用DMA的双缓冲模式(DBM)并配合中断标志位:在DMA传输完成中断(TC)中,通过读取DMA_SxNDTR寄存器或使用半传输/传输完成回调,确认当前DMA正在写入哪个缓冲区,然后CPU只处理另一个缓冲区。同时,在中断服务程序(ISR)中先禁用DMA传输(或使用暂停/恢复),处理完数据后再重新使能,避免在切换瞬间发生竞争。实操建议:1) 使用STM32 HAL库的HAL_ADC_ConvCpltCallback和HalfConvCpltCallback,分别处理两个缓冲区;2) 在回调中设置一个标志位(如buffer_index),CPU主循环根据标志位处理对应缓冲区,并确保在回调中不直接操作缓冲区内容,而是通过队列或信号量通知;3) 若使用裸机,可在DMA传输完成中断中直接切换缓冲区指针(通过修改DMA_Memory0/Memory1地址),但需注意在修改前确认DMA已停止。另外,可考虑使用内存屏障(__DMB())确保数据可见性。
mcuku 阿沐 · 2026-08-27