单片机怎么把电压变成数字?|单片机动画课 06

按钮通常只问“按下没有”,但光线、温度、旋钮位置常常需要表达程度。如果一个传感器把变化变成电压,单片机怎样理解它?
它需要 ADC,也就是模数转换器。ADC 在某个时刻取得输入信息,再把它归入有限个数字等级。 数字更细,不等于天然更准。
GIF 使用理想教学模型,非芯片内部结构图、非仿真、非实测。为了看清量化台阶,图中采用虚构的 3 位、8 等分 ADC;它不代表 Uno R3 或 ESP32 的真实转换曲线。
先在时间上取一个样本
输入电压可能连续变化,程序却不能用一串有限数字保留每一个瞬间。采样,就是在选定的时刻取得输入值。

第一张图里,曲线一直向前,只有标记的位置形成样本。两次采样之间发生的细节,并没有被这几个样本完整记录下来。如果信号变化太快而采样太稀,还可能把快变化看成另一种慢变化。
因此,读取频率要与想观察的现象匹配。测一个人慢慢转动的旋钮,与观察快速音频信号,不是同一个时间要求。本课先建立这个概念,不把一条平滑插值曲线当成原始测量的全部内容。
再把电压放进一个格子
假设把 0~4V 均分为八个区间,每格宽 0.5V,编号为 0~7。这是特意简化的 3 位量化模型:因为 2 的 3 次方等于 8。

在这个模型中,2.2V 落在 2.0~2.5V 的区间,输出编号 4。2.3V 也落在同一格,仍然输出 4。可见数字暂时不变,不代表电压一点都没变;变化可能还没跨过下一个区间边界。
真实 ADC 的转换门限、端点行为、偏移和误差应以数据手册为准。这里使用均匀分格,是为了讲清“连续值变成有限编号”,不能把这张简图当成某颗芯片的精确公式。
Uno R3 的 ATmega328P 提供 10 位 ADC,常见读数是 0~1023,共 1024 个编码。多出来的位数让格子更细,但供电噪声、参考误差和器件误差不会因为位数增加而自动消失。
同一个数字,要看使用哪把尺
假设电压仍为 2.2V,把刚才教学模型的满量程从 4V 改成 3.2V。八等分后每格变成 0.4V,2.2V 就落入编号 5 的区间。

这说明原始读数是相对于量程和参考条件的编码,不是带着单位的电压。把数字换算成伏特,需要知道有效量程和转换关系。
注意:动图是在切换两套理想量尺,并没有演示“只改一个寄存器,就能任意改变真实芯片参考电压”。芯片支持哪些参考源、允许怎样配置,都有具体约束。
对于 Uno R3,可以先看懂这一个调用:
int raw = analogRead(A0); // 得到 ADC 原始编码
它不直接返回温度、亮度,也不保证返回伏特数。如果传感器输出每变化一定电压代表一度温差,还要结合传感器自己的关系式再换算。
ESP32 的情况又有区别:Arduino-ESP32 的 analogRead() 返回未校准原始值,而 analogReadMilliVolts() 返回校准后的毫伏结果。可测范围与芯片型号和衰减配置有关,不能把所有读数一律乘上“3.3/4095”就称为准确电压。
一个常见误区
“12 位一定比 10 位测得准。”位数首先描述编码分辨率。精度还取决于误差、参考、噪声和校准。更细的尺刻度,如果尺本身不准,仍然可能把数写得很精细却离真实值很远。
多个样本求平均有时能减小某些随机噪声的影响,但不能自动消除系统性偏差,也不能恢复根本没有采到的快速细节。
看完再猜
在本课 0~4V 八等分模型中,从 2.2V 变到 2.3V,数字为什么没变化?
因为两者还在同一个量化区间。你已经理解了 ADC 最重要的一步:它交给程序的是有限等级的编号。下一课,我们把这些数字串起来,看看它们怎样沿着通信线到达另一块板。
资料:Arduino 模拟输入、Espressif ADC 文档。
发现更多好玩的开源项目
专注 Arduino、开源硬件、端侧 AI 和值得收藏的开发者工具。
长按二维码关注「GitStar」
所有动画为教学原理示意,非芯片仿真、非硬件实测。网页发布:2026-09-21。