STM32 使用DMA+双缓冲在ADC连续采样时,如何避免缓存覆盖与触发中断丢失?

· 3 浏览

回答(4)

注意:双缓冲模式下,DMA传输完成中断会交替触发半传输和全传输,确保两个中断都处理。若使用HAL库,需在HAL_ADC_ConvHalfCpltCallback和HAL_ADC_ConvCpltCallback中分别处理,避免只处理一个导致覆盖。
STM32老司机 · 2026-08-27
中断丢失常见于中断服务函数执行时间过长。建议在中断中只做缓冲切换和置标志,数据处理放主循环。若ADC采样率极高,可考虑提高中断优先级或使用FIFO缓冲。
ADC采样专家 · 2026-08-27
补充:使用DMA双缓冲时,务必配置DMA的M0AR/M1AR为两个不同缓冲区,并开启循环模式。在中断中通过读取DMA的CR寄存器的CT位判断当前使用哪个缓冲,从而知道哪个缓冲可安全处理。
嵌入式老白 · 2026-08-27
核心方案:采用DMA双缓冲(半传输/全传输中断)配合乒乓切换,确保CPU处理一个缓冲时DMA写入另一个。具体操作:1) 配置DMA为循环模式,使能半传输和传输完成中断;2) 在中断服务函数中,先读取DMA->NDTR或使用HAL的HalfCpltCallback/FullCpltCallback,立即切换当前活动缓冲(通过修改DMA的M0AR/M1AR或使用双缓冲模式下的CT位);3) 处理数据时,使用volatile标志位防止中断重入,并在主循环中处理数据,避免在中断中做耗时操作。关键点:确保DMA传输速度低于CPU处理速度,否则仍会覆盖;若中断频率过高,可考虑在中断中仅置标志,主循环轮询处理。另外,使用HAL库时,注意在回调中先调用HAL_ADC_Stop_DMA再重新启动(若需重配),或使用LL库直接操作寄存器减少延迟。
mcuku 阿沐 · 2026-08-27