3. CubeMX初始化配置(下):使能ADC1、多通道扫描模式、采样时间与DMA配置

好,咱们接着上一讲继续。上一章我们把时钟树和GPIO给捋顺了,这一章要动真格的了——配置ADC1的核心参数,再把DMA请进来帮忙搬数据。

说实话,ADC这部分我第一次接触的时候也绕了不少弯路。尤其是多通道扫描模式和DMA的配合,稍不注意就会采回来一堆乱码。今天我就把那些坑一个一个指给你看。

3.1 使能ADC1与选择多通道扫描模式

在CubeMX的Pinout & Configuration界面,找到Analog → ADC1,点击使能。你会看到右侧的芯片引脚图上,与ADC1对应的引脚会变成绿色可配置状态。

关键配置项:

  • Mode:选择 Independent mode(独立模式)
  • Scan Conversion Mode:Enabled(使能扫描模式)
  • Continuous Conversion Mode:Enabled(连续转换模式)
  • Discontinuous Conversion Mode:Disabled(禁用不连续模式)

为什么要开扫描模式?说白了,就是让ADC自己按顺序把每个通道都采一遍,不用你手动一个个去触发。我刚开始做项目时图省事,想用单通道轮询的方式采4路信号,结果CPU被死死拖住,啥也干不了。后来换成扫描模式+DMA,CPU直接解放了。

连续转换模式也要打开,这样ADC采完一轮会立刻开始下一轮,配合DMA的循环模式,数据流就不会断。

3.2 配置采样时间——这个参数别乱填

采样时间(Sampling Time)决定了ADC对输入信号采样的持续时间。CubeMX里每个通道都可以独立设置。

采样周期数 适用场景 注意事项
1.5 Cycles 低阻抗信号源(<10kΩ) 速度快,但信号源内阻大时误差明显
7.5 Cycles 中等阻抗信号源(10~50kΩ) 常用折中值,我一般默认用这个
13.5 Cycles 高阻抗信号源(50~100kΩ) 精度较好,但采样率会下降
28.5~71.5 Cycles 极高阻抗或噪声环境 采样率低,适合慢速信号

我曾经踩过的坑:有一次用ADC采集一个电位器分压信号,电位器内阻100kΩ,我图快设了1.5个周期的采样时间。结果采回来的数值跳得像心电图,后来换成28.5个周期才稳定下来。采样时间不够,ADC内部的采样电容没充满电,数据能准才怪。

我个人习惯:所有通道统一设置为13.5 Cycles。这个值对大多数传感器信号都够用,又不至于太慢。如果你的信号源内阻特别小(比如运放输出),可以降到7.5 Cycles来提升采样率。

3.3 配置DMA——让数据自己跑起来

ADC配置好之后,切换到DMA Settings选项卡,点击Add按钮添加一个DMA请求。

DMA配置参数:

  • DMA Request:选择 ADC1
  • Direction:Peripheral To Memory(外设到内存)
  • Mode:Circular(循环模式)
  • Peripheral Data Width:Half Word(16位)
  • Memory Data Width:Half Word(16位)
  • Priority:Medium 或 High

这里有几个要点我得跟你说明白:

  • 数据宽度为什么选Half Word?因为STM32的ADC分辨率最高12位,用16位(Half Word)刚好装下,8位(Byte)会截断数据,32位(Word)又浪费内存。
  • 循环模式(Circular)必须开。这样DMA传输完一轮数据后会自动重新开始,配合ADC的连续转换模式,实现不间断的数据流。
  • 优先级设Medium以上。如果系统里还有其他DMA通道(比如USART、SPI),ADC的DMA优先级最好设高一点,避免数据丢失。

一个小技巧:在DMA配置页面,记得勾选 Use FIFO 并设置为 ENABLE。FIFO可以缓冲几个数据,防止DMA请求过于频繁导致总线拥堵。我实测过,开启FIFO后ADC数据的连续性明显改善。

3.4 配置Rank与通道顺序

回到ADC1的Configuration页面,你会看到Rank列表。每个Rank对应一个采样通道,ADC会按照Rank编号从小到大依次采样。

假设我们要采3个通道:IN0、IN1、IN2。配置方法如下:

  1. 在Number of Conversion里填入 3(转换通道数)
  2. 依次配置Rank 1、Rank 2、Rank 3:
    • Rank 1:Channel IN0,Sampling Time 13.5 Cycles
    • Rank 2:Channel IN1,Sampling Time 13.5 Cycles
    • Rank 3:Channel IN2,Sampling Time 13.5 Cycles

注意:Rank的顺序决定了DMA缓冲区里数据的排列顺序。比如Rank1是IN0,Rank2是IN1,那么DMA缓冲区里第一个16位数据就是IN0的值,第二个是IN1的值。这个顺序一定要记清楚,不然你写代码解析数据时会搞混。

3.5 生成代码前的最后检查

在点击Generate Code之前,我建议你对照下面这个清单再过一遍:

检查项 正确配置 常见错误
ADC1 Mode Independent mode 选成了Dual mode(双ADC模式)
Scan Conversion Mode Enabled 忘记使能,导致只采第一个通道
Continuous Conversion Mode Enabled 没开,采一轮就停了
Number of Conversion 与实际通道数一致 填少了,后面的通道不采
DMA Mode Circular 选了Normal,传输一次就停
Data Width Half Word 选了Byte导致数据截断

嗯,检查完这些,就可以放心生成代码了。下一章我们会分析生成的代码结构,看看HAL库到底帮我们做了哪些事,还有哪些需要我们手动补全。

3.6 本章知识结构图

下面这张图把ADC1多通道+DMA的配置流程串起来了,你可以对照着检查自己的配置有没有遗漏。

ADC1多通道+DMA配置流程 ADC1多通道+DMA配置流程 使能ADC1 扫描模式 + 连续转换 Scan & Continuous Enabled 配置Rank & 采样时间 Number of Conversion = 3 配置DMA Circular + Half Word Generate Code ⚠️ 常见遗漏 • 忘记使能扫描模式 • Rank顺序与预期不符 • DMA模式选了Normal • 数据宽度选了Byte 💡 建议 • 采样时间统一13.5 Cycles • DMA优先级设Medium以上 • 开启DMA FIFO

这张图把整个配置链路画得很清楚。你可以在CubeMX里照着这个顺序一步步来,每完成一步就打个勾,基本不会漏。

3.7 小结

这一章我们把ADC1的多通道扫描模式、采样时间、DMA循环传输这些核心配置都讲透了。说白了,配置的关键就三点:

  • 扫描模式+连续转换——让ADC自己跑起来
  • 采样时间别太小——尤其是高阻抗信号源
  • DMA循环模式+Half Word——数据自动搬运,不丢不截

这些配置在CubeMX里都是鼠标点几下的事,但背后的原理一定要吃透。不然出了问题,你连从哪下手排查都不知道。