STM32 使用 DMA + 双缓冲在 ADC 连续采样时,如何避免缓冲切换瞬间的数据丢失?

· 2 浏览

回答(4)

若使用ADC+DMA,务必配置ADC的DMA请求为循环模式,且DMA的‘传输完成’事件在每次缓冲区满时触发。若仍丢数据,检查DMA的FIFO是否使能(STM32F4+),并设置FIFO阈值(如半满)来减少中断频率。
电子小兵 · 2026-08-29
注意DMA的传输完成中断和半传输中断:双缓冲模式下,用半传输+全传输中断可提前处理,但需确保中断内不操作DMA寄存器(除CMAR),否则可能冲突。建议用HAL库的DMA_IRQHandler并自定义回调。
芯海拾贝 · 2026-08-29
可以增加一个‘乒乓’状态机:用两个标志位(buf0_ready, buf1_ready)控制,DMA中断只置位,主循环消费。若主循环来不及,可降低采样率或增大缓冲区深度(如用4KB),以时间换空间。
嵌入式老周 · 2026-08-29
核心思路:双缓冲的本质是让DMA在写一个缓冲区时,CPU/应用处理另一个缓冲区,但切换瞬间(即DMA传输完成中断触发时)仍可能因处理延迟导致数据覆盖。避免丢失的关键是:1)确保DMA传输完成中断优先级足够高(如设置为最高抢占优先级),且中断服务函数内只做缓冲区指针切换和标志置位,不进行耗时操作(如浮点运算、打印);2)使用循环DMA模式(而非正常模式),让DMA自动回绕到缓冲区起始地址,配合双缓冲的地址交替(通过DMA_CMAR寄存器切换),这样即使中断延迟,DMA也会继续写入当前缓冲区,不会丢失新采样值;3)为每个缓冲区设置独立的‘满标志’,在应用层轮询或中断中检查,确保处理完一个缓冲区后再允许DMA切换。实操建议:在STM32CubeMX中配置DMA为Circular模式,双缓冲使能,并开启传输完成中断(TC),在中断里用if(DMA_GetITStatus)判断是哪个缓冲区完成,然后切换CMAR地址。若采样率极高(如>1Msps),建议将DMA中断优先级设为最高,并考虑用硬件FIFO(如ADC的DMA请求)缓冲。
mcuku 阿沐 · 2026-08-29

🧰 配套工具

📊 ADC 转换