1. ADC 基础概念:从原理到 STM32 实现
ADC,模数转换器,说白了就是把模拟电压变成数字。你想想看,单片机只能处理 0 和 1,但现实世界里的温度、声音、光照都是连续变化的模拟量。没有 ADC,这些信号单片机根本读不懂。
我刚开始做嵌入式那会儿,总觉得 ADC 就是读个电压值,简单得很。直到有一次做工业采集项目,采样值跳得像心电图,我才意识到——ADC 这玩意儿,坑多着呢。
1.1 ADC 工作原理:量化与编码
ADC 的核心就两步:采样和量化。
- 采样:把连续时间信号变成离散时间信号。每隔固定时间抓一个点。
- 量化:把连续幅值变成离散数字。比如 0~3.3V 分成 4096 份(12 位),每份约 0.8mV。
这里有个关键概念——量化误差。你想想看,模拟电压是连续的,但数字量是离散的,必然有舍入误差。12 位 ADC 的理论量化误差是 ±0.5 LSB。我在项目中遇到过,有些新手把量化误差当成噪声去滤波,结果越滤越偏。
核心公式:数字量 = (模拟电压 / 参考电压) × (2^N - 1)
其中 N 是分辨率位数,STM32F4 系列通常是 12 位。
1.2 分辨率与采样率:一对冤家
这两个参数经常被放在一起说,但很多人搞混。我简单解释一下:
| 参数 | 含义 | 典型值(STM32) | 我的经验 |
|---|---|---|---|
| 分辨率 | 能分辨的最小电压变化 | 12 位(0~4095) | 够用,但做音频采集建议用外部 16 位 |
| 采样率 | 每秒能采多少个点 | 最高 2.4Msps(单通道) | 实际跑不到,总线有瓶颈 |
分辨率越高,采样率就越低,这是 ADC 的物理限制。STM32 内部用的是逐次逼近型(SAR)架构,每次转换需要多个时钟周期。你想想看,12 位分辨率需要 12 个比较周期,再加上采样保持时间,速度自然上不去。
我曾经踩过的坑:做多通道扫描时,以为每个通道都能跑到 2.4Msps。结果一算,3 个通道轮流采,每个通道实际只有 800ksps。后来老老实实查了参考手册的时序图。
1.3 STM32 ADC 模块概述
STM32 的 ADC 模块设计得挺灵活。我以 F4 系列为例,说说它的核心特性:
- 12 位分辨率,可配置为 6/8/10/12 位
- 最多 3 个 ADC,支持同步/交替模式
- 16 个外部通道 + 2 个内部通道(温度传感器、Vrefint)
- 多种触发源:定时器、外部中断、软件触发
- DMA 支持:自动搬运数据,不占 CPU
下面这张图是我自己整理的 STM32 ADC 内部结构,你看一眼就能明白数据是怎么流出来的:
1.4 采样时间与转换时间
很多人以为 ADC 转换就是一瞬间的事。其实不是。STM32 的 ADC 转换分两段:
- 采样阶段:对输入电容充电,时间可配置(3~480 个 ADC 时钟周期)
- 转换阶段:逐次逼近,12 位分辨率需要 12 个 ADC 时钟周期
总转换时间 = 采样时间 + 12 个时钟周期。我习惯把采样时间设成 15 个周期,这样总时间就是 27 个周期。如果 ADC 时钟是 30MHz,单次转换大约 0.9μs。
我的建议:信号源阻抗高时,采样时间要加长。我曾经用 10kΩ 的传感器,采样时间设成 3 个周期,结果读数偏低。后来改成 84 个周期,数据才正常。说白了,采样时间不够,电容充不满,读数自然不准。
1.5 参考电压与测量范围
ADC 的测量范围由参考电压决定。STM32 通常有两个参考:
- Vref+:正参考,通常接 3.3V 或外部精密参考
- Vref-:负参考,通常接 GND
测量范围就是 Vref- 到 Vref+。如果 Vref+ 是 3.3V,12 位 ADC 的 LSB 就是 3.3V / 4096 ≈ 0.8mV。
这里有个细节——Vref+ 的噪声会直接耦合到测量结果中。我做过对比实验:用板载 3.3V 供电时,ADC 跳动 ±3 LSB;换成外部精密参考 ADR421,跳动降到 ±1 LSB。所以,精度要求高的项目,别省那个外部参考芯片的钱。
1.6 本章小结
ADC 的基础概念就这些。记住三件事:
- 分辨率决定精度,采样率决定速度,两者要权衡
- 采样时间不够是新手最常见的错误
- 参考电压的质量直接影响测量精度