
1. 从一次采样数据抖动说起AD/DA模块到底在干什么几年前我做过一块电池组检测的小板子用的是主控芯片自带的12位ADC分压之后读单节电压。原理上没问题可实际读数一直在正负七八个码之间跳换算下来抖动接近8mV做电量估算还行做单体一致性判断就完全不够看。当时我以为换个外置的AD/DA模块就能立刻解决问题结果第一次换上一颗16位AD模块读数反而更飘了——后来查了两个晚上问题出在参考电压和地线上模块本身一点毛病没有。这件事之后我才真正把AD/DA模块当成一个“系统”来看而不是一个“芯片”。AD/DA模块这四个字说的其实就是模数转换与数模转换这一对搭档。AD模块负责把传感器、电桥、热电阻、分流器送出来的连续电压变成数字量DA模块负责把处理器算出来的数字量还原成电压或者电流去驱动执行器、设定点、调光、调速。搞硬件、做数据采集、写嵌入式固件、折腾仪器仪表的人几乎绕不开这两个东西。这篇就按我自己的踩坑顺序把它的原理、参数、接线、驱动和排查一条条讲透新手能照着跑通做过几年的人也能从里面挑到几条能省时间的细节。1.1 模拟世界与数字系统之间那道必须被量化的门现实世界里的物理量都是连续的。热电偶输出的热电势是连续的压力变送器输出的是连续的电流光敏管出来的也是连续电流。处理器只认离散的0和1中间必须有人做一次翻译这个翻译动作分两步走先在一个时间点上把信号“摁住”不动这叫采样再把这一个瞬间的幅度切成有限个等级这叫量化。采样让时间变成离散的量化让幅度变成离散的这两步合起来就是AD转换。DA转换是反方向的操作把一串数字码映射回一个电压或者电流然后再由后级的滤波、放大、驱动电路补回连续性。理解这一点特别重要因为后面遇到的绝大多数精度问题都能往上追溯到这两步。采样这一步引入的误差叫混叠来源于采样速度不够量化这一步引入的误差叫量化误差来源于等级不够密再加上参考电压本身的漂移、输入前端的噪声、地线上的干扰最终你拿到的那个数字是所有这些误差叠在一起的结果。用芯片自带的ADC还是外挂模块本质上是在问一句我需要的有效精度主控芯片给不给得了。自带ADC省事、便宜、速度快、不占板子面积但它通常拴在芯片的电源上参考就是那颗3.3V的LDO精度和噪声都要打折扣。外置模块的价值在于它能把参考、前端放大、滤波、甚至隔离都统统单独做好你付出的是成本、布线和一颗额外的芯片。我个人的判断标准是只要量程内需要的分辨力低于1mV或者需要在电机、继电器、开关电源旁边稳定工作我就直接上外置的。1.2 采样定理不是背书量化误差到底长什么样采样定理的说法很朴素采样频率至少得是被测信号最高频率的两倍否则高频成分会折叠到低频里去形成假的信号这就是混叠。工程上没人卡着两倍来我一般按5到10倍取被测信号里如果含有快速边沿前面还要加一级模拟低通滤波把超出采样带宽的成分先摁下去。这一级滤波器常被省掉省掉之后你看到的就是一个“怎么调都不对”的诡异波形。量化误差更值得说清楚。一个N位的AD模块把满量程FSR切成2的N次方块每一块的大小就是最低有效位LSBLSB FSR / 2^N理想情况下量化误差是正负半个LSB且呈现均匀分布。把这种误差当作噪声来看可以得到一个很有用的经验公式理想N位转换器的信噪比大约是SNR(dB) ≈ 6.02 × N 1.76反过来说如果实测出来的信噪比比这个值低了不少说明有效位数ENOB已经掉下来了掉的原因是噪声、参考漂移、非线性而不是“位数不够”。我见过太多人拿着一个16位模块抱怨精度不行实际上有效位数可能只有12位出头剩下的四位全被前端噪声和布局吃掉了。这个公式最大的价值是给你一把尺子设计之前先算一遍理论值实测之后再算一遍两者的差值就是你要去攻的噪声预算。1.3 什么场景下才真的该上外置模块不是所有项目都需要外置。按键检测、电位器旋钮、粗略的温度读取、电池电压的大致判断主控芯片自带的12位ADC完全够用硬上外置模块只是给自己找麻烦。真正值得上外置模块的场景我总结成这么几类。第一类是分辨力要求高。比如用Pt100测温度或者用应变片测微小形变信号本身只有几毫伏到几十毫伏需要先把量程压到很小的范围再放大自带ADC那点分辨力完全不够。第二类是要求低噪声和低漂移。典型的如电子秤、精密电流检测、计量类的设备需要参考电压稳定到ppm级别自带ADC的参考做不到。第三类是多通道同步。三相电参数测量、多路振动采集这类场合需要几个通道在同一时刻采样分时轮询会引入通道间的相位误差专用的多通道同步模块才顶得住。第四类是环境恶劣或者需要隔离。变频器旁边、大电流母排旁边、长线缆传输的场合隔离型AD/DA模块能救命。第五类是希望把模拟部分和数字部分解耦。数字电源的纹波会影响ADC把模拟前端单独供电、单独参考效果立竿见影。还有一个经常被忽略的理由可维护性。外置模块是一个明确的、可替换的单元出问题换一颗就行用主控内部ADC一旦模拟通道设计有问题整块板子都得重来。2. 看AD模块的规格书除了分辨率还有四个坑人的参数新手挑AD模块第一眼看位数这没错但只看位数一定会踩坑。位数决定了理论的台阶数实际的台阶能不能用取决于量程、参考、输入阻抗和采样速率这四件事它们每一个都能把有效精度往下拽好几个位。2.1 分辨率、量程与LSB的换算账先算清楚一笔账。同样是16位量程不同一个码代表的电压差得远了。这个换算我建议在选型阶段就写在纸上因为后面所有的噪声预算都要以它为基准。位数量程配置一个LSB1000个码对应电压12位0~3.3V 单端0.806mV0.806V12位0~5.0V 单端1.221mV1.221V16位±2.048V62.5μV62.5mV16位±0.256V7.81μV7.81mV24位±2.5V0.298μV0.298mV看这张表能得出两个很实用的结论。第一压缩量程比堆位数划算。把量程从±2.048V压到±0.256V等效于多了三位分辨率代价是前端信号必须先放大到匹配这个范围同时输入的共模和噪声要求更严。第二位数越高对每一个LSB的物理要求就越苛刻。16位在±0.256V量程下一个LSB只有7.8微伏这个电压比一根普通铜线和焊点之间的热电势大不了多少所以高分辨率模块必须认真处理热电势和漏电流否则最后几位就是随温度乱跳的噪声。很多模块带可编程增益放大器增益档位本质上就是在切换上面这张表里的量程列。用PGA的时候有个典型的坑信号刚好跨在档位边界上。比如信号在0.25V附近晃PGA在×8和×16之间来回切读数会在两个档位之间跳一个台阶。解决办法是选档留15%以上的余量或者干脆锁死一个档位用软件做量程压缩。2.2 参考电压才是精度的天花板这是我认为最容易被低估的一条。AD转换的本质是把输入电压和参考电压做比例所以参考电压不准输入测出来一定不准。而参考电压的误差有三块初始精度、温漂、噪声。用主控的3.3V电源做参考初始精度通常在±2%左右温漂几十到上百ppm每摄氏度。算一笔账就明白问题有多大一个16位、±2.048V量程的模块一个LSB是62.5微伏。参考电压如果漂了20毫伏折算到输入端相当于20mV除以2.048V再乘上满量程码数大约是640个码的偏移。640个码在16位系统里意味着什么意味着你辛辛苦苦堆的三位分辨率被一次温度变化吃掉了。所以只要项目对精度有点要求我都会用外置基准。基准选型的三个关键指标是初始精度、温漂系数和输出噪声其中温漂最关键因为它随环境温度变你没法用一次标定抹掉。另外注意基准的输出电流能力和去耦基准输出端一定要放合适的电容具体容值按规格书推荐来放错了可能引起振荡反而更糟。这里还有一个非常实用的技巧叫比例式测量。如果用同一个参考同时驱动传感器电桥和AD模块的参考端那么参考漂移在分子分母上同时出现会互相抵消测量结果对参考的依赖大幅降低。称重、应变、压力这类惠斯通电桥的应用特别适合这么干。2.3 输入阻抗、采样保持与源阻抗的配合大多数逐次逼近型AD模块的输入端内部有一个采样电容转换时这个电容要在一小段时间内被外部信号充到目标电压。这段充电时间由内部的采样开关电阻加上你的外部源阻抗共同决定。源阻抗越大充电越慢充不满就会带来误差而且这个误差跟信号大小有关表现为非线性。工程上的经验做法是这样分压电阻的总阻值尽量别超过几十千欧具体上限看模块规格书里给的建立时间指标如果信号源本身是高阻的比如某些传感器直接输出那就必须在AD前面加一级运放缓冲选低失调、低偏置电流的型号。我自己踩过的坑是用两个100k的电阻分压去测12V读数在小电压段一切正常到了大电压段就偏低换成10k的分压加一级跟随器之后线性度立刻好了一个数量级。差分输入还要额外关心共模范围。很多差分AD模块允许输入正负压差但两个引脚对地的共模电压必须落在规定区间内超了读数会直接跑飞。遇到地电位差比较大的场合先用仪表放大器把差分信号调理好再送进AD比硬接省事得多。2.4 速率、接口与噪声之间的三角关系采样速率不是越快越好它是一个三角关系的一端另外两端是有效位数和抗干扰能力。数据率提高内部模拟带宽跟着变宽进来的噪声总量就变大等效有效位数下降。这是一个非常普遍的规律用同一颗芯片在不同速率下测同一个直流基准就能明显看到位数在变。数据率档位典型有效位数适用场景8~16 SPS接近16位静态量、温度、称重128 SPS15位上下慢速多通道扫描860 SPS13~14位音频包络、快速监测所以选速率的原则是够用就行不要为了“看起来快”把速率拉满。测温度的通道开到860SPS纯粹是给自己找噪声。接口方面I2C接线的引脚少、布线简单但速率低、总线容易挂死多设备共享时还要处理地址冲突SPI速度快、全双工适合高速多通道代价是占用引脚多。我个人的习惯是慢速、少量通道、板子空间紧张就用I2C高速、多通道、要求严格同步就用SPI。3. DA模块的输出链路从数字码到干净电压要过几道关DA这块被谈论得少但实际项目里翻车的概率一点不低因为它的错误往往不是“读不到数”而是“输出看起来对但带不动负载”或者“有台阶、有毛刺”。把输出链路拆开看问题会清楚很多。3.1 电阻网络型与PWM滤波型是两条完全不同的路第一条路是用真正的DAC芯片内部是电阻串或者R-2R网络数字码进来直接切换电阻分压比输出一个跟参考成比例的电压。这类方案分辨力高、单调性好、建立快像常见的12位I2C小DAC、10位SPI DAC都属于这一类适合做精密设定点、可编程基准、模拟量输出模块。第二条路是用PWM加RC滤波靠占空比的变化和滤波器的平均效应得到电压。它的好处是几乎零成本任何一颗带PWM的单片机都能做缺点是分辨力和纹波天然打架。算一下就知道PWM频率100kHzRC取1k和1μF时间常数1ms远大于周期10微秒输出电压是占空比乘以幅值纹波峰峰值大约等于幅值乘以占空比乘以1减占空比再除以频率与时间常数之积。在50%占空比、3.3V幅值下纹波大约是8毫伏峰峰值。8毫伏在12位、3.3V量程下相当于10个码也就是说这个滤波器只能给你10位出头、而且台阶边缘不干净的效果。我的选择原则很直白要精度、要稳定、要做闭环控制就用真DAC只是驱动一个LED亮度、调一个风扇转速、给比较器设个粗略阈值PWM加RC完全够用还能省一颗芯片。用PWM路线的话记得把PWM频率往上提同时把RC时间常数加大再在后面补一级二级滤波纹波会明显改善。3.2 建立时间、输出运放与负载匹配DAC的输出不是理想电压源它有一个输出阻抗也有一个从码变化到电压稳定的建立时间。建立时间决定了你能多快更新输出如果要做一个1kHz的正弦波输出那么每个周期只有1毫秒分成几十个点每点只有几十微秒的稳定窗口建立时间必须远小于这个窗口否则波形会严重失真。负载匹配是另一个高频翻车点。DAC输出的电流能力通常只有几百微安到几毫安你要是直接拿它去驱动继电器线圈、LED、电机驱动器的输入电阻输出电压立刻被拉下来而且拉下来的程度跟输出码有关看起来就是一条弯掉的传输曲线。正确的做法是DAC后面加一级运放做缓冲运放选轨到轨输出、低失调的型号负载电流全部由运放承担。还有一个容易忽略的细节是容性负载。运放直接驱动长线缆或者大电容时容易自激振荡表现为输出上叠加高频抖动。串一个小电阻做隔离通常几十欧姆到一百欧姆就能压住这个振荡代价是带载时有一点分压误差算进标定里就行。3.3 输出端的滤波、缓启动与上电冲击DA输出端我一般会留三个位置一个串联的隔离电阻一个对地的滤波电容还有一个用来限流的保护电阻。滤波电容不是为了平滑数字码的跳动而是为了滤掉DAC更新时产生的高频分量同时给后级提供一个低阻抗的瞬间电流源。缓启动也值得强调。上电瞬间DAC输出可能是一个不确定的状态如果后级接的是功率级的设定点这个不确定状态会被放大成一次冲击。解决办法有两个一是上电后先给DAC写一个安全的默认值再放开使能二是在输出端加一级斜坡限速让电压按预定斜率爬上去。做电源模块和电机驱动的时候这个细节能省下不少炸管的钱。用DAC做工业标准输出的思路也是从这条链路延伸出去的先把0到满量程的数字码映射成电压再经过一级运放转换成电流环路或者经过比例放大变成0到10V标定的时候抓住两个端点就能把整条链路校正好。4. 接线与驱动的完整跑通流程理论说完了回到实操。我按自己带新人的顺序把跑通一颗I2C接口AD模块和一颗I2C接口DA模块的全过程拆一遍中间那些“文档上没写但一定会遇到”的点都标出来。4.1 上电之前必须过一遍的检查清单很多人是焊完直接上电读不到数再回头找问题效率极低。我习惯先坐下来按清单看一遍五分钟能省两小时。检查项要点常见错误供电电压是否在规格范围模拟供电是否有独立滤波直接用数字3.3V噪声大参考外部基准是否接好去耦电容是否按要求参考引脚悬空读数乱跳总线I2C上拉电阻是否装上阻值是否合适忘记上拉或者从板子上又并了一组地址地址引脚的接法是否与代码一致地址算错完全不应答接地模拟地与数字地是否单点连接两处连接形成地环路去耦每个电源引脚是否就近放了电容电容离得远等于没放关于上拉电阻我的经验值是3.3V系统用4.7k5V系统用10k总线很长或者设备很多时降到2.2k。上拉太小会增加总线电容带来的上升沿问题上拉太大则上升沿太缓高速率下会出错。还有一点如果模块自带的板子上已经有上拉主板上就不要再加了并起来阻值变小反而容易出问题。4.2 寄存器配置与最小闭环代码以最常见的可编程增益型16位I2C AD模块为例跑通的最小闭环就是四步配置寄存器选定输入通道、增益、数据率和单次转换模式触发一次转换等待转换完成可以延时也可以读状态位读回两个字节拼成有符号整数再乘上LSB换算成电压。需要记住的换算关系是读回的码值乘以对应量程的LSB就是电压。这里必须强调一句很多模块的输出码是补码形式的有符号数直接当成无符号数去算结果会在跨零的地方出现巨大的跳变这个坑我见过不下五个人踩。用Python在树莓派一类的主机上快速验证会比写单片机固件快得多import time from smbus2 import SMBus ADDR 0x48 # 模块地址务必先用i2cdetect确认 CONFIG 0xC383 # 通道、增益、速率、单次模式的组合 LSB 0.000125 # 这里假设量程对应的每码电压单位V bus SMBus(1) def read_voltage(): bus.write_i2c_block_data(ADDR, 0x01, [(CONFIG 8) 0xFF, CONFIG 0xFF]) time.sleep(0.02) # 留足转换时间速率越慢等得越久 data bus.read_i2c_block_data(ADDR, 0x00, 2) raw (data[0] 8) | data[1] if raw 0x7FFF: # 补码转有符号 raw - 0x10000 return raw * LSB while True: print(V %.6f % read_voltage()) time.sleep(0.5)对应的C语言版本结构一样只是把总线的读写换成HAL或者寄存器操作。DA模块的驱动更简单以12位I2C DAC为例把12位数据拆成两个字节加上命令字一起发出去就行#include stdint.h #define DAC_ADDR 0x60 #define DAC_WRITE_REG 0x40 uint8_t dac_write(uint16_t code) { if (code 0x0FFF) code 0x0FFF; /* 12位模块越界一定要夹紧 */ uint8_t buf[3]; buf[0] DAC_WRITE_REG; buf[1] (code 4) 0xFF; /* 高8位 */ buf[2] (code 4) 0xF0; /* 低4位补在字节高位 */ /* 这里调用你平台上的I2C发送函数 */ return 0; }代码本身不长真正花时间的是把参数含义搞对。我强烈建议第一次调试时把配置寄存器按位拆开用纸写一遍每一位是什么含义比反复改代码试要快。4.3 拿万用表和示波器验收的判定标准代码跑起来能出数不代表模块工作正常。我有一套固定的验收动作基本十分钟就能判断这颗片子是真好还是凑合。第一步把输入端短接到地看零点。理想情况下读数接近零实际会有几十个码的失调这个数值记录下来作为后面标定的偏置。第二步输入端接到一个已知的、比参考更准的电压上看满量程附近的读数据此算出增益误差。第三步用可调电源从小到大扫一遍每个点记下读数和标准值看误差曲线是否单调、有没有明显的台阶台阶说明有失码或者档位切换问题。第四步把输入固定在一个中间值上用示波器看电源引脚和参考引脚上的纹波同时记录读数的峰峰值波动这就是整个系统的噪声底线。验收项合格参考不合格的典型表现零点失调稳定、重复性好每次上电差异大满量程误差在标称范围内明显偏大或偏小说明增益或参考有问题线性扫描曲线单调平滑出现跳变台阶噪声峰峰值在几个码以内十几到几十个码乱跳示波器探头记得用弹簧地针别用那根长长的鳄鱼夹地线否则你看到的“噪声”大部分是探头环路自己感应来的。5. 调不通的时候按这个顺序排查调试现场最忌讳东一榔头西一棒槌。我给自己定了一条固定路线先看是不是完全不响应再看是不是响应了但数值不对最后看是不是数值对但会漂。按这个顺序走基本不会漏。5.1 读数全是零或者全满先从参考和地址入手完全不响应或者读数固定在一个极端值这类问题的根因高度集中。第一种是地址错了。I2C模块的地址通常由一两个引脚的高低电平决定规格书上给的是一个基准地址加偏移很容易算错一位。上电之前先用总线扫描工具扫一遍确认设备真的在总线上这一步能排除掉一半的问题。第二种是参考没接好或者参考引脚被误接到地或者电源上。参考异常时转换结果通常表现为全部挤在量程的一端。第三种是通道选择写错。多个输入通道共用一组寄存器位配置字写错的时候你读到的可能是另一个悬空通道自然全是噪声或者满值。第四种是增益档位越界。信号超过了当前档位的量程转换结果会饱和在最大值看起来就像“一直读满”。第五种是SPI接口的时序模式搞错了。时钟极性和相位有四种组合模式不对时读到的位是错位的表现为数据看起来完全随机。我的排查动作是这样先量供电和参考的实际电压再用总线工具确认设备存在并能读出一个已知寄存器接着把配置字改成最简单的单通道、最低速、固定增益排除掉所有花哨配置的干扰最后再逐个加回功能。这个“最小配置起步”的习惯帮我省过无数次时间。5.2 数值乱跳和工频干扰几乎都出在地和布线上数值在一个不大的范围内持续跳动是第二类典型症状。如果跳动的规律跟时间有关比如每隔一段时间冒一个大值通常是外部干扰耦合进来如果跳动的频率恰好是50赫兹或者100赫兹那基本可以确定是工频干扰。工频干扰的传播路径有几条。最常见的是地线环路信号源和采集板分别接了不同的地两个地之间有电位差这个电位差直接加在信号上。解决方式是让信号走差分输入或者用屏蔽双绞线把信号和它的地一起送过来。第二条路径是电源耦合模拟供电和数字供电共用一条线数字电路的开关噪声直接串进来。解决办法是模拟部分单独走线、单独去耦必要时在电源入口串磁珠。第三条路径是空间耦合长线缆像天线一样接收工频电场。屏蔽层单端接地能解决大部分问题。还有一个很容易被忽略的点是采样时机。如果采样是自由运行的跟工频没有固定关系那么干扰会在读数上形成低频的拍频看起来像是缓慢漂移的大数。把采样时刻同步到工频周期的整数倍或者干脆在一个工频周期内采整数个点做平均这个漂移会立刻消失。这个技巧在电力参数测量里几乎是标配。现象可能根因快速验证方法读数固定为0或满值参考异常、地址错误、通道配置错误量参考电压扫描总线读回配置寄存器读数在几十个码内随机跳前端噪声、去耦不足、源阻抗过高短接输入看噪声加运放缓冲读数周期性大幅跳变工频干扰、地环路改差分输入检查接地方式读数单调变化但不够准参考精度、增益误差两点标定换高精度基准对比5.3 非线性、温漂与那些“通电能跑跑两小时就不行”的问题第三类问题最折磨人因为它往往跟时间和温度有关。最典型的是自热。分压电阻功耗大了会把附近的PCB加热AD模块的温度系数开始发挥作用读数慢慢往上漂。测一下开机的读数和运行半小时之后的读数如果差值明显先怀疑自热。解决办法是加大分压电阻的阻值或者用更小的功耗设计同时把温度敏感的元件分散开布置。热电偶效应也是一个大坑。不同金属的连接点之间会产生热电势量级在每摄氏度几微伏。前面算过16位小量程下每个码只有几微伏一个焊点和一个接插件之间的温差就足以让它漂起来。所以我做高分辨率的板子时会尽量避免在模拟输入回路上出现异种金属连接实在避不开就做等温设计让同一回路的两个连接点温度尽量一致。还有一类是PCB漏电流。助焊剂残留、潮气、手指的汗渍都会在模拟输入的高阻抗节点附近形成一条漏电通路读数会表现为高值拉低、低值抬高整体曲线被压扁。用无水乙醇清洗并彻底吹干往往能立刻恢复。这个经验我是在南方梅雨季吃过大亏之后才学乖的现在只要板子涉及高阻抗模拟输入出货前必洗必烘。最后一个建议是给自己一个“基线对比”的习惯。手头留一块已知良好的参考板出问题的时候把怀疑的板子和它接在同一个信号源上并行跑一段时间两条曲线的差异能立刻告诉你问题在板子本身还是在外部环境。这比单看一条曲线猜原因快得多。6. 标定、滤波与长期稳定性把可用精度再提一档硬件做完、驱动跑通剩下的工作就是软件上的精雕。这三件事做得好同一套硬件的可用精度能有明显提升而且成本几乎为零。6.1 两点标定比想象中更管用理想情况下测得的码值与实际电压是线性关系斜率和截距分别对应增益和偏置。标定就是把这根直线的两个参数找出来。最实用的做法是两点法找一个接近量程下限的标准值再找一个接近量程上限的标准值分别记录读数解出斜率和截距之后所有读数都用这两个参数修正。两点法的前提是系统的非线性足够小。如果扫描一遍发现中段偏离直线比较明显那就得用多点最小二乘拟合把二次项也考虑进去。不管几点标定有两条原则不能破第一标定用的标准源精度至少要比目标精度高一个数量级用普通万用表去标定16位系统是自欺欺人第二标定必须在整机温度稳定之后进行冷机标定出来的参数热机了就不准。标定的参数不要写死在代码里存到非易失存储里并且用一个版本号或者校验值保护起来。我遇到过因为标定参数丢失导致整批设备偏移的情况后来加了校验值读取不合法就回到默认值并报警这类问题就再没出现过。6.2 中位值、滑动平均与过采样的取舍数字滤波这块手法看着多用起来其实就那几招关键是知道各自适合什么场合。中位值滤波连续取奇数个样本排序后取中间那个。它对突发性的脉冲干扰特别有效比如继电器动作、电机启停带来的单个大跳变一个中位值就能把它抹掉代价是响应稍微慢一点且对持续性噪声无效。滑动平均取N个样本求平均。它对付随机噪声效果很好噪声的峰峰值大约按根号N的规律下降也就是说4个点平均能把噪声降到一半。代价是很明显的滞后N越大响应越慢不适合跟踪快速变化的信号。我在实际项目里一般把N控制在4到16之间超过16就改用带遗忘因子的方式让新数据权重更大一些。过采样用远高于需要的速率采样然后若干个点相加再抽取。理论上噪声是白噪声的前提下采样率每提高4倍、平均4个点可以换来大约1个比特的有效位数。这个技巧非常实用很多低成本的方案就是靠过采样硬生生多做出两三位。但它有个前提条件就是噪声必须足够“白”、足够随机而且样本量要够。如果噪声里带有明显的周期性成分过采样不但没好处还可能把干扰放大成一个固定偏移。这时候一个巧妙的做法是主动注入一点微小的抖动信号让量化误差随机化反而能改善过采样效果。滤波方式抗脉冲干扰降随机噪声响应延迟适用场景中位值强弱中有开关动作的场合滑动平均弱强大缓慢变化的静态量过采样弱中中追求额外有效位数一阶低通弱中小跟踪一般动态信号6.3 长期运行的自检与回归验证设备装到现场之后最怕的是慢慢变坏而且没人发现。我给自己做的每一套采集设备都留了自检的手段用不了多少资源但能救命。第一招是预留一个基准通道。把一路输入固定接在基准上定期采一次读数偏离历史值超过阈值就报警。这一路不需要额外的硬件只需要在PCB上多留一个电阻的位置。第二招是上电自检。开机时先读基准、读零输入确认两个端点都在合理范围内才进入正常工作不通过就直接停在故障状态并给提示比带病运行强得多。第三招是记录漂移曲线。把每天的自检数据存下来看长期趋势很多问题在数值还没超限的时候趋势已经能看出来。这里有一个我自己的体会把校准系数的历史值也记录下来。如果某次维护之后系数发生了明显跳变说明硬件状态变了这时候与其覆盖旧值不如先查一下为什么变了。我有过一次经历是接插件氧化导致接触电阻变化标定系数连续几次都往一个方向跑最后查到接插件换掉之后一切恢复正常。如果当时只是机械地重新标定问题会一直藏着直到某天彻底失效。再补一个小技巧。做多通道系统的时候可以在空余的低成本通道上接一个固定的分压把它当成一个“环境传感器”专门用来监视参考和电源的长期变化。它的绝对值不需要准只需要稳定一旦它的读数出现台阶你立刻就知道整个系统的参考链路上出了问题而不是某个具体的信号出了问题。这套东西我前后迭代了三四版从最早只关注“能不能读出来”到后来关注“读出来准不准”再到最后关注“一年之后还准不准”。每次出问题回头看几乎都能在采样、参考、接地、滤波这四个环节里找到对应的影子。把这几件事老老实实做扎实比换更贵的芯片有用得多。