如果说串口是单片机的“嘴巴”,那么 ADC 就是单片机的“眼睛”。它让单片机能够感知真实世界中连续变化的模拟信号(如光照、温度、声音、电压)。
1. 什么是 ADC?(通俗理解)
- 模拟信号(Analog):大自然中的信号,比如 0.5V, 1.25V, 3.3V,是连续不断的。
- 数字信号(Digital):单片机的大脑,只能理解 0 和 1(二进制数字)。
ADC 的角色:就像一个带有刻度的量杯。它把杯子里液面的高度(电压)转化成一个具体的数字,告诉单片机:“现在的电压是 2048”。
2. STM32 ADC 的核心参数
在 STM32F103C8T6 中,自带有一个 ADC,ADC 的性能非常强劲:
| 参数 | 数值 | 含义 |
|---|---|---|
| 分辨率 (Resolution) | 12 位 (12-bit) | 把 0~3.3V 分成 $2^{12} = 4096$ 份。 |
| 转换范围 (Range) | 0V ~ 3.3V | 超过 3.3V 可能烧毁引脚,低于 0V 读不到。 |
| 对应关系 | 0 $\to$ 0V, 4095 $\to$ 3.3V | 数值每增加 1,代表电压增加了约 0.8mV。 |
| 通道数量 | 10 个外部通道 | PA0 |
3. ADC 的内部构造 (Mermaid)
你会发现 ADC 也有很多 Channel(通道),它的原理和定时器通道类似:一个“测量核心”配合一个“多路开关”。
Multiplexer} Core[ADC 核心
12位量化] DataReg[数据寄存器
DR] end In0 --> MUX In1 --> MUX In2 --> MUX MUX --> Core Core --> DataReg DataReg --> CPU[CPU 或 DMA]
4. 三种常见的“看世界”方式
根据你对实时性的要求,ADC 有三种工作模式:
- 单次转换 (Single Conversion):点一下,看一眼。看完了就闭上眼。
- 连续转换 (Continuous Conversion):睁着眼不眨,一直看,一直更新数据。
- 扫描模式 (Scan Mode):如果有多个通道(比如同时看光敏和电位器),它会挨个看一圈。
5. 快速上手实验:读取电位器电压(轮询模式)
我们先用最简单的轮询方式(类似于按键扫描)来感受 ADC。
第一步:CubeIDE 配置 (.ioc)
- 在左侧点击 Analog -> ADC1。
- 勾选 IN1(对应引脚 PA1)。
- 在下方的 Parameter Settings:
- Continuous Conversion Mode:设为 Enabled(让它不停地转换)。
- 保存生成代码。
开启了 ADC 之后,需要注意一下这里的 ADC 分频
第二步:编写代码 (main.c)
在 main 函数的 while(1) 之前启动 ADC,在 while(1) 里读取。
注意这里也用到了 printf 和串口通讯
|
|
6. 进阶预告:为什么 ADC 最离不开 DMA?
你可能已经发现了:
- 如果 ADC 开启了连续转换,它每秒钟能产生几十万个数据。
- 如果 CPU 每次都去
GetValue,那 CPU 真的就什么都不用干了,光在那“看眼睛”了。
专业做法:开启 ADC + DMA。 让 DMA 这个“快递员”自动把 ADC 转换好的数据搬运到数组里,CPU 只需要在想看的时候去数组里翻一下就行了。
常见避坑指南
- 引脚悬空:如果你不接任何东西到 PA1,读到的数值会乱跳。这是正常的,因为引脚在感知空气中的静电电场(这叫“天线效应”)。
- 采样时间:如果信号变化很快,需要调整 Sampling Time(采样时间),让量杯有足够的时间装满水(充好电)。
扩展资料
在 CubeIDE 中选择 ADC1 时,能看到 IN0、IN1…,这些是频道选择。就像电视机有很多个频道,但只有一个屏幕,ADC 内部通常只有一个“测量器”,通过一个开关来决定现在看哪个引脚的电压
1. 什么是 IN0, IN1…?
在 STM32F103C8T6 中,ADC1 拥有 10 个外部引脚通道。它们的对应关系是固定的:
- IN0 $\to$ PA0
- IN1 $\to$ PA1
- …
- IN9 $\to$ PB1
你在 CubeIDE 里勾选了哪个 IN,就代表你告诉单片机:“我要把这个引脚当成模拟输入来用”。
2. ADC 内部框架图 (Mermaid)
为了理解那些复杂的配置项,我们来看看电压信号进入单片机后经历了什么:
Multiplexer} subgraph "采样保持与转化" SH[采样保持器
Sampling Time] SAR[12位逐次逼近器
Successive Approx] end Logic[控制逻辑
Continuous/Scan Mode] end P0 --> MUX P1 --> MUX Pn --> MUX MUX --> SH SH --> SAR SAR --> DR[数据寄存器
Data Register] Logic -.-> MUX Logic -.-> SAR DR --> CPU[CPU读取/中断] DR --> DMA[DMA搬运] style SAR fill:#f96,stroke:#333 style Logic fill:#bbf,stroke:#333
3. 配置参数详细拆解
当你点击 ADC1 的 Parameter Settings 时,最核心的配置分为三部分:
A. 基础设置 (Basic Settings)
- Data Alignment (数据对齐):通常选 Right Alignment(右对齐)。
- 解释:ADC 结果是 12 位的,但寄存器是 16 位的。右对齐就像我们在本子上写数字,个位对齐,方便直接读取数值。
- Scan Conversion Mode (扫描模式):
- 如果你勾选了多个 IN 通道(比如同时看 PA0 和 PA1),就必须 Enable。它会自动按顺序测量选中的所有通道。
- Continuous Conversion Mode (连续转换模式):
- Enable:它会像监控摄像头一样,拍完一张(转完一次)立刻拍下一张,数据永不停歇地更新。
- Disable:拍一张就闭眼,直到你再次命令它。
B. 规则组设置 (ADC_Regular_ConversionMode)
这里决定了“谁先测,测多久”。
- Number of Conversion:你要测几个通道?如果你选了 IN0 和 IN1,这里就填 2。
- Rank (排名):这是具体的顺序。
Rank 1选Channel 0,代表第一个测 PA0。Rank 2选Channel 1,代表第二个测 PA1。
- Sampling Time (采样时间):
- 这是最容易被忽视的参数! 电压进入单片机需要给内部电容充电。
- 如果电压信号“很虚”(阻抗高),你需要把这个时间调大(比如选 55.5 Cycles 或更高),测出来的电压才准。
C. 外部触发 (External Trigger)
- External Trigger Conversion Source:通常选 Regular Conversion launched by software。
- 意思是:由你在代码里写
HAL_ADC_Start来手动开启转换。你也可以设置为由定时器触发(比如每秒精准采集 1000 次)。
- 意思是:由你在代码里写
4. 为什么配置这么多?
STM32 的 ADC 设计理念是:尽可能不需要 CPU 介入。
- 最简单的配置:单通道、单次转换(你之前的实验)。
- 最专业的配置:
- 开启 Scan Mode(看多个引脚)。
- 开启 Continuous Mode(不停地看)。
- 开启 DMA(让搬运工把看的结果自动写进数组)。
- 结果:CPU 只需要在启动时下个令,然后随时去查数组就行了,完全不浪费 CPU 时间。