STM32 使用DMA+双缓冲采集ADC时,如何精确计算采样时刻并避免数据覆盖?

· 1 浏览

回答(4)

若需要高精度时间戳,可在DMA中断中读取TIM->CNT,但注意中断延迟。更优方案是使用DMA的硬件时间戳功能(部分STM32支持),或使用定时器输入捕获同步。
信号链工程师 · 2026-08-27
双缓冲防覆盖的关键是确保CPU处理速度大于DMA填充速度,否则即使双缓冲也会丢数据。建议用RTOS或中断优先级管理,并考虑DMA传输完成标志的原子操作。
ADC小能手 · 2026-08-27
用定时器触发ADC时,采样时刻就是定时器更新事件的瞬间,但ADC实际采样有延迟(采样时间+转换时间),需在代码中补偿这个固定延迟,可用逻辑分析仪校准。
嵌入式老张 · 2026-08-27
精确计算采样时刻的核心是理解DMA传输与ADC采样的时序关系。首先,配置ADC为定时器触发(如TIM1/8的TRGO),并设置采样时间(如1.5周期)和转换时间(采样+12.5周期),则采样时刻为触发沿后的采样时间点,可由定时器计数值精确推算。为避免数据覆盖,双缓冲需配合DMA的循环模式和半传输/传输完成中断:当DMA传输半满时,CPU处理缓冲区A;全满时处理B,确保在下一个半周期完成前处理完数据。实操建议:1)使用HAL库的HAL_ADC_ConvCpltCallback和HalfConvCpltCallback,在回调中切换缓冲区指针;2)设置DMA为循环模式,并确保缓冲区大小足够(如采样点数×2字节),且DMA传输宽度与ADC数据宽度一致;3)在中断中记录当前DMA传输的剩余计数(__HAL_DMA_GET_COUNTER),结合定时器周期计算精确采样时刻。注意:若采样率过高导致中断处理不及时,可增加缓冲区深度或使用乒乓缓冲的变体(如四缓冲)。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

📊 ADC 转换