STM32 使用 DMA+双缓冲在 ADC 连续采样时,如何避免缓冲区覆盖与数据错位?

· 1 浏览

回答(4)

调试时可用逻辑分析仪抓取DMA的TC和HT信号,对比实际写入位置。若发现错位,检查DMA配置的Memory-to-Peripheral方向是否错误,以及ADC的DMA请求是否在每次转换后正确触发。
硬件工程师阿强 · 2026-08-27
建议在Half/Full中断中仅置标志位,主循环处理数据,避免中断内耗时操作。若处理时间超过半缓冲周期,可增加缓冲区深度或降低采样率,否则必然覆盖。
码农小张 · 2026-08-27
注意DMA的FIFO和突发模式:若ADC采样率极高,可开启DMA的FIFO(如4字深度)并配置突发传输,减少总线占用,但需确保FIFO阈值与缓冲区对齐,否则易丢数据。
老周嵌入式 · 2026-08-27
核心方案是采用DMA循环模式+双缓冲(Half-Transfer/Full-Transfer中断),并配合乒乓切换。具体做法:配置DMA为Circular模式,数据宽度与ADC对齐(如半字),缓冲区设为两个独立数组(如buf1、buf2),每个大小等于采样点数。使能DMA的Half-Transfer和Transfer Complete中断:当半传输完成时,CPU处理buf1(此时DMA正写buf2);全传输完成时,处理buf2(DMA正写buf1)。关键点:在中断服务函数中,先读取DMA的CNDTR寄存器确认当前写入位置,再切换处理缓冲区,避免因中断延迟导致覆盖。同时,ADC连续采样需设置DMA为循环模式,且缓冲区大小必须是采样点数的整数倍,防止数据错位。建议将缓冲区放在D2RAM(若芯片支持)以降低总线冲突,并在处理时使用volatile修饰。若需更高实时性,可改用双缓冲+空闲中断(如定时器触发),但乒乓中断已足够覆盖多数场景。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

📊 ADC 转换