
前阵子手上有个项目板子用的是 imx6ull外挂一颗 12 位的 ADC型号就不点名了SPI 接口最高 1Msps要采一路 0~5V 的传感器信号做温度监控。按理说 12 位参考电压 3.3V理论分辨率 3.3/4096 ≈ 0.8mV算下来精度挺够用的。结果实测出来的数据跳动得厉害。同一个稳定输入采 100 个点最大值和最小值能差出 40 多个 LSB换算成电压差不多 30 多 mV。这还只是静态输入动起来更没法看。我一开始以为是传感器本身噪声大换了个稳压源直接灌电压还是跳。又怀疑是 SPI 时序问题拿逻辑分析仪抓波形时序干干净净。折腾了小半天才意识到问题不在采而在采之前和采之后。今天就把我踩过的这几个坑捋一遍都是那种不显眼、但真能把精度吃掉的隐形杀手。一、相关知识点先把这个 ADC 的基本情况说清楚后面才好展开。这颗 ADC 是逐次逼近型SAR12 位内部采样保持电容大概几 pF 量级输入阻抗不算高。数据手册里写了一句很关键的话建议源阻抗小于 1kΩ。这句话我当时扫了一眼就过去了后来才知道这是第一个坑的根源。再一个概念是有效位数ENOB。12 位是标称分辨率但实际能用的位数往往要打折。ENOB 才是你真正能信的数。一个 12 位 ADC如果 ENOB 只有 9 位那后 3 位基本就是噪声跳来跳去很正常。还有参考电压。很多人默认 VREF 就是电源电压稳得很。其实 VREF 上的任何纹波、噪声会 1:1 地反映到转换结果里。VREF 抖 1mV输出就跟着抖。最后是数字滤波。采样值不是采完就能用的尤其低频信号过采样 平均是最便宜有效的降噪手段。二、解决过程1、先查源阻抗我回到原理图看传感器到 ADC 输入之间串了什么。结果发现中间串了个 10kΩ 的电阻做限流保护还并了个 100nF 电容到地。这就坏了。10kΩ 远大于手册建议的 1kΩ。SAR ADC 采样瞬间内部采样电容要在很短时间内充到输入电压源阻抗太大充电不充分采到的值就偏低而且每次偏低程度还不一样——这就是跳动的来源之一。处理办法有两个一是降低源阻抗二是加缓冲运放。我先把 10kΩ 换成 1kΩ实际测试还是不行呀跳动是小了点但还有 20 多个 LSB。折腾了大半天才发现问题不止这一个——那个 100nF 电容和 1kΩ 电阻构成了 RC时间常数 100μs而我的采样率是 10ksps间隔 100μs电容根本来不及跟上信号变化反而在动态时拖后腿。把电容改成 1nF 之后静态跳动降到 10 个 LSB 以内。2、查参考电压源阻抗搞定后还剩 10 个 LSB 左右的跳动。我拿示波器AC 耦合20mV/div量 VREF 引脚果然看到一条毛刺峰峰值大概 15mV频率跟 SPI 时钟对得上。原因是我图省事VREF 直接接的 3.3V 数字电源跟 MCU、SPI 共用。SPI 一通信电源上就有开关噪声VREF 跟着抖。改法VREF 单独走一路 LDO输出并 10μF 钽电容 100nF 陶瓷电容就近放。改完再量VREF 纹波降到 2mV 以内采样跳动降到 3~4 个 LSB。这里插一句很多人喜欢在 VREF 上并大电容觉得越大越稳。其实要看 LDO 的环路稳定性有些 LDO 对输出电容的 ESR 有要求乱并反而会振。我这次是照着 LDO 手册推荐的容值来的没敢乱来。3、软件上做平均滤波硬件改完静态已经不错了。但实际工况下还是有零星跳点尤其是电机一启动干扰就上来了。软件上加了个简单的中位值平均滤波连续采 16 个点去掉最大最小各 2 个剩下 12 个求平均。代码大概这样#defineN16staticintadc_filter(intraw[N]){inti,j,tmp,sum0;/* 冒泡排序N 小无所谓 */for(i0;iN-1;i)for(j0;jN-1-i;j)if(raw[j]raw[j1]){tmpraw[j];raw[j]raw[j1];raw[j1]tmp;}for(i2;iN-2;i)sumraw[i];returnsum/(N-4);}实测输出滤波前: 2048 2051 2045 2053 2047 2050 2044 2052 ... 滤波后: 2048 2048 2049 2048 2048 2048 2049 2048 ...跳动从 ±5 LSB 压到 ±1 LSB。代价是响应变慢16 个点按 10ksps 算延迟 1.6ms。对温度这种慢变量完全无所谓但如果你采的是快速信号这个滤波就得慎用或者换成滑动平均。4、顺手查了下地最后还发现一个细节ADC 的模拟地和数字地我在板子上是单点连的但连的位置离 ADC 有点远中间走了段细线。把它改到 ADC 芯片正下方用 0 欧电阻单点连接又好了那么一点点。这一步收益不大但属于该做对的事顺手做了。三、结果和遗留三处改完最终静态跳动控制在 ±2 LSB 以内动态电机启停瞬间最大 ±5 LSB。按 3.3V/4096 折算大概 ±1.6mV对这个温度监控场景够用了。遗留问题也有我这套改动是在现有板子上飞线验证的正式版还得改 PCB。另外那个 1nF 采样电容的取值跟采样率和源阻抗强相关换颗 ADC 就得重新算不能照抄。参考资料主要是这颗 ADC 的数据手册重点看Source Impedance和Reference Input两节还有 TI 那篇讲 SAR ADC 前端设计的应用笔记网上搜SAR ADC front-end design就能找到。感谢写这些文档的工程师真是省了我不少事。我这方面也就学了点皮毛上面这些结论都是在自己板子上实测出来的换个平台不一定完全适用。有踩过类似坑的朋友欢迎留言交流说不定你那个坑我还没遇到呢。如果这篇对你有用请扫码关注。