1. 多路ADC采集的两种模式:轮询与DMA
在嵌入式开发中,ADC(模数转换器)采集模拟信号是常见需求。当我们需要同时采集多路传感器数据时,如何高效读取ADC值就成了关键问题。我在实际项目中尝试过两种主流方案:传统的轮询模式和使用DMA的直接存储器访问模式。
轮询模式就像是你亲自去超市买东西,每次都要问售货员"有货了吗?",直到拿到商品为止。代码实现上就是通过HAL_ADC_Start()启动转换后,不断调用HAL_ADC_PollForConversion()检查转换是否完成。这种方式简单直接,但CPU需要一直等待转换完成,效率较低。
DMA模式则像是雇了个跑腿小哥,你只需要告诉他"去超市帮我买这些东西",然后就可以去做其他事情了。DMA控制器会自动把ADC转换结果搬运到指定内存位置,完全不需要CPU参与。实测下来,这种方式的效率提升非常明显。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. CubeMX配置多路ADC采集
2.1 硬件环境搭建
我使用的是STM32F407开发板,需要采集4路模拟信号。在CubeMX中配置ADC时,需要注意以下几点:
- 在Analog标签下选择ADC1
- 配置ADC参数:12位分辨率,连续转换模式,使能扫描模式
- 为每个需要采集的通道设置采样时间和顺序
- 在DMA Settings中添加DMA请求,选择循环模式
关键配置代码如下:
c复制static void MX_ADC1_Init(void)
{
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
