前阵子做一套工业控制器温度采集部分要求整机精度做到±0.5℃以内传感器这边热电偶、PT100、NTC三种都要兼容控制器的主控还得分心去管通信、显示和控制逻辑。选了一圈最后定下来的是两片芯片的组合TI 的 ADS122U04IPWR 做前端模拟采集Microchip 的 PIC32MZ1024EFF144 做主控中间走 UART 连接。这套组合做完之后热电偶读数在恒温箱里能看到 ±0.1℃ 以内的稳定度PT100 在 -40℃ 到 85℃ 范围内线性段也压得住指标。这篇文章把从选型理由、硬件测量链路设计、软件驱动实现到现场噪声排查和标定验证的全过程完整写出来中间有大量踩坑记录和实操细节适合近期要做温度采集、多点测温或者工业/暖通控制器开发的朋友参考。为什么值得用一颗带 UART 接口的 24 位 ADC 配一颗大 Flash 的 32 位 MCU说到底还是信号链路的分工问题传感器给出的微弱信号得先被完整、干净地数字化之后的各种滤波、补偿、断线报警才能在数据意义上展开。先用一个章节把这条链路拆清楚后面所有硬件和软件设计都好理解。1. 先理清信号链路ADS122U04IPWR 和 PIC32MZ1024EFF144 的分工边界1.1 三类温度传感器输出信号差着好几个数量级工业与 HVAC 场景里最常见的温度传感器基本就三类。热电偶输出的是微伏级电压K 型热电偶的灵敏度大约 41μV/℃J 型大约 55μV/℃测 1000℃ 时信号也才几十毫伏没有足够高增益的 ADC 前端这信号基本是白测。PT100/PT1000 这类热电阻输出的是电阻变化PT100 在 0℃ 时是 100Ω温度每变化 1℃ 大约变 0.385Ω必须靠恒流源或恒压源把它变成电压信号再去测量。NTC 热敏电阻的阻值随温度变化非常剧烈一个 10kΩ 的 NTC 从 25℃ 变到 85℃阻值能掉一个数量级好处是灵敏度高坏处是非线性严重、还要小心自热误差。这三类信号如果都挤在同一块 ADC 上ADC 必须同时具备高增益可编程放大器PGA、激励电流源IDAC、灵活的输入多路复用器以及高分辨率。否则就得在板子上堆一堆运放和模拟开关既占面积又难调试。1.2 ADC 内置资源PGA、IDAC、内部基准、内部温度传感器ADS122U04IPWR 是一片 24 位 Δ-Σ 型 ADC它最打动我的其实是把测量前端需要的周边器件一次集成完。它内置了增益 1 到 128 倍的可编程放大器热电偶那种微伏级信号可以直接进 PGA内置两个 IDAC 恒流源输出电流从 50μA 到 1.5mA 多档可调正好用来激励 PT100/PT1000内部还带一个 2.048V 基准源虽然性能比外部分立基准弱一点但做 NTC 测量已经足够更实用的是它内部有一个温度传感器可以用来测芯片附近的冷端温度配合热电偶做冷端补偿。输入通道方面它有 4 个模拟输入引脚可以配成 2 路差分输入或 4 路单端输入。对于工业温度采集差分输入在抗共模干扰上的优势非常明显比如热电偶的引线比较长两端对地电位不一致时只有差分测量才能把共模电压扣掉。1.3 为什么 MCU 端选了 PIC32MZ1024EFF144PIC32MZ1024EFF144 属于 Microchip 的 32 位 MIPS 平台200MHz 主频、1MB 程序 Flash跑温度采集的数学滤波、查表、PID 这些绰绰有余。之所以在这个方案里选它而不是随便一颗 M0 级单片机原因有三。一是这颗芯片的可用外设数量很足UART、SPI、I2C、CAN 各有好几路做控制器时不至于为挂一个通信模块就要换 MCU。二是它带单精度浮点单元后面做 Steinhart-Hart 方程换算、冷端补偿计算的时候可以直接用浮点不用去手写定点算法。三是它的引脚和封装尺寸适合做两片板级设计100 多脚的封装箱子里做多层板很方便模拟区和数字区的脚位安排不至于被憋死。当然如果项目只是单独做一个温度采集模块选一颗 STM32 之类的也能干但在我这个采集控制通信的整体方案里PIC32MZ 的容量和外设冗余让整个项目只用一颗主控就完成了省掉了片间通信和两套固件维护的成本。2. 从传感器到 ADC 引脚热电偶、RTD 与 NTC 的测量链路设计从传感器出来的信号怎么进 ADC这里面的坑比想象中多。ADS122U04 的引脚资源是固定的 4 个模拟输入 AI0-AI3怎么在三种传感器之间分配直接决定了后面寄存器的配置和测量的稳定性。2.1 热电偶差分输入加冷端补偿热电偶的测量链路我用了 AI0 和 AI1 接成差分输入。K 型热电偶的正极接 AI0负极接 AI1中间不要串联电阻直接把热电偶线缆接到板子上。很多人会忽略的一点是热电偶引线的电阻对高增益 PGA 是有影响的如果用的是几十米长的延长线源阻抗可能到几十欧姆而 ADS122U04 在高增益下的输入阻抗并不是无穷大阻抗不匹配会造成分压误差。所以现场布线尽量用热电偶专用补偿导线并且把接线端子尽量靠近 ADC 引脚。冷端补偿这里ADS122U04 内置温度传感器能测芯片内部的温度但工程上更稳的做法是让热电偶连接器的冷端位置尽可能贴住 ADC 或者 PCB 上的铜皮再用内置温度传感器读数反推冷端温度补偿公式里用到的就是热电偶标准多项式。2.2 PT100/PT1000 三线制用 IDAC 把电阻变成电压RTD 的测量链路我用了 AI1、AI2 和 AI3 三个引脚走的是经典三线制接法。一个 IDAC 恒流源从 AI1 向外送电流电流流过 PT100 之后从 AI2 返回同时 AI3 作为独立的感应线接到 PT100 的另一端这样测出来的差分电压只包含 RTD 上的压降不会把连接引线的电阻算进去。用 AD 转换后的电压除以激励电流就能得到 RTD 的电阻值。这里要注意激励电流的大小选择。PT100 本身阻值小在 0℃ 时只有 100Ω用 1mA 激励也只产生 0.1V 压降PGA 增益选 8 或 16 就可以把信号摆在量程的一半。但如果用 PT1000阻值大十倍激励电流反而要降到 250μA 左右否则 RTD 上的压降加上引线上的压降会把 ADC 输入顶到接近满量程还可能让 RTD 自热超过 0.1℃。2.3 NTC 和通用模拟输入别忘了基准与保护NTC 这条链路最简单因为 NTC 阻值变化范围大不需要专门的恒流源直接用电阻分压就可以。我把 10kΩ NTC 从 AI0 输入参考电阻用 10kΩ 0.1% 精度低温漂电阻接到内部 2.048V 基准上分压点进 ADC 单端测量。这里有个细节值得注意分压式测量对基准电压的稳定性要求并不高因为测量结果的误差主要取决于 NTC 电阻和参考电阻的比例基准漂移反而不会造成太大误差倒是参考电阻的温漂会直接变成测量误差所以这颗电阻一定要选好的金属箔电阻或者精密薄膜电阻。NTC 的测量链路还是要加一个保护传感器可能在现场被错误接线或者被雷击感应出高压我在输入端并了一对背对背的二极管限幅到电源轨以内串了 1kΩ 限流电阻。这个保护电阻会带来一点测量误差所以选择时要在误差预算里留出空间或者在实际校准的环节一并补偿掉。2.4 供电与基准的选型ADS122U04 的模拟供电 AVDD 和数字供电 DVDD 我分别做了 LDO 供电而不是直接用系统的 3.3V 开关电源。24 位 ADC 对电源的敏感程度高到什么程度呢开关电源的纹波哪怕只有 10mV在 128 倍 PGA 增益下等效于好几微伏输入误差直接就能体现在热电偶读数上。所以这部分的成本不能省一颗低噪声 LDO 加一颗磁珠再去推动整个模拟小系统的电源轨。外部基准方面如果做 NTC 分压或者 RTD 比例测量可以用内部基准如果对热电偶测量精度要求很高建议用外部精密基准 REF5025 之类它的温漂能做到 3ppm/℃比内部基准稳定得多。在原理图阶段就留出外接基准的焊盘后面标定不合格还能改板补救。3. 在 PIC32MZ1024EFF144 上打通 UART 数据通路硬件链路搭好之后软件这边最核心的就是把 ADS122U04 的 UART 协议跑通。这里说一句芯片虽然写着 UART 接口但它和电脑上那种两根线的异步串口不完全一样驱动起来有几个隐藏的坑我一个个拆开讲。3.1 UART 协议不是 SPI命令、响应和就绪信号严格说ADS122U04 用的是 4 线 UARTSCLK、DIN、DOUT/DRDY、CS。它保留了典型的 SPI 物理层特征SCLK 仍需主机提供CS 仍需片选但字节内部格式是标准的 8 位 UART 帧支持 8N1 和 8N2。也就是说它在物理传输层上像 SPI在命令组织层上像 UART。这样设计的好处是命令集非常简洁单字节命令就能完成大部分操作不像普通 SPI ADC 还要先拼地址、再拼读写位、再拼数据长度。这块芯片常用的命令有这么几个写寄存器 WREG、读寄存器 RREG、读转换结果 RDATA、同步 SYNC、复位 RESET。每次通信前拉低 CS在 SCLK 配合下主机往 DIN 发送命令字节然后从 DOUT/DRDY 读回响应。DOUT/DRDY 还有一个额外职责当数据转换完毕而还没被读走时它会以低电平状态表示数据就绪。3.2 寄存器配置顺序与读写实现ADS122U04 的配置寄存器我从头到尾捋了一遍关键就是先完成通道选择再定 PGA 增益再定数据率最后配置 IDAC顺序不能乱。因为 IDAC 配置和通道选择是有关联的如果先配 IDAC 再选通道某些模式下内部 MUX 可能来不及建立就产生错误输出。下面是一段示意性质的寄存器操作代码重点看命令发送和字节拼装逻辑具体时序要以你手里的 datasheet 为准。#define ADS122U04_WREG 0x43 #define ADS122U04_RREG 0x22 #define ADS122U04_RDATA 0x12 #define ADS122U04_RESET 0x06 static void ads122u04_write_reg(uint8_t reg, uint8_t value) { // 拉低CS按位发送地址和数值最后拉高CS gpio_write(PIN_CS, 0); uart_putc(ADS122U04_WREG); uart_putc(reg); uart_putc(value); gpio_write(PIN_CS, 1); } static uint8_t ads122u04_read_reg(uint8_t reg) { uint8_t val; gpio_write(PIN_CS, 0); uart_putc(ADS122U04_RREG); uart_putc(reg); val uart_getc(); gpio_write(PIN_CS, 1); return val; }实际做连续转换的时候我一般把配置寄存器 0 和 1 写成一次 WREG 连续写多个寄存器减少主机交互次数。寄存器数据率那一位建议先选 50SPS 或者 60SPS因为这两个档位内部带了 50/60Hz 工频陷波器后面噪声那节会提到。3.3 PIC32MZ 端串口初始化和数据解析PIC32MZ 侧我用的是 UART 的发送和接收功能SCLK 和 CS 用普通 GPIO 模拟。初始化的要点有三处波特率设置需要先确认 SCLK 时序是否能跟上不能一味贪快接收端要开 UART 接收中断避免在 ADC 数据连续输出时丢失字节DRDY 信号用 GPIO 中断来监测配合超时机制防止死等。判断转换结果是否就绪可以看 DRDY 引脚的状态也可以直接发 RDATA 命令去读。如果数据没就绪读出来的可能是不完整的旧数据。实际代码里我会加一个简单的状态机启动转换后等 DRDY 拉低拉低之后才发 RDATA 读三个字节读的过程必须连续中间一旦别的中断插入太久就需要重新同步。uint8_t ads122u04_read_conversion(int32_t *code) { uint8_t b0, b1, b2; int32_t raw; if (gpio_read(PIN_DRDY)) { return 0; // 数据未就绪 } gpio_write(PIN_CS, 0); uart_putc(ADS122U04_RDATA); b0 uart_getc(); b1 uart_getc(); b2 uart_getc(); gpio_write(PIN_CS, 1); raw ((int32_t)b0 16) | ((int32_t)b1 8) | (int32_t)b2; // 24位数据转成有符号数 if (raw 0x800000) { raw | 0xFF000000; } *code raw; return 1; }拿到 24 位原始码之后要换算成电压。用内部基准时电压公式是电压 原始码 × VREF / ((2^23 - 1) × PGA)。VREF 用 2.048VPGA 用 128热电偶 1μV 对应的原始码大约是 1280 个 LSB这个分辨率对多数工艺温度控制完全够用。3.4 通信异常排查波特率、FIFO 与超时驱动跑起来的第一个坑就是通信不同步。现象是读回来的数据要么全是 0xFF要么偶尔某个字节跳变。排查顺序我建议先查 SCLK 和 CS 的极性配置再查每个命令之间是否给了足够的间隔最后才是波特率。ADS122U04 的时序要求命令字节发出后要等一小段稳定时间才能继续下一次操作如果主机代码里一条命令接着一条命令地连续写就会出现内部状态没准备好导致丢字节。PIC32MZ 的 UART 自带 FIFO这个功能在普通串口通信里是福音但在和 ADC 的这种同步帧通信里反而是坑。如果从机回的字节到达时主机正在忙别的FIFO 会先把字节存起来等主机有空再读这样时序就乱了。我最后的处理是直接把 UART 接收中断优先级提到最高并在中断服务函数里只做字节排队不做任何计算再由主循环从队列里取字节组帧。4. 实测精度翻车现场五类噪声的识别与压制原理图和代码都调通之后真正让读数稳定可重复靠的是后面几天的噪声排查。这一节的内容比前面任何一步都实用因为芯片的指标再好PCB 上的噪声也会让它发挥不出来。4.1 50Hz 工频干扰周期性抖动的罪魁第一次拿到完整测量数据的时候我发现热电偶读数不是一个稳定值而是在大约 5 个 LSB 的范围内来回摆动摆动周期肉眼看不出来用串口打点画波形之后明显是 20ms 为周期的正弦。这就是典型的 50Hz 工频干扰。解决办法最简单的是把数据率设成 50SPS 或者 60SPS利用 Δ-Σ ADC 的 SINC 滤波器特性把工频和它的谐波陷掉。数据率从 1000SPS 降到 50SPS抖动立刻从 5 LSB 降到 1 LSB。如果你的系统里还有变频器或者可控硅调功器50Hz 干扰还会带大量谐波这时候光靠 ADC 内置滤波不够前端还要加一个差分低通 RC 滤波截止频率压到 100Hz 以内热电偶这种缓变信号完全不影响响应。RC 的值要按传感器源阻抗算别随手抓一个 10kΩ和 ADC 输入阻抗叠加之后会引入新的误差。4.2 开关电源纹波在 24 位 ADC 面前的放大效应电源纹波的问题是上了大功率负载才暴露的。一套加热器在 PID 输出到 100% 的时候温度读数比空载时波动大了快一倍。查到最后是系统 24V 开关电源在满载时纹波变大经 DC-DC 和 LDO 传导到 AVDD 上。LDO 不是万能的中高频纹波的电源抑制比有限尤其 24V 开关电源的开关频率在几百 kHz直接穿透。这个问题的硬件解法是给模拟电源加两级 LC 滤波一级粗滤靠磁珠一级细滤靠低 ESR 电容阵列。软件上我在数据率允许的情况下把采样周期和加热控制周期做了相位错开读数避开加热器刚启动的冲击段实测峰值误差又降了一截。这个采样避开大电流切换的思路在工业控制里非常实用比单纯堆硬件便宜多了。4.3 PGA 增益与源阻抗高增益不是免费的热电偶测量一开始我把 PGA 直接设成 128 倍想着增益越高越灵敏结果读数漂得厉害。后来翻手册才重新理解了源阻抗对 Δ-Σ ADC 的影响增益越高ADC 输入级的动态输入阻抗越低源阻抗一大就形成分压更麻烦的是输入端的采样电容充放电需要时间高阻源充不满等效就引入了非线性误差。后面我把热电偶测量链路拆开分析K 型热电偶本身输出阻抗很小但延长线和 EMI 滤波电阻加起来可能有几十到几百欧姆。在 128 倍增益下几百欧姆的源阻抗已经会让增益误差超过 0.1%所以我的处理是 PGA 降到 64 倍靠外部加一级 10 倍仪表放大器把信号提到合适的幅度。麻烦一点但线性度明显改善。如果你不想加外部放大器就老老实实保持低增益然后在校准算法里把源阻抗造成的误差拟合掉。4.4 数字串扰UART 走线和 GPIO 翻转一个容易被忽视的噪声来源是数字信号对模拟输入的 PCB 板上耦合。我的第一个 PCB 版本把 UART 线直接从 ADS122U04 下方经过DRDY 引脚挨着 AI0 输入结果每次 GPIO 中断读取数据的时候AI0 上都能耦合到几微伏的毛刺。后来把数字线全部改到板子另一层模拟输入引脚周围铺了一圈接地保护环情况好了不少。这里给一个具体的 PCB 布局经验模拟输入引脚旁边不要走任何周期性翻转的数字信号ADC 的 DOUT/DRDY 这类引脚尽量远离 AIx 输入模拟地和数字地单点连接不要在 ADC 正下方直接合并让数字回流电流自己走一条独立的路径回到电源地。4.5 校准路上最容易翻车的三个细节噪声压完之后还有一个坎是校准。我说三个最容易翻车的地方。第一校准时必须先让电路上电稳定至少 5 分钟很多人上电就标结果标完发现后面转漂。ADS122U04 内部基准源的建立时间并不长但板子上的精密电阻和运放需要热平衡等温度稳定再标才准确。第二做零点校准时不要单纯把输入端短路要模拟真实的传感器源阻抗否则标定出来的偏移只在短路条件下有效接上热电偶之后偏移又变了。第三用精密电压源校增益时电压源本身要预热源阻抗要和实际传感器在同一数量级有条件的话用干式温度炉配合标准铂电阻做全链路校准比单纯给 ADC 加电压更贴近工程实际。下面这张表是我在最终产线上用的校准记录模板供参考。校准点传感器类型标准温度ADC 原始码误差折算零点PT1000.0℃8388600.02℃满点PT100100.0℃109226-0.05℃冷端热电偶25.0℃1040000.08℃5. HVAC 和工业环境下的标定流程与长期可靠性验证实验室里读数漂亮只是第一步温度采集方案真正的考验在现场HVAC 项目里传感器可能分布在屋顶、风管和机房工业项目里还要面对电机启停、电磁干扰和温差环境。这一章专门讲现场遇到的问题和针对性处理。5.1 HVAC 场景长线传输和响应速度的取舍HVAC 里最常见的是把温度传感器放在几十米外的风管或机房而 ADC 和主控在控制柜里这就是典型的微弱模拟信号长线传输。长线的主要问题是引入共模噪声和线阻。共模噪声靠差分输入和屏蔽双绞线压住线阻的问题需要分传感器类型处理NTC 用三线或四线接法能把线阻影响降到最低但成本高工程上很多项目用二线 NTC这种情况下线阻就直接折算进测量结果只能靠软件里预留的线路补偿电阻参数去校准。HVAC 的另一个指标是响应速度。风管温度变化本来就慢但电动阀动作之后的温度回升需要尽快反映出来所以不能把 ADC 数据率压到太低。我的折中方案是数据率用 50SPS软件里再做一阶移动平均平均窗口 5 到 10 个点。这样既滤掉了工频干扰又能在一两秒内反映温度变化比单纯降低采样率的效果好得多。5.2 工业场景隔离、浪涌和电机启停工业用户那边的问题更硬核主控板旁边就是接触器和变频器测温板离动力线只有几十厘米电机一启动所有模拟通道的读数都跳。这种环境下光靠 PCB 布局已经救不回来必须做隔离。好在 ADS122U04 的 4 线 UART 接口做隔离很方便数字隔离器把四根线全部隔离掉测温板用独立的隔离电源供电ADC 端电源和控制板电源之间没有任何形式的共地这样电机启动造成的共模干扰再大也进不了模拟链路。隔离之后还有一个问题是浪涌。工业现场如果传感器线从室外进来冬天静电或者感应雷都可能把 ADC 输入端打坏。我在模拟输入前面加了瞬态抑制二极管和小阻值串阻压敏电阻放在传感器端子入口。保护器件的结电容会影响信号精度所以要选低电容型号并且用差分对称的方式布置否则差分信号里会混入共模转差模的误差。5.3 长期稳定性焊点、老化与定期校验最后聊一下长期可靠性。24 位 ADC 本身的长期漂移其实不是主要矛盾基准源和外围精密电阻的温漂、焊点应力、连接器氧化才是大头。ADS122U04 配合外部低漂移基准在没有校准的情况下年漂移能做到大约 ±0.1℃ 到 ±0.2℃但对于需要长期保证 ±0.5℃ 的系统两年内必须有铅点校准安排。PCB 板级设计上也有一招普遍的工程做法把基准电阻的焊盘设计成四线开尔文连接这样校准时可以直接用探针接触量到的电阻值不受焊盘接触电阻影响。另外量产的板子在出厂前一定要做老化筛选至少通电老化 4 小时再标定标定出来的数据稳定率明显比上电就标的高。具体标定流程在我这套方案里是这样的先给温控箱稳定到 0℃等测温和控温都进入稳态后记录原始码作为零点基准再设置到 100℃ 或现场实际工作温度上限附近的点记录第二点两点之间做线性增益修正对 NTC 还可以加第三点做二次曲线拟合。整个过程写成一个半自动脚本PC 通过主控串口直接读取 ADC 码自动生成每块板的校准系数并写入 Flash。这套方案的测量链路我已经完整跑过一轮从信号的接入到主控里的最终温度值每种传感器都经过至少一周的连续运行验证。最后想分享两条实际经验。第一ADS122U04 这种带 UART 接口的 ADC 在驱动上一定不要照搬 SPI 的思维方式它需要你把 SCLK、CS、DOUT/DRDY 这几根线的时序关系当成一个整体来理解调试的时候用逻辑分析仪同时抓四根线比对着代码猜要快得多。第二不论芯片手册把内部基准吹得多好只要产品精度指标高于 ±0.5℃外部基准、LDO 噪声、PCB 布局这三块的预算就不能省很多读数跳的问题到最后都不是芯片的问题而是你喂给它的电源和参考本身就不干净。 SEO 优化官网定制响应式建站教育培训建站