一、ADC 是什么

ADC 的全称是 Analog-to-Digital Converter,即模拟/数字转换器。

单片机本身处理的是数字量,而现实世界中的很多信号都是模拟量,例如电压、温度、光照、压力、电流等。ADC 的作用就是把连续变化的模拟电压转换成单片机能够处理的数字量。

典型数据流可以理解为:

传感器 -> ADC -> 单片机 -> 控制 / 显示 / 通信 / 存储

例如电位器输出 0 到 3.3 V 的模拟电压,STM32 ADC 可以把它转换为 0 到 4095 的数字量。

二、常见 ADC 类型

常见 ADC 类型包括并联比较型和逐次逼近型。

1. 并联比较型 ADC

并联比较型 ADC 通常由分压部分、比较部分和编码部分组成。

特点 说明
优点 转换速度最快
缺点 成本高、功耗高、分辨率较低

并联比较型适合高速场景,但硬件资源消耗较大。

2. 逐次逼近型 ADC

逐次逼近型 ADC 通常由控制电路、数码寄存器、D/A 转换器和电压比较器组成。

特点 说明
优点 结构简单、功耗较低
缺点 转换速度相对较慢

STM32 内部 ADC 通常属于逐次逼近型 ADC。它通过逐位逼近的方式,把输入模拟电压转换为数字结果。

3. 分辨率与采样速度的矛盾

ADC 的分辨率和采样速度往往存在矛盾:

分辨率越高,通常采样速率越低
采样速率越高,通常对分辨率和精度会有更多限制

工程中需要根据实际需求权衡。例如按键电压、电池电压这类慢变化信号不需要很高采样率,而高速波形采集则更关注采样速度。

三、ADC 关键参数

1. 分辨率

分辨率表示 ADC 能辨别的最小模拟量,通常用二进制位数表示,例如 8 位、10 位、12 位、16 位等。

以 12 位 ADC 为例:

数字量范围 = 0 ~ 4095
总刻度数 = 2^12 = 4096

如果参考电压为 3.3 V,则最小刻度约为:

最小刻度 = 3.3 / 4096 ≈ 0.000805 V

也就是约 0.805 mV。

2. 转换时间

转换时间表示完成一次 A/D 转换所需的时间。

转换时间越短,单位时间内能完成的采样次数越多,采样率也越高。

STM32 ADC 的转换时间主要和以下因素有关:

  • ADC 工作时钟频率

  • 采样时间

  • ADC 分辨率

3. 精度

精度不是简单等于分辨率。

分辨率只说明 ADC 结果有多少个刻度,而精度还会受到多种误差影响,例如:

  • ADC 本身误差

  • 参考电压误差

  • 模拟输入噪声

  • 温度变化

  • PCB 走线和电源质量

  • 传感器误差

因此,12 位 ADC 不代表实际测量一定能达到 12 位有效精度。

4. 量化误差

ADC 用离散数字量近似表示连续模拟量,这个过程会产生量化误差。

可以简单理解为:模拟电压落在两个数字刻度之间时,ADC 只能选择其中一个数字值表示它,因此必然存在误差。

四、ADC 参考电压与输入范围

STM32 ADC 模拟部分通常由 VDDAVSSAVREF+VREF- 等信号决定。

信号 作用
VDDA ADC 模拟电源
VSSA ADC 模拟地
VREF+ ADC 正参考电压
VREF- ADC 负参考电压

常见使用中:

VREF- = 0 V
VREF+ = 3.3 V
ADC输入范围 = 0 V ~ 3.3 V

输入电压必须满足:

VREF- <= VIN <= VREF+

如果输入电压超过 ADC 允许范围,可能导致转换结果错误,严重时还可能损坏芯片。因此测量高于 3.3 V 的信号时,必须使用分压、电压跟随、隔离或保护电路。

五、ADC 输入通道

STM32 ADC 通过多个输入通道连接外部引脚或内部信号。

常见通道来源包括:

  • 外部 GPIO 模拟输入

  • 内部温度传感器

  • 内部参考电压

  • VBAT 或其他内部测量通道

使用外部引脚作为 ADC 输入时,需要将对应 GPIO 配置为模拟输入模式,避免数字输入结构影响采样结果。

六、规则组与注入组

STM32 ADC 通道转换分为规则组和注入组。

1. 规则组

规则组是最常用的转换组。

特点:

  • 最多可配置 16 个转换通道。

  • 转换顺序由规则序列寄存器 SQRx 控制。

  • 适合普通周期采样、连续采样和 DMA 采集。

规则组转换结果保存在:

ADCx_DR

2. 注入组

注入组可以理解为优先级更高的一组转换。

特点:

  • 最多可配置 4 个转换通道。

  • 转换顺序由注入序列寄存器 JSQR 控制。

  • 可以在规则组转换过程中插入执行。

注入组转换结果保存在:

ADCx_JDRy, y = 1 ~ 4

普通 ADC 采样场景下,优先掌握规则组即可。

七、ADC 触发源

ADC 转换需要触发源启动。

常见触发方式包括:

触发方式 说明
软件触发 程序调用函数启动转换
ADON 位触发 F1 中再次写 ADON 位可启动规则组转换
外部事件触发 由定时器、外部事件等触发 ADC 转换

规则组和注入组都可以使用外部触发,但具体可选触发源与芯片系列和 ADC 实例有关。

在工程中,软件触发适合低速、按需采样;定时器触发适合固定采样频率的场景。

八、ADC 转换时间

ADC 完成一次转换需要时间。

转换时间主要由采样时间和转换周期组成。

可以简单理解为:

总转换时间 = 采样时间 + ADC内部转换时间

以 12 位 ADC 为例,内部转换通常需要固定若干 ADC 时钟周期,再加上用户配置的采样时间。

如果采样时间设置为 239.5 个 ADC 时钟周期,且 ADC 时钟合适,一次转换时间可能达到几十微秒级。

采样时间不是越短越好。采样时间过短时,ADC 采样电容可能还没有稳定到输入电压,导致转换结果偏差变大。高阻抗信号源尤其需要更长的采样时间。

九、ADC 数据寄存器与数据对齐

规则组转换结果存放在:

ADCx_DR

注入组转换结果存放在:

ADCx_JDR1 ~ ADCx_JDR4

ADC 数据可以设置为右对齐或左对齐。

对齐方式 特点
右对齐 常用,读取结果更直观
左对齐 便于某些定点计算或兼容高位数据处理

大多数应用中使用右对齐即可。

十、ADC 中断与 DMA

1. EOC 转换结束标志

规则通道转换结束后,会产生 EOC 标志。

程序可以通过以下方式获取结果:

  • 轮询等待转换完成。

  • 开启转换完成中断。

  • 使用 DMA 自动搬运结果。

2. DMA 请求

规则组每个通道转换结束后,除了可以产生中断外,还可以产生 DMA 请求。

使用 DMA 的目的,是及时把转换好的数据传输到指定内存中,防止数据被覆盖,也减少 CPU 频繁读取 ADC 数据寄存器的负担。

DMA 特别适合:

  • 连续采样

  • 多通道扫描采样

  • 高采样率采集

  • 固定长度采样缓存

十一、单次转换、连续转换和扫描模式

ADC 常见模式包括单次转换模式、连续转换模式和扫描模式。

1. 单次转换模式

单次转换模式只触发一次转换。

转换完成后 ADC 停止,需要下一次触发才会再次转换。

适合:

  • 按键触发采样

  • 偶尔读取电池电压

  • 低频传感器采样

2. 连续转换模式

连续转换模式下,ADC 完成一次转换后会自动开始下一次转换。

适合:

  • 持续采集某个模拟量

  • 配合 DMA 自动更新采样结果

  • 需要实时监测的信号

3. 扫描模式

关闭扫描模式时,ADC 只转换规则序列或注入序列中选中的第一个通道。

开启扫描模式时,ADC 会按序转换序列中配置的多个通道。

4. 模式组合

模式组合 效果
单次转换 + 不扫描 只转换一个通道一次
单次转换 + 扫描 按序转换多个通道一次
连续转换 + 不扫描 只转换一个通道,转换完成后自动进入下一次
连续转换 + 扫描 按序转换多个通道,完成后自动进入下一轮

还有一种不连续采样模式,在 F1 手册中也称为间断模式,通常只适用于扫描模式。它可以把完整扫描序列拆成多个小段触发执行。

十二、单通道 ADC 采集

单通道采集是 ADC 最基础的使用方式。

典型目标:

采集某个模拟输入通道的电压
读取 ADC 数字量
换算为实际电压值

以 12 位 ADC、VREF+ = 3.3 V 为例:

最小刻度 = 3.3 / 4096
输入电压 = ADC_Value * 3.3 / 4096

配置步骤

使用 HAL 库进行单通道 ADC 采集时,典型流程如下:

  • 配置 ADC 工作参数并执行校准:

HAL_ADC_Init();
HAL_ADCEx_Calibration_Start();
  • 完成 ADC MSP 初始化:
HAL_ADC_MspInit();

MSP 初始化通常包括 GPIO、ADC 时钟、NVIC 等配置。

  • 配置 ADC 通道参数:

HAL_ADC_ConfigChannel();
  • 启动 A/D 转换:

HAL_ADC_Start();
  • 等待规则通道转换完成:

HAL_ADC_PollForConversion();
  • 获取 ADC 转换结果:

HAL_ADC_GetValue();

这种方式适合低速采样和简单测试。

十三、单通道 ADC + DMA 采集

当需要连续采集单个通道时,可以使用 ADC + DMA。

典型配置:

连续转换模式
不使用扫描模式
DMA 将 ADCx_DR 中的数据搬运到内存变量或数组

配置步骤

典型流程如下:

  • 初始化 DMA:

HAL_DMA_Init();
  • 将 DMA 句柄和 ADC 句柄关联:

__HAL_LINKDMA();
  • 配置 ADC 工作参数并执行校准:

HAL_ADC_Init();
HAL_ADCEx_Calibration_Start();
  • 完成 ADC MSP 初始化:

HAL_ADC_MspInit();
  • 配置 ADC 通道参数:

HAL_ADC_ConfigChannel();
  • 配置 DMA 中断优先级并使能中断:

HAL_NVIC_SetPriority();
HAL_NVIC_EnableIRQ();
  • 编写 DMA 中断服务函数:

void DMAx_Channely_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_xxx);
}
  • 启动 DMA 并开启传输完成中断:

HAL_DMA_Start_IT();
  • 启动 ADC DMA 转换:

HAL_ADC_Start_DMA();

使用 DMA 时,要注意缓冲区长度、DMA 数据宽度、ADC 数据对齐和采样频率。

十四、多通道 ADC + DMA 采集

多通道采集通常使用扫描模式配合 DMA。

典型配置:

连续转换模式
使用扫描模式
规则序列配置多个通道
DMA 将每个通道结果依次搬运到数组中

例如配置 6 个通道,则 DMA 缓冲区通常也需要至少 6 个元素:

uint16_t adc_buf[6];

每一轮扫描完成后,缓冲区中的数据对应各通道转换结果。

需要注意:

  • 通道顺序由规则序列决定。

  • DMA 数组下标要和通道顺序对应。

  • 多通道总采样周期会比单通道更长。

  • 每个通道可以根据输入阻抗设置合适采样时间。

十五、过采样与求均值

过采样和求均值可以在一定程度上提高 ADC 有效分辨率,并降低随机噪声影响。

1. 过采样基本思路

如果希望提高 N 位分辨率,需要提高采样次数,并对多次采样结果求和后右移。

常见结论:

提高 N 位分辨率,需要右移 N 位

例如,12 位 ADC 希望提高 4 位,得到近似 16 位结果,需要进行 256 次采样:

采样次数 = 4^N = 4^4 = 256

处理方式:

256 次采样结果求和 -> 右移 4 位 -> 得到提高分辨率后的结果

2. 注意事项

过采样不是万能的。

需要满足:

  • 输入信号变化不能太快。

  • 采样频率足够高。

  • 系统存在一定随机噪声,否则提升有限。

  • 累加变量位宽要足够,避免溢出。

例如 12 位 ADC 最大值为 4095,256 次累加最大为:

4095 * 256 = 1048320

因此累加变量至少应使用 32 位。

十六、内部温度传感器

STM32 内部通常集成温度传感器,可通过 ADC 内部通道读取。

使用内部温度传感器时,基本流程是:

  1. 使能内部温度传感器通道。

  2. 配置 ADC 对内部通道采样。

  3. 读取 ADC 数字量。

  4. 换算为传感器输出电压。

  5. 根据芯片手册公式换算温度。

需要注意:

  • 内部温度传感器精度有限,更适合芯片温度趋势监测。

  • 不适合作为高精度环境温度计。

  • 不同 STM32 系列的温度换算公式可能不同。

  • 采样时间通常需要设置得较长,保证内部通道采样稳定。

十七、光敏传感器采集思路

光敏二极管的核心是 PN 结,对光照强度敏感。

它具有以下特点:

概念 说明
单向导电性 工作时通常需要加反向电压
暗电流 无光照时反向电流很小
光电流 有光照时,光照越强,反向电流越大

实际电路中,可以利用光电流变化,并串联电阻,把电流变化转换为电压变化,再由 ADC 读取。

常见处理方式:

光照变化 -> 光敏器件电流变化 -> 电阻上电压变化 -> ADC采样 -> 换算光强等级

由于光敏二极管响应通常不是严格线性的,工程上常把 ADC 结果映射为 0 到 100 的光照强度等级,而不是直接计算绝对光照值。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐