☰
ADC转换实战汇总:采样原理、噪声抑制与校准技巧
2026/10/14 1:44:12 网站建设 项目流程

我调试一块板子上的电池电压采样时,被ADC读数折磨得够呛:输入电压纹丝不动,采集值却在一两百个数之间来回跳。查了几天,最后发现问题根本不在ADC自身——参考电压引脚旁边缺了一颗退耦电容,采样结果自然跟着参考源一起抖。从那以后我就养成了一个习惯:遇到ADC转换结果不准,先别急着怀疑芯片坏了,按“原理—噪声—算法—校准”这条线逐层排查,大部分问题都能定位。

这篇内容就是把这几年跟ADC转换打交道的经验汇总出来。从采样原理中最核心的保持电容与量化误差,到取平均时算术平均与滑动平均怎么选,再到精度层面参考电压、输入阻抗、校准方法的影响,配合几个可以直接抄的工程参数建议。无论你是在做电池电压检测、传感器采集还是电流采样,读完应该都能少踩几个坑。

1. ADC到底在做什么:从电压到数字的一次翻译

1.1 采样保持:为什么ADC需要“定格”瞬间值

ADC转换(模数转换)的本质,是把一个连续的模拟电压信号切成一个个离散的数字值。但这件事不像读数那么轻松,因为转换需要时间——芯片内部的处理电路从拿到电压到输出数字结果,总有个过程。如果在这个过程中输入电压一直在变化,转换结果就会“糊”掉,谁也说不清你采到的到底是哪个时刻的电压。

所以几乎所有逐次逼近型ADC(SAR ADC)内部都有一个采样保持电路,它的角色相当于“按下快门”:先通过一个开关接通输入信号,让内部的保持电容充电,让电容电压跟着输入走一小段时间;然后断开开关,电容就把这一刻的电压“定格”住,直到转换完成。这个“定格”的电压,才是后续量化电路真正处理的输入。

这里有一个非常关键的工程参数叫采样时间。你给这电容的充电时间越短,就越要求输入信号源能快速把电容充满。如果信号源输出阻抗过大,充电时间常数RC太大,电容电压还没追上输入电压开关就断开了,结果就是采样值偏低——这是很多人遇到的“读数偏小”问题的常见原因之一。后面讲精度时还会专门展开。

1.2 量化与分辨率:位数的真实含义

采样保持之后,电压信号进入量化阶段。量化就是把连续的电压幅度划分为有限个台阶,每个台阶对应一个数字编码。一个12位ADC,就是把参考电压Vref(比如3.3V)从0到Vref分成4096个台阶,每个台阶对应1 LSB,也就是1个最低有效位:

1 LSB = Vref / 2^N

代入一下:12位ADC,参考电压3.3V,1 LSB ≈ 0.000806V,约0.8mV。这意味着,你输入2.000V得到的数字值,和输入2.0008V得到的数字值,从数字结果上看可能完全一样——ADC的“分辨率天花板”就摆在那里,不是软件能突破的。

这里必须澄清一个很多人混为一谈的概念:分辨率不等于精度。分辨率只是ADC能分辨的最小步进,而精度是实际测量值与真实电压之间的接近程度。一个12位ADC如果参考电压噪声很大,可能分辨率很高但精度很差;反过来,一个10位ADC经过精心校准,精度反而可能超过那个未经校准的12位ADC。理解这个区别,后续很多调试方向就不会跑偏。

量化过程还有一个绕不开的量化误差,理论最大为±0.5 LSB。这个误差本质上是信息丢失——电压落在两个台阶之间时,ADC只能选其中一个最近的台阶。它不是芯片缺陷,而是所有ADC的原理性误差。

1.3 转换时钟与采样时间:快不等于好

如果你翻过单片机手册的ADC章节,一定会看到“最大转换频率”和“最小采样时间”两个指标。以常见的12位逐次逼近型ADC为例,芯片内部要求一定频率范围内的ADC时钟,然后规定最短采样时间(比如1.5个ADC时钟周期)和转换时间(比如12.5个周期)。

很多新手容易这样操作:把ADC时钟拉到最大值,总转换时间压到最短,结果发现测量结果波动变大。原因在于,采样时间太短时,内部采样电容没有足够时间充满,尤其当信号源阻抗偏高时,误差会被进一步放大。此外,过高的转换时钟会引入更多内部数字开关噪声,对模拟结果造成干扰。

实际项目中我一般不建议把ADC设为“极限高速”模式,除非你确实需要极高的采样率。多数应用场景,比如电池电压检测、温度采集,采样率哪怕只有几百赫兹也完全够用。此时把采样时间适当放宽(比如软件里配置成最大采样周期),往往能显著改善读数的稳定性。快不是目的,准确才是。

2. 读数乱跳的根源:噪声来自哪里

2.1 参考电压的抖动:精度的大本营

ADC转换的本质是把输入电压与参考电压做比较。说得直白点,参考电压就是ADC的“标尺”——标尺本身不准,量什么都白搭。参考电压的抖动、漂移、纹波,会直接叠加到所有转换结果里。

内部参考源的优势是使用方便,有些芯片还能在软件里调节参考电压值,但它的温漂系数和噪声水平通常不如外部专用参考芯片。如果你做的是工业级产品,要求在全温范围内保持稳定,强烈建议使用外部参考芯片,选型时重点关注两个指标:温漂系数(ppm/°C)和噪声峰峰值。举例来说,一个温漂50ppm/°C的外部参考,常温下3.0V很准,温度升到85°C时,参考电压可能偏了大约9mV——对12位ADC来说,这个偏量接近11个LSB,足够让你的采集结果出现可观察的偏移。

MCU内部参考通常存在同样问题,只是表现更隐蔽。我踩过的坑是:某芯片数据手册上写着内部基准精度2%,其实常温下问题不大,但板子放在室外,早晚温差十几度时,采集值就像“呼吸”一样缓慢漂移。后来换成外部参考IC后,漂移曲线立刻平了。

2.2 电源与布局带来的耦合噪声

第二个常见噪声源来自供电。ADC的模拟电源引脚(AVDD、AVCC等)和数字电源引脚如果共用同一路电源,数字电路翻转时产生的电流尖峰会在电源走线的寄生电感上产生压降,进而污染模拟电源。这个问题在ADC采样率较高、数字总线繁忙时尤其明显。

处理方式有几个层次,按性价比从高到低:

  • 模拟电源与数字电源之间串磁珠,磁珠在高频时呈高阻,能阻断数字噪声向模拟域传播;
  • 模拟电源引脚就近放0.1uF + 10uF并联退耦电容,电容要尽可能靠近引脚放置,走线先到电容再到引脚效果比较好;
  • 条件允许时,PCB上把模拟地和数字地分区铺铜,在一点处汇合,避免数字电流的返回路径穿过模拟采样区域。

再一个容易忽视的噪声源,就是快速翻转的数字信号线(比如I2C时钟线、PWM输出线)与ADC模拟走线平行敷设。高频信号通过寄生电容耦合到模拟走线上,直接污染采样结果。解决办法就是拉开距离、垂直走线、用地线隔离,这些都属于布局基本功,但很多人都不爱注意,直到读数飘了才回头查布线。

2.3 信号源阻抗:别把ADC输入端当成理想电压表

有人用万用表测量习惯套ADC:以为ADC输入引脚是高阻,随便接什么源都行。实际上,大多数MCU内置ADC的输入引脚并非理想高阻,它有一个采样电容,每次采样都相当于把一个电容接入被测电路充电,充电需要从信号源吸取电流。

重要概念是信号源阻抗。以一个输出阻抗10kΩ的温度传感器分压网络为例,内部采样电容假设为14pF(常见MCU参数),取样时间极短时,RC = 10kΩ * 14pF = 0.14us,这个时间常数本身很小。但如果源阻抗为100kΩ,RC就变成1.4us。设计上要求采样时间内电容电压应稳定到0.5 LSB以内,经验法则是采样时间至少要达到几个RC时间常数。

如果源阻抗较大而采样时间不足时,会出现一个非常典型的症状:ADC读数“系统性偏低”,而且这个偏低量随着前一通道电压的大小变化而变化——因为电容上的残留电荷会影响下一次采样。解决思路有三类:

  • 增大采样时间(软件可配);
  • 在ADC输入引脚对地并联一个电容(无源RC滤波,也能压低噪声,但注意会与源阻抗形成低通,可能导致动态信号变慢);
  • 加入运算放大器做缓冲,电压跟随器提供极低输出阻抗,这是最彻底的方案。

我的经验是,先用上面的“并联电容看变化”法快速判断源阻抗问题:在输入脚并联一个0.1uF电容,如果读数明显变高趋向真实值,或者波动显著变小,那就说明源阻抗偏高了。

2.4 运放与缓冲:低阻抗驱动的必要性

既然源阻抗问题这么普遍,实际项目中直接用运放做缓冲就是常规操作。电压跟随器接成单位增益,输入阻抗可以做到几百兆欧,输出阻抗只有几欧姆到几十欧姆,几乎可以和任何ADC直接相连。

不过运放不是随便接上就完事。要注意运放是否轨到轨输出,如果输入电压接近电源轨,普通运放输出会削顶;还要注意运放的带宽和压摆率,对于变化很慢的直流信号基本无所谓,但如果信号有高频成分,带宽不足会导致信号失真。

此外,运放自身也有失调电压(Vos),高精度场景要选低失调、低温漂的型号。很多精密运放Vos能做到几十微伏级别,比12位ADC的一个LSB还小,基本不会成为误差瓶颈。

给ADC做缓冲还有个防呆技巧:给运放输出到ADC输入之间串一个小电阻(比如100Ω),可以抑制运放输出与采样电容之间的振铃,代价是引入极小的时间延迟和电阻热噪声,对于大多数场景可以忽略。

3. 取平均的正确姿势:从简单算术到滑动滤波

3.1 算术平均:最简单但容易被忽视的前提

ADC读数乱跳时,很多人的第一反应就是“多采几次取平均”。这个思路没错,但必须明白算术平均到底解决了什么问题。它主要抑制的是随机白噪声——也就是那种围绕真实值上下对称抖动的噪声。对确定性干扰(比如50Hz工频干扰的固定偏置、方波毛刺、脉冲尖峰),单纯求平均效果有限。

这里有个“收益递减”规律:对高斯白噪声,M次采样的平均值,噪声标准差降为单次采样的1/√M。也就是说,4次平均噪声降一半,16次平均降到四分之一,100次平均才降到十分之一。想靠无限增加采样次数来压噪,投入产出比很低。

我做过一组实测对比:某个12位ADC,单次采样噪声峰峰值约±8 LSB;4次平均后降到约±4 LSB;16次平均后降到约±2 LSB;64次平均后约±1 LSB,基本接近12位ADC的物理极限。再往上增加次数,改善幅度几乎不可感知,还白白占用CPU时间。

所以使用算术平均时,先要判断噪声类型。如果读数在真实值上下对称抖动,抖动幅值随机,那么算术平均是有效的;如果噪声表现为偶发的尖峰,那算术平均会把这个尖峰也平均进去,导致偶尔出现一次离谱的值——这种情况中值滤波反而更合适。

另一个容易忽略的前提:被测信号本身必须是稳定的。如果信号本身就在缓慢变化,你对64次采样取平均,得到的是这段时间内的“时间平均”,可能抹平了真实的信号波动。取舍原则是:信号的截止频率越低,滤波窗口可以越大;信号变化越快,窗口必须越短。

3.2 滑动平均:实时系统的实用选择

算术平均有个使用限制:要么定期采集固定次数,要么就必须等凑齐N个数据才能算一次。实时系统里,我们希望每个控制周期都能拿到一个刷新过的平滑值,而不是隔一段时间才跳出一个新数。滑动平均就是为此设计的。

实现上就是固定一个长度为N的环形缓冲区,每次采到新值,把最老的值丢出去,用剩余N-1个值和最新值重新求平均。这样每个采样周期都能输出一个新的滤波值,数据流动性好。

选择窗口长度N要权衡两点:窗口越长,平滑效果越好、滞后越大;窗口越短,响应越快、但残余噪声更多。我的经验参考如下:

  • 电源电压监测:窗口8-16,信号变化本身很慢,有效值刷新足够频繁;
  • 温度NTC采集:窗口4-8,温度变化蒸馏一般,可以稍微激进一点;
  • 电机电流采样:窗口4-8,需要一定的响应速度,窗口太大会掩盖真实电流突变;
  • 音频/话音信号:不建议用简单滑动平均,相位失真和频率响应问题会让信号明显“发闷”。

滑动平均还有一个工程便利:如果窗口长度N取2的整数次幂(8、16、32),除法可以直接用移位实现,在无FPU的低端单片机上节省不少CPU开销。

3.3 中值滤波:对付尖峰干扰更稳

ADC采集中最令人头疼的噪声,往往不是随机白噪声,而是偶发的脉冲干扰——可能是电机换向火花、继电器吸合、电磁阀动作瞬间产生的尖峰。这类干扰的特点是:时间很短、幅度很大、偶尔出现。用算术平均和滑动平均处理,尖峰会被部分“吸收”进结果里,表现为偶尔一次的突跳;但如果用中值滤波,只要尖峰不占多数,它就会被直接丢弃。

中值滤波的原理很简单:连续采N个值(通常N取奇数,如3、5、7),排序后取中间那个作为输出。如果N=5,连续采到的值是[100, 98, 102, 350, 101],排序后是[98, 100, 101, 102, 350],取中间值101,尖峰350被完全排除。

中值滤波的代价是排序耗时。N=3时交换排序非常快;N=5、7时,适当选择插入排序或选择排序,在几十MHz的单片机上也就是几十个周期的事。如果采样率要求不高,这个开销可以忽略。

把中值滤波和滑动平均组合使用,效果往往好于任何一个单独使用:先做一次窗口大小为3或5的中值滤波剔除尖峰,再对剔除尖峰后的数据做滑动平均压低白噪声。这个组合在电机控制场景里非常常见,既能防脉冲,又不至于让平滑滞后太大。

3.4 一次性跳变检测:游戏摇杆式的数据平滑思路

还有一种场景,既不希望随机抖动暴露出来,又不希望过滤掉真实的大幅变化。典型比如摇杆电位器、油门踏板位置传感器——用户拨动时,数据应该平滑跟进;用户不操作时,输出应该稳定如钉。

这类场景可以采用“死区+步进跟随”的思路:维护一个上次输出值base,每次读取新采样值cur,如果 |cur - base| 小于阈值,认为这是噪声,保持base不变;如果差值大于阈值,则让base向cur方向移动一个固定步长step。这样小抖动被完全抑制,大变化则以固定速率跟进,手感上类似模拟摇杆的阻尼。

实际参数设定上,阈值要大于系统正常噪声的峰峰值,步长决定响应的快慢。一次项目中调速旋钮的读数一直抖动导致电机转速抖,参考这个思路只加了十几行代码,问题就解决了。这个方式完全不需要排序和缓冲,内存占用小,是资源受限场景下的好方案。

4. 精度的尽头是校准:增益误差与偏移误差的处理

4.1 偏移误差:让曲线平移的元凶

只要输入端接地,理论上ADC应该输出0。但实际芯片总有偏移误差,表现为“输入为0时输出不为0”或“输入为某个电压时输出整体平移了若干个LSB”。偏移误差意味着整个转换曲线在横轴方向上平移了一段距离。

偏移误差的来源主要是内部比较器的失调电压、电荷注入效应、以及参考电路的不对称。对大多数MCU内置ADC来说,出厂时并没有做精密校准,偏移误差可以达到几个到十几个LSB。

处理偏移误差的方法叫零点校准:把输入端接到已知电压(最方便的就是接地),采集足够多次取平均,把平均值记作offset。以后每次转换结果都减去这个offset。

注意一点:零点校准只是在“0点附近”修正平移,它不能同时修正放大倍数的偏差。所以做完偏移校准后,还要做增益校准。

4.2 增益误差:斜率不对是什么感觉

增益误差表现为转换曲线斜率偏离理想斜率。假设理想情况下输入Vref时输出4095,实际可能只有4080;输入Vref/2时输出2047,实际可能只有2035。这种误差在高量程端表现得尤为明显。

增益误差的来源包括内部DAC电容阵列的失配、参考电压采样网络阻抗等。和偏移误差一样,MCU内置ADC的增益误差也不做出厂标定,不同芯片之间的离散性还比较大。

这里可以算一笔账:一个12位ADC,增益误差假设为-5 LSB@满幅,如果直接测量3.0V(接近满幅),误差就是接近5个LSB;测量0.5V时,由于信号只占量程的15%,贡献误差大约只有0.8个LSB左右——所以增益误差在低量程端影响小,高量程端影响大。这也是为什么校准增益误差要尽可能在接近满量程的电压下进行。

4.3 两点校准法的完整流程

把偏移误差和增益误差合在一起校准,就是经典的两点校准法。核心假设是:ADC的实际输入-输出曲线是一条直线,与理想直线之间存在偏移和斜率两个偏差,只要测两个已知点,就能唯一确定这条实际直线,然后建立从ADC读数到真实电压的线性映射关系。

实操步骤:

  1. 选两个校准点:一个尽量接近0V(比如Vref引脚接地),一个尽量接近满量程(比如用精密基准源给Vref电压或者一个已知高精度电压)。
  2. 每个校准点连续采集N次(N建议64或128),取平均,得到raw_low和raw_high,对应的真实电压为real_low和real_high(已知值)。
  3. 计算增益系数k = (real_high - real_low) / (raw_high - raw_low),以及偏移量b = real_low - k * raw_low。
  4. 实际测量时,真实电压 = k * 原始读数 + b。

需要注意两个细节:校准点之间跨度越大,拟合出的直线越能代表整个量程的响应;校准点的真实电压必须比你的测量设备还准,否则校准反而引入了新误差。批量产品想要一致性更好,可以每个模块单独校准,把k和b写入EEPROM/Flash里,上电时加载。

4.4 温度漂移:校完了还会变

两点校准能解决芯片固有偏差,但校准结果并非永久有效。ADC的偏移误差和增益误差都会随温度变化,尤其是MCU内置ADC,内部某些电路的温度系数并不算小。你25°C室温下校准好的k和b,板子放到60°C环境里,可能又偏回去了。

应对措施分几个层次:

  • 不追求极端精度时,做常温两点校准即可,在整机工作温度范围内精度仍然可以接受;
  • 如果温度范围大、精度要求高,可以在多个温度点做分段校准,在运行中根据当前温度插值选取k和b;
  • 还有一种不算常见的做法:利用ADC内部温度传感器,实时估计芯片温度,然后对校准参数做温度补偿。这个精度取决于内部传感器的准确度,不算特别好但聊胜于无。

我的看法是:不要一开始就想着搞复杂温度补偿。先在常温下校准,测试整机全温度范围的误差到底有多少。如果校后误差在可接受范围内,就不用画蛇添足;如果超差,再看误差是否呈线性规律,再决定是否做多温度点标定。

5. 工程上的几个实用经验

5.1 关键参数速查表

把前面涉及的核心参数整理成一个表,方便设计时快速对照:

参数典型值/建议说明
1 LSB(12位,3.3V)≈0.806mV分辨率物理极限
采样时间按需拉长源阻抗高时尤其重要
信号源阻抗建议低于10kΩ过高需加运放缓冲
平均次数16~64对白噪声有效
窗口长度(滑动平均)4~16滞后与平滑的折中
中值窗口3或5抗脉冲尖峰
校准点数2点0点附近+满量程附近

表里每一项背后都能串联起一串排查步骤。你调ADC时如果感觉无从下手,照着表逐项核对就是一个很好的排查路径。

5.2 过采样:用速度换精度的技巧

有些场景下ADC的分辨率不够用,想测量一个比1 LSB还小的电压细微变化,又不想换更高位数的外部ADC,可以尝试过采样(Oversampling)技巧。原理不复杂:如果噪声是白噪声且幅度足够覆盖至少1 LSB,对2^m次采样取平均,等效分辨率大约可以增加m/2位。也就是说,要增加1位有效分辨率,需要4倍过采样;增加2位,需要16倍。

注意这个技术有两个先决条件:噪声必须是随机白噪声,且噪声幅度不能太小。如果信号本身极其稳定、噪声极小,那么每次采样得到的都是同一个值,取平均自然什么都提升不了。这种情况下反而可以把参考电压调低以提高相对分辨率,或者改用更高位数的ADC。

过采样的另一个作用是“白赚分辨率”的同时还平滑了数据。常见实现是:以4倍或16倍于所需采样率的频率连续采样,累加后右移相应位数输出。代码实现相当简单,很多低端单片机也能跑得动。

5.3 不同场景下的推荐配置

最终给几个场景的推荐组合,属于可以直接套用的起点配置:

  • 电池电压检测:采样率1kHz以下,采样时间拉长,滑动平均窗口8,不需要运放缓冲(分压电阻注意阻值,典型100k/20k这种组合最好加运放)。
  • NTC温度采集:采样率几百Hz,中值滤波3 + 滑动平均4,NTC分压网络中上拉电阻建议不超过10k,否则直接换用低阻输入电路。
  • 电机电流采样:采样率尽量高(几十kHz),先做3值中值剔除尖峰,再做4~8点滑动平均,布局上采样电阻与ADC距离尽量短。
  • 多通道轮询采集:每个通道切换后延时几个微秒再启动采样,给内部电容充分时间建立到新通道的电压水平。

这几组配置都不是什么严谨推论,而是多种场景实测后觉得比较“省心”的起点。带自己项目时,从这些参数出发,再根据实际噪声情况微调,通常能少走很多弯路。如果调参过程中发现再怎么调都压不下来的噪声,回到上面2和4两节,检查参考电压、电源、接地和信号源阻抗——八成问题不在算法上。

文章来自:“ADC转换汇总(采样原理、取平均、精度等)”

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询