如何用STM32的DMA双缓冲机制实现ADC连续采样且不丢数据?

· 2 浏览

回答(4)

注意DMA双缓冲在F1系列不支持,需要F3/F4/H7等。若用F1,可用两个DMA通道或单缓冲+半传输中断模拟。另外,ADC的DMA请求优先级要高于其他外设,防止总线竞争丢数据。
芯片调试员 · 2026-08-27
双缓冲的关键是‘处理速度’匹配‘采样速度’。如果CPU处理慢,可以改用‘环形缓冲’配合DMA半传输中断,但双缓冲更简单。建议用定时器触发ADC,这样采样率可控,避免DMA溢出。
STM32实战派 · 2026-08-27
用HAL库时,记得调用HAL_ADC_Start_DMA并传入双缓冲地址,然后重写HAL_ADC_ConvCpltCallback,在回调里用HAL_DMA_GetCurrentTarget判断当前缓冲,处理另一个。别忘了设置DMA的FIFO或突发模式提升效率。
嵌入式老白 · 2026-08-27
实现STM32 ADC连续采样不丢数据,关键在于利用DMA双缓冲(也叫乒乓缓冲)机制,让DMA在后台交替填充两个缓冲区,同时CPU处理已填充的缓冲区。具体步骤:1)配置ADC为连续转换模式,触发源设为定时器或软件,确保采样率稳定;2)配置DMA为循环模式,方向外设到内存,数据宽度半字(16位,匹配ADC输出);3)启用DMA双缓冲模式(如STM32F4的DMA_CTRLB寄存器或HAL库的hdma->Init.Mode = DMA_CIRCULAR,并设置两个内存地址),通过DMA_SetDoubleBuffer或HAL_DMAEx_MultiBufferStart配置两个缓冲区;4)在DMA传输完成中断(TC)中,判断当前活动缓冲区(通过DMA_GetCurrentMemoryTarget或HAL_DMA_GetCurrentTarget),切换处理非活动缓冲区。注意:缓冲区大小需为2的幂次方,且处理速度要快于采样周期,否则仍可能丢数据。建议使用中断或RTOS信号量通知处理任务,避免在中断中做耗时操作。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

📊 ADC 转换