ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ADC分辨率、LSB与精度:三者的区别及实际测量中的关键避坑指南

ADC分辨率、LSB与精度:三者的区别及实际测量中的关键避坑指南 做嵌入式这些年面试过不少人也逛过不少技术帖子发现一个特别普遍的现象聊到ADC十个里有七个分不清LSB、分辨率和精度。有人拿12位ADC就拍胸脯说“这精度能到1mV以内”有人把LSB算出来的电压直接当成了误差值还有人觉得采集卡标了24位就是24位精度。这些问题不搞清楚做传感器采集、电源检测、仪器仪表这类项目时一定会栽跟头。这篇不扯教科书的定义我就用大白话加上实际项目里遇到的案例把ADC的LSB、分辨率和精度这三兄弟掰开揉碎讲清楚。看完你至少能明白这三个概念说的完全是不同的维度为什么高分辨率不代表高精度以及自己在做板子、选芯片、调采集电路时到底该信哪个、该测哪个、该怎么避坑。不管是玩STM32、ESP32这种内置ADC还是外挂ADS1115、ADS1256这类独立采集芯片这套思路都通用。1. 先把三兄弟认全分辨率、LSB、精度到底在说什么1.1 用一把刻度尺讲清楚三者的关系想象你手头有一把普通的塑料尺子量程是30厘米。尺子上有30个大格每个大格里又分了10个小格所以一共有300个小格。这时候分辨率就是这个尺子上刻了多少条线你能读出多少种不同的长度值LSBLeast Significant Bit最小有效位就是最小那一格实际代表的长度在这里是1毫米精度是你量出来的数值和真实长度之间的偏差——你可以读出来1毫米的变化但尺子本身是塑料的热胀冷缩或者印刷歪了量10厘米的东西读出来是9.8厘米那这个尺子的精度就不行。对于ADC来说道理一模一样。ADC的输入通常是一个电压范围比如0到3.3V。如果这颗ADC是12位的意味着它能把0到3.3V这个区间切成2的12次方份也就是4096份。每一份的电压就是LSB算一算就是3.3V除以4096约等于0.806mV。分辨率就是这个“能切成4096份”的能力也就是位数。而精度呢是你实际输入一个1V的电压ADC读回来的码值换算成电压是1.000V还是0.985V还是1.032V。读出来和真实值差多少这就是精度问题。很多人一开始最大的误区就是觉得分辨率越高测得就越准。其实分辨率只决定了ADC能“分辨”多小的变化但分辨得出来不代表就量得准。你拿一个能读出0.1微米的激光测距仪去量一张桌子如果仪器内部的基准波长偏了量出来照样不准。这就是尺子本身刻歪了的问题跟刻多少条线没有关系。1.2 LSB到底是什么怎么算LSB的全称是Least Significant Bit翻译过来是“最小有效位”。在ADC语境下它通常被理解为“一个离散码字对应的理想电压间隔”也就是量化步长。公式很简单LSB Vref / 2^N其中Vref是参考电压N是ADC的分辨率位数。举个例子一颗12位ADC参考电压Vref3.3V那么LSB3.3/4096≈0.8057mV。一颗16位ADC参考电压Vref5V那么LSB5/65536≈76.29µV。位数越高LSB越小理论上能分辨的电压变化就越细微。这里有个容易让人犯迷糊的坑。我们算2^N但实际ADC输出的最大码值其实是2^N减1。比如12位ADC输出码值范围是0到4095并没有4096这个码。那为什么LSB还是按除以4096算这是因为ADC的传输特性默认是最低码000h对应0V最高码FFFh对应的是Vref乘以(4095/4096)而不是刚好等于Vref。换句话说满量程电压Vref对应的码值是4095而4095这个码代表的实际电压是Vref×(4095/4096)。理想情况下LSB依然是Vref/4096最后一个码对应的电压比Vref稍微低了那么一丁点。这个问题在精密测量时才会体现日常估算不用太纠结但你要知道有这个差别免得后面调试时发现满量程读数总是差半个LSB左右。再补一个容易混淆的点LSB本身是个电压单位不是误差单位。它说的是“一格多大”。但是芯片数据手册里经常写“Offset Error: ±2 LSB”意思是偏移误差是“两个格子”那么多换算成电压就是±2×LSB。所以LSB经常会当作误差的度量单位出现。你就把它理解为“以最小格子为单位来表示偏差大小”就像我们说某人身高误差“半格”。1.3 分辨率ADC的“视力”分辨率英文Resolution描述的是ADC能区分的最小模拟输入变化。它主要由位数决定。8位ADC能把量程切成256份10位切1024份12位切4096份16位切65536份24位切16777216份。分辨率决定了ADC的量化噪声上限。一个理想ADC输入一个稳如老狗的直流电压输出码值也不是永远不变的因为模拟电压总会被量化到最近的离散电平量化过程中产生的误差叫量化误差最多不超过±0.5LSB。这个误差是原理性的任何ADC都有位数越高LSB越小量化误差的影响就越小。所以分辨率的核心意义在于“看得细不细”。做电池电压监测1mV的变化都要抓出来12位ADC在3.3V参考下LSB约0.8mV理论上是够用的。如果只是监测一个220V电源是否存在用8位甚至更低的都行。选分辨率之前先问自己我最关心的最小电压变化是多少留出余量因为真实环境下还有噪声不是说看到一个LSB就等于能看到那么小的稳定信号。1.4 精度ADC的“手感”精度英文Accuracy描述的是ADC的实际转换结果与真实输入值之间的接近程度。精度受很多因素影响偏移误差、增益误差、积分非线性INL、微分非线性DNL、参考电压的准确度和温漂、温度漂移、输入前端电阻分压的误差、PCB漏电、电源纹波、甚至采样保持电容的电荷注入。用一个更贴近生活的例子。你去买电子秤分辨率是1g这是它能显示的最小变化但你把一个标准100g的砝码放上去显示102g那精度就是2g的偏差。哪怕它显示到小数点后三位分辨率0.1g如果测100g砝码出来105.2g你也不能说它精度高。ADC也一样。分辨率是写在位数里的天赋上限精度是电路工程要费心去保证的结果。一个12位ADC理论分辨率可能是0.8mV但如果你给它供参考电压的LDO有±10mV的纹波前级运放偏置又有±5mV的误差那整体精度可能只有±15mV12位的分辨率在这种情况下只能保证你能看到跳动的码但码对应的电压值并不“准”。2. 数学账LSB、分辨率与精度的换算和边界2.1 常用公式与真实计算示例先列几个工程里天天用的公式。已知参考电压Vref和位数N求LSBLSB Vref / 2^N已知采样码值Code无符号单端求对应理想电压VinVin Code × LSB已知目标电压Vin求理论码值Code Vin / LSB取整到最近的整数。举个例子。某传感器输出0到3.3V用STM32内部12位ADC采集Vref接3.3V。传感器输出1.25V时理想码值是Code 1.25V / (3.3V / 4096) 1.25 × 4096 / 3.3 ≈ 1551.5所以理论上你会读到1551或1552这个码值附近。如果把参考电压换成2.5V的基准源LSB变成2.5/4096≈0.610mV同样1.25V输入码值变成1.25×4096/2.52048。这从侧面说明参考电压的选取直接影响LSB也直接影响码值分布。我们再看一位常见的12位和16位对比表位数2^N参考3.3V时的LSB参考5V时的LSB825612.9mV19.5mV1010243.22mV4.88mV1240960.806mV1.22mV166553650.35µV76.29µV24167772160.196µV0.298µV看到24位的LSB只有零点几微伏但是注意这只是理想量化步长真实系统中PCB上两个焊盘之间的热噪声、参考源噪声、运放噪声随便都是微伏甚至毫伏级别。所以位数只是天花板实际精度是由系统噪声地板决定的。2.2 有效位数ENOB别被纸面位数骗了实际ADC有一个指标叫ENOBEffective Number of Bits有效位数。这个指标是拿实际测到的信纳比SINAD反推出来的公式是ENOB (SINAD - 1.76) / 6.02SINAD单位是dB表示信号与噪声加失真的比值。一个12位ADC理论上如果没有任何噪声和失真它的SINAD上限大约是12×6.021.76≈74dB。但现实中电源噪声、时钟抖动、芯片内部热噪声、输入前端噪声都会让SINAD下降。如果实测SINAD是65dB那ENOB就是(65-1.76)/6.02≈10.5位。也就是说这颗12位ADC实际能用到的“干净位数”其实只有10.5位。很多数据手册会直接给出ENOB。比如说某16位ADC在100kSPS采样率下ENOB是13.2位这就意味着虽然它输出16位码值但最低的两三位基本是噪声在翻动。你去做高精度测量不能指望那几位是稳定的信息。怎么理解这个你可以把ADC输出的最低几bit当成“抖动位”——它们不是信号的真实信息更像是噪声洒在低位上的随机雨点。真正值得你信赖的是ENOB对应的那几位。这也是为什么经常有人说“ESP32的ADC没眼看”——并不是说ESP32的ADC芯片绝对值很烂而是它的实际有效位数在常规配置下偏低加上线性度和温漂不好会让人大失所望。2.3 精度怎么量化偏移误差、增益误差、INL和DNL精度不是一个单一数字它是一堆误差的合集。芯片数据手册里通常会给出几个关键参数我在选型时一定会看这几个。偏移误差Offset Error又叫零点误差。输入0V时ADC输出码值不为0而是偏离了一个固定值。比如某12位ADC的偏移误差是±3LSB意味着你输入0V读到的码值可能在0±3之间浮动换算成电压就是大约±2.4mV参考3.3V时。增益误差Gain Error。输入满量程附近电压时ADC输出码值和理想值有偏差。通常表现为斜率偏移。比如理想斜率是1码/LSB实际可能是0.998码/LSB。低端表现为偏移高端被放大。有的手册会用“Gain Error: ±6 LSB”这种写法表示在满量程处偏差约6个LSB。积分非线性INL, Integral Non-Linearity。它描述ADC的实际传输曲线和理想直线之间的最大偏离。INL大的ADC即使做了零点和满量程校准中间电压点依然可能偏差。做精密采集如果只校准两点INL就会成为残余误差的主要来源。一般来说高精度SAR ADC的INL可以做到±1.5LSB甚至更好。微分非线性DNL, Differential Non-Linearity。描述实际相邻码间隔和理想LSB之间的偏差。DNL不好表现为某些码被压缩、某些码被拉伸甚至出现失码Missing Code即某个码值永远跳不过去。对图像采集、控制环路这类应用DNL不好会导致输出“台阶”不均匀。工程上有时会参考Total Unadjusted ErrorTUE总不可调误差。TUE是偏移、增益、INL等误差的综合估算值。数据手册如果给了TUE可以直接用来估算最坏情况误差。举个例子某ADC手册写TUE ±4.5 LSB 5V参考5V那么它的总不可调误差就是±4.5×5/65536≈±343µV。这个数字天然就比只有分辨率数字要诚实得多。最后再强调一句精度计算不是简单把几个误差做个加法那么严谨因为误差有正有负不一定同向叠加。工程上为了留余量常常按最坏情况简单相加或者按平方和开方RSS估算。最靠谱的还是直接看手册的TUE以及实测数据。3. 实操避坑分辨率不是精度选型和使用常见的坑3.1 选型时别只看ADC位数我见过一个真实案例。有人设计一个电压采集模块起初用了一颗内置12位ADC的单片机加上外部2.5V精密基准把采样结果滤波之后分辨率做到了接近0.1mV的跳字。后来项目要求“提高精度”甲方一拍脑袋说要16位他也不去分析误差构成直接换了一颗16位的逐次逼近型ADC结果呢因为没有重视参考源和前级噪声16位ADC的低几位全是乱跳实际能用位数还不如之前12位做得精细。选型很容易犯这个错误因为位数是最好看的宣传点。现在市面上甚至有几块钱的24位ADC芯片看起来参数吓人但如果整个信号链路的噪声在毫伏级别24位位数就是摆设。正确的选型流程应该是先算信号链路的总噪声预算包括传感器输出阻抗产生的热噪声、运放电压噪声、参考源噪声、PCB耦合噪声然后根据“信号最小分辨率”确定系统需要多大ENOB再倒推ADC位数。工程上有一个粗算经验需要的有效位数比你要达到的精度对应位数多一到两位作为余量。也就是说你系统目标精度是1mV量程3.3V那么需要约12位有效分辨率3.3/2^N 0.5mVN≥12.7再留余量选16位或14位同时想办法把前端噪声压下来。3.2 参考电压最容易忽视的隐藏精度来源参考电压决定了ADC的“尺子长度”。尺子本身不准读出来的数怎么可能准我遇到过很多调理不理想的板子。有人直接把3.3V的LDO输出既给MCU供电又给ADC的Vref引脚。LDO输出精度通常也就±2%动态负载下纹波可能有几十毫伏。对一颗12位ADC来说参考3.3V时LSB只有0.8mVVref一旦波动20mV相当于整个量程被拉伸或压缩了20mV对应20多个LSB的跳变。你采样出来的数据当然是跳的。解决办法无非三种。第一种用独立的精密基准源。常见的如REF50252.5V温漂低、ADR4525、ADR4550等。这种专门的基准源精度高、温漂小、噪声低适合做精密采集。第二种采用比率式测量ratiometric。如果你的传感器输出和ADC参考电压来自同一个激励电源比如电桥传感器激励电源Vex同时接ADC的Vref那Vex漂多少信号和参考电压同比例漂多少最终码值不受Vex漂移影响。这种方法在很多称重、压力检测方案里非常常用成本低且效果好。第三种对普通的低压差LDO做后级滤波比如加Π型滤波再加去耦电容尽量降低高频噪声。这适合中等精度场景但LDO本身的温度系数和负载调整率还是会带来误差高精度场景下不够用。另外一个容易忽略的是Vref去耦电容的摆放。Vref引脚一定要就近放高质量电容比如1µF X7RNPO并联而且不要走长线到数字区域否则数字开关噪声会耦合进基准。有条件的芯片还建议在Vref引脚串一个小磁珠隔离来自电源面的高频噪声。3.3 内置ADC的坑STM32和ESP32的真实体验STM32的ADC算是比较好用的12位分辨率速度也不低。但有几个注意点。参考电压STM32F1系列很多型号Vref直接和VDDA绑定如果VDDA没有处理干净ADC精度就会下降。F3、F4、H7等部分型号支持独立的VREF引脚可以外接精密基准。采样时间ADC内部采样电容需要时间充电如果信号源阻抗高得把采样周期调大否则充电不充分读数偏低或抖动。官方建议源阻抗上限通常在10kΩ以内超过就要加跟随器。校准STM32硬件ADC提供校准功能上电时做一次可以消除部分偏移误差。很多人不做白白损失了精度。ESP32的ADC则是另一类问题。它的12位ADC主要缺点是输入电压范围比较特殊部分型号量程到2.5V左右非线性不太好而且温度变化后读数会漂。网上不少人都发现同一颗ESP32在不同温度下同一电压的采样值能差出不少。所以用它做高精度采集要两头下功夫一是做多点校准而非两点校准尽量把非线性拉回来二是保证工作环境温度恒定或者在系统里加温度传感器做补偿。我用过很多ESP32做环境监测产品说实话作为“有没有超过阈值”这种定性检测完全够用但你要它做到0.1%精度那就别指望了。真要做精密电池电压监测宁可在ESP32外面挂一颗16位外置ADC比如ADS1115走I2C方便可靠精度也高得多。3.4 采集卡、仪器仪表的位数不是系统精度热词里有一条“采集卡的位数是精度吗”正好拿来说说。你买一块USB采集卡商家标“16位分辨率”这通常只说明它的ADC是16位的输出码值最多16bit。这不代表你采到的数据就有16位精度。采集卡的整体精度还取决于模拟前端放大器的噪声和漂移、输入阻抗匹配、通道串扰、参考源的稳定性、出厂校准文件、采样时钟的抖动。举一个实际场景工业数据采集卡标16位量程±10V那么一个LSB对应约0.3mV。如果实测系统噪声是±3mV那你实际的可靠分辨率只有约14位。更别提很多采集卡在两三年后因为元器件老化精度会下降所以工业采集仪器都有定期校准的要求出厂标称精度不是永久有效的。你去看数据采集卡的规格书真正要关注的是“Accuracy”那一栏比如“±0.01% of reading ±0.005% of range”这是综合精度。换算到整个量程它已经包含了增益误差、偏移误差、非线性等一大堆东西比“位数”这个数字实在得多。买仪器也一样台式万用表标6位半不等于6位都准真正准的是它的“基本精度”指标。4. 把理论落地一块ADC采集板的调试验证流程4.1 规规矩矩的设计从源头上减少误差ADC采集出问题很多不是ADC芯片的锅而是外围电路没伺候好。分享几个我画板时一定注意的地方。参考电压去耦Vref引脚附近放1µF0.1µF陶瓷电容尽量贴近引脚走线要短粗。分压给Vref的电路分压电阻用低温漂的精密电阻比如0.1%、25ppm/℃。模拟地和数字地ADC的AGND和DGND处理遵循芯片手册建议一般建议单点连接不要在ADC下方直接大面积铺铜连死。电源和地平面保持完整别让数字走线横穿模拟区域。输入端滤波在ADC输入端加RC低通滤波器截止频率比信号带宽高一点又要把开关电容采样带来的电荷注入毛刺滤掉。典型值比如R100Ω~1kΩC1nF~10nF具体根据采样率和源阻抗调整。前级驱动SAR ADC的采样电容在采样瞬间会抽取电流脉冲如果源阻抗太高电压会掉。一般建议加一个低噪声运放做跟随器或同相放大让ADC看到的是一个低压阻抗源。4.2 零点校准与增益校准简单两步把误差拉回来不管外围做得多好系统里总有偏移误差和增益误差。最实用的方法就是校准。校准要在产品组装完成后进行因为PCB漏电、焊接应力都会影响最终精度。第一步零点校准。ADC输入端接地或者接信号地采集N个样本取平均记为code_zero。如果输入接地后ADC输出的码值不是0这个偏差就是零点偏移。第二步增益校准。接一个高精度电压源比如用精密基准如AD584这类或用高精度万用表实测的稳定电压记为V_ref_cal。采集M个样本取平均记为code_cal。注意校准电压最好选在量程的75%到95%之间太接近满量程容易非线性偏大太低则增益校准灵敏度不足。然后未来任意时刻采集到的码值code_raw就可以用校准参数换算成实际电压V_actual (code_raw - code_zero) × (V_ref_cal - V_zero) / (code_cal - code_zero) V_zero这里的V_zero是零点校准时的实际输入电压接地就是0V。用这个线性公式可以把偏移误差和增益误差同时拉回来。我实测过一个案例STM32F407内部ADC参考3.3V内部校准也做了但零点能偏差约2LSB满量程偏差约5LSB。做了零点加增益校准后在0.5V到3.0V区间误差从±6LSB降到了±1.5LSB以内。这个提升对很多应用已经质变了。如果你追求更高的线性度可以做多点校准。用高精度源输出5个、10个电压点用最小二乘法拟合一条直线把INL导致的残余误差也摊平。这个方法在ESP32这颗非线性比较明显的芯片上特别值得做。4.3 用实测数据反推有效位数的小方法很多人拿到一块ADC板子不知道到底实际能用多少位。这里说一个快速粗估的办法。把ADC输入端直接短路接地用正常的采样率采集1000到5000个样本记录码值。如果ADC内部有噪声你看到的码值会在0附近波动无失码情况下。计算这些码值的标准差σ以LSB为单位。理想情况下如果噪声主要来自量化噪声σ大约在0.29LSB左右。如果σ明显大于这个值说明系统里有多余噪声或干扰。根据σ可以粗估有效位数ENOB_noise ≈ N - log2(σ / 0.29)其中N是ADC标称位数。这个公式的直觉是如果噪声标准差是理想量化的3倍相当于低位多丢了约1.58bit。举个例子12位ADC接地采集算出标准差σ1.2LSB那么ENOB_noise≈12-log2(1.2/0.29)≈12-2.05≈9.95位。这说明系统里真实可用的信息大约只有10位左右最低的两位都在被噪声搅动。严格来说工程上评估ENOB更标准的方法是输入满量程正弦波采样做FFT看SINAD再换算。但那个对环境要求高对单片机开发来说接地抖动估算法简单直观很适合作为一个快速筛选方案的方法。5. 常见问题速查与排障实录5.1 常见疑问速查表下面这些是我在技术交流群里经常看到的提问整理成一个速查表方便你遇到问题直接对号入座。问题背后原因处理建议分辨率越高越准吗分辨率只决定量化细度不代表整体精度优先检查参考源、前端噪声、INL、TUE等指标LSB算出来的电压是误差吗LSB是理想码步长不是误差值误差要查偏移误差、增益误差、INL、DNL12位ADC读值总跳是什么原因多数是电源噪声、参考源不稳、采样时间不足加滤波、调采样时间、独立基准、重复采样平均校准过零点后读数还是偏可能有增益误差没校或INL大做增益校准必要时多点拟合输入端空接读数乱跳正常吗悬空输入是无定态ADC会采到周围噪声正常现象输入端必须接确定电平或信号源采集卡标24位为何测不准24位是ADC位数不是系统精度看系统精度指标注意校准有效期和噪声差分输入比单端更准吗差分抗共模干扰能力强适合长线、低幅信号信号源是差分形式才用差分输入别乱接5.2 几个实战排障场景照着排查场景一ADC读数跳动幅度大。先查电源。用示波器看Vref和VDDA的纹波如果没有示波器就用另一块高精度表测一下。然后把采样速率降下来加软件均值滤波看是否明显改善。如果纹波不大检查信号源阻抗是否太高导致采样充电不完全并尝试加大采样周期。最后检查PCB布局比如ADC输入走线是否跨过了电源或数字信号线。场景二ADC读数整体偏大或偏小但很稳定。这是典型偏移误差或增益误差。先做零点校准把输入接地看码值再做增益校准输入一个已知电压看码值然后用4.2节的线性公式修正。如果校准后中间点还歪基本可以断定INL偏大这时要考虑换更高线性度的ADC或做多点拟合。场景三读数和万用表对不上但数值关系是固定比例。比如你测2.000VADC读出来1.930V。这个典型就是参考电压不对。用万用表实测Vref引脚的实际电压再和理论值对比。比如你以为是3.3V实际只有3.18V那读数整体就缩水了4%左右。换成精密基准源就好。场景四低电压端读数正常高电压端开始偏差变大。有可能是前端分压电阻精度不够或者是ADC在高段的DNL不良。先确认分压电阻是否用的是精密电阻然后用两个不同电压点校准观察偏差走向。5.3 几个能救命的小习惯都是“学费”换来的第一个习惯每块新板子回来先别急着跑业务代码花十分钟做底噪测试。输入端接地采集一组数据看码值分布。如果你连这块板子的底噪都不知道后面出了问题就很难分清是软件问题还是硬件问题。第二个习惯采样均值滤波不是万能的它能压白噪声但压不了基准漂移和工频干扰。50Hz工频干扰要用64点或128点的整周期滑动平均才能有效抑制或者用硬件低通。盲目的“一顿平均猛如虎”有时候只是把噪声掩盖了没有解决根本。第三个习惯软件里保留原始码值和校准参数不要直接丢掉。产品上线后如果发现数据漂移你可以通过对比校准前后的原始码值判断是传感器的问题还是ADC通道的问题还是校准参数失效。我曾经就靠这个习惯在生产一批产品后快速定位到某个批次焊锡不良导致漏电增大问题码值分布和正常批次完全不一样。第四个习惯数据手册上的“典型值”别太当真。典型值是在特定测试条件下测出来的你的板子可能不具备那个条件。做设计时按手册最大最小值Max/Min来评估误差或者用TUE这种综合参数更不容易翻车。写在最后的一点体会我自己做ADC采集也有几年了踩得最多的是两类坑一类是参考电压不干净另一类是只盯着位数忘了前端噪声。其实分辨率、LSB、精度这三个词说穿了就是“能看多细”和“看得多对”的区别。LSB是刻度分辨率是有多少刻度精度是你用这把尺子去量东西靠不靠谱。尺子刻度再多尺子本身是歪的量出来的数也全是白搭。如果这篇文章你只记一句话那就是分辨率是纸面上的能力上限精度是电路里一点一点抠出来的工程结果。希望这篇能让你以后拿到ADC数据手册时先看ENOB和TUE再看位数拿到板子时先测底噪再谈采集精度。我在这些坑里摔过的跟头你能绕开几个这篇就没白写。
返回列表