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

· 1 浏览

回答(4)

如果采样率极高(>1Msps),考虑使用ADC的注入组或规则组多通道,但双缓冲仍适用;另外,可在中断中直接处理数据,避免RTOS调度延迟。
代码工匠 · 2026-08-27
建议用CubeMX生成代码,但双缓冲需手动修改DMA初始化结构体,设置DMA_InitStruct.DMA_Mode = DMA_MODE_CIRCULAR,并启用DMA_InitStruct.DMA_MemoryDataSize = HAL_DMA_MDATAALIGN_WORD,确保对齐。
STM32小能手 · 2026-08-27
补充:别忘了配置DMA的FIFO,开启FIFO模式并设置阈值(如半满),可减少总线冲突,提升采样稳定性。
嵌入式老张 · 2026-08-27
在STM32上实现ADC连续采样不丢码,核心是让DMA在双缓冲间无缝切换,同时CPU及时处理已满缓冲区。具体做法:1) 配置ADC为连续转换模式,触发源设为定时器(如TIM1)PWM输出,确保采样频率稳定;2) 初始化DMA为循环模式,开启双缓冲(DBM=1),设置两个缓冲区大小一致(如各存N个采样值),并启用传输完成中断(TCIF);3) 在中断服务函数中,先读取DMA的当前目标地址(DMA_GetCurrentMemoryTarget),判断哪个缓冲区已满,然后处理该缓冲区数据(如滤波、存储),处理期间DMA自动切换到另一缓冲区继续采样,避免覆盖;4) 注意缓冲区大小需大于中断处理时间对应的采样数,防止溢出;5) 若使用HAL库,可用HAL_ADC_ConvCpltCallback,但需手动管理双缓冲切换标志。实测中,建议将缓冲区设为2的幂次(如256),并优先使用DMA1(部分型号DMA2带宽更高)。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

📊 ADC 转换