
ADC 虽然强大,但并不是完美的。由于半导体制造工艺、温度变化和电源波动,ADC 通常存在以下误差:
零点偏移误差:输入 0V 时,读数不是 0,而是一个小数值(比如 10 LSB)。
增益误差:输入满量程(如 3.3V)时,读数达不到 4095,或者比例不对。
非线性误差:中间的刻度不均匀。
温度漂移:温度一变,基准电压和内部电阻变了,读数跟着飘。
校准的目标:就是通过软件算法,把这些系统误差“减”掉或“除”掉,让测量值逼近真实值。
校准通常分为芯片级自校准(硬件自动)和系统级标定(软件算法)。
这是 STM32 等 MCU 内部自带的功能,用于消除芯片内部的电容失配。
时机:在 ADC 上电初始化之后,第一次转换之前。
流程:
使能 ADC:必须先上电。
复位校准:调用 ADC_ResetCalibration(),清除旧的校准因子。
启动校准:调用 ADC_StartCalibration(),硬件会自动计算内部补偿参数。
等待完成:轮询标志位,直到硬件校准结束。
这是最常用、性价比最高的方法,俗称“调零”和“调满”。
原理:假设 ADC 的输入输出是线性的( y=kx+by=kx+b ),我们只需要测出两个点,就能算出 kk (斜率/增益)和 bb (截距/偏移)。
操作:
采集零点:将 ADC 输入端短接到 GND(或输入已知低电压 VlowVlow ),读取数值 DlowDlow 。
采集满点:将 ADC 输入端接到精密基准源(如 2.5V 或 3.0V,记为 VhighVhigh ),读取数值 DhighDhigh 。
计算参数:
实际斜率: k=Vhigh−VlowDhigh−Dlowk=Dhigh−DlowVhigh−Vlow
实际偏移: b=Vlow−(Dlow×k)b=Vlow−(Dlow×k)
应用公式:以后每次读到原始数据 DrawDraw ,真实电压 Vreal=Draw×k+bVreal=Draw×k+b 。
校准参数算出来后,不能存在 RAM 里(断电就没了),要存到 Flash 的最后一页或特定的配置区。
结构体示例:
c
编辑
1typedef struct {2 float gain_factor; // 增益系数 k3 float offset_factor;// 偏移系数 b4 uint32_t crc; // 校验码,防止Flash数据出错5} ADC_Calib_Data; 启动流程:系统上电 -> 从 Flash 读取参数 -> 如果 CRC 正确则加载,否则执行一次新的校准流程。
温度补偿:
如果你的设备工作环境温差大(比如 -20℃ 到 60℃),仅做常温校准是不够的。
做法:利用 MCU 内部的温度传感器,建立“温度-偏移量”对照表。运行时根据当前温度,动态修正 ADC 的偏移系数。
多通道均衡:
如果是多路采集(如 4 路电流),不同通道之间的 PCB 走线阻抗不同会导致误差。
做法:对每一路单独进行“两点校准”,算出每一路独立的 kk 和 bb ,确保所有通道的一致性。
过采样提升精度:
在校准前,先对信号进行过采样(比如连续采 16 次取平均)。这能降低随机噪声,让校准出的 kk 和 bb 更准,甚至能把 12 位 ADC 的精度“软”提升到 14 位。
基础:DMA 用于获取大量稳定的采样数据,Flash 读写用于保存参数。
应用:电池电量计(需要极高精度的电压测量)、精密称重(需要消除零点漂移)。