STM32 使用DMA+双缓冲在ADC连续采样中避免数据丢失的配置细节

· 2 浏览

回答(4)

若使用STM32CubeMX,注意勾选DMA的‘Circular’和‘Half Transfer Interrupt’,并确认ADC的DMA请求模式为‘Circular’,否则双缓冲不会自动循环,导致数据覆盖。
硬件调试员阿强 · 2026-08-27
双缓冲的本质是‘乒乓操作’,建议在初始化时用memset清零两个缓冲区,并在中断中只做数据拷贝或标志置位,避免在中断里做耗时处理,否则可能丢失后续中断。
代码工匠小王 · 2026-08-27
别忘了配置DMA的FIFO模式,若ADC采样率很高,建议开启FIFO并设置阈值(如半满),可减少总线冲突,但需确保FIFO大小与缓冲区匹配。
嵌入式老周 · 2026-08-27
配置DMA+双缓冲的关键在于:1) 使用DMA的循环模式(Circular Mode)并设置两个内存缓冲区(Memory Buffer 1/2),通过DMA的Half Transfer和Transfer Complete中断标志来区分当前填充的缓冲区;2) ADC需配置为连续转换模式(Continuous Conversion Mode)且DMA请求使能,确保每次转换完成自动触发DMA搬运;3) 在中断服务函数中,根据DMA->ISR的HTIF或TCIF标志,切换处理当前未使用的缓冲区(例如,若HTIF置位,则处理Buffer1,同时DMA正在写Buffer2);4) 注意缓冲区大小需为ADC数据宽度的整数倍(如16位数据时,缓冲区长度建议为采样点数×2字节),并确保DMA配置为半字(Half Word)传输;5) 启动前需清零DMA中断标志,并设置DMA优先级高于CPU任务,避免搬运延迟。实操建议:使用HAL库时,可调用HAL_ADC_Start_DMA()并启用DMA中断,在回调函数HAL_ADC_ConvHalfCpltCallback和HAL_ADC_ConvCpltCallback中分别处理两个缓冲区,同时用volatile标志位防止数据竞争。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

📊 ADC 转换