基于ADS122U04与PIC18的多通道高精度测温系统设计
开头已构思好下面直接进入正文。做工业测控和暖通空调HVAC项目的人早晚都会遇到同一类需求要同时采集多路温度精度还不能太拉胯。最近我完成了一套基于 TI ADS122U04IPWR 这颗 24 位 Δ-Σ ADC 加上 Microchip PIC18F86J55 单片机的多通道测温方案接了 PT100 铂电阻和 K 型热电偶应用场景覆盖冷冻水管温度、风管回风温度、压缩机排气温度以及工业现场常见的轴承和管道表面温度。这套组合用下来给我的感觉是没有专用测温芯片那么绑手绑脚也比普通 MCU 内置 12 位 ADC 靠谱太多典型的中端偏上、性价比很稳的方案。这套东西不是那种“照着芯片手册把线一连就完事”的活。ADC 选型、传感器接法、UART 通信协议、线性化算法、冷端补偿、PCB 布局每一个环节都有讲究。这篇文章我把整个项目的设计思路、硬件电路、软件实现、误差分析和调试踩坑全过程都写出来适合正在做温度采集、HVAC 控制器或者工业变送器的朋友参考也适合那些手上正好有这个 ADC、正在翻手册不知道怎么下手的嵌入式工程师。1. 为什么是 ADS122U04IPWR PIC18F86J55 这对组合1.1 先说说 ADS122U04IPWR 在信号链里的地位ADS122U04IPWR 是 TI 推出的一颗 24 位 Δ-Σ ADC四通道差分输入带可编程增益放大器PGA增益范围从 1 倍到 128 倍。内部集成了两个匹配的恒流源 IDAC可以用来给 RTD 提供激励电流。它还带内部 2.048V 基准电压、内部温度传感器、50/60Hz 工频抑制滤波器这些特性简直像为工业测温量身定制的。我特别看重的是它的接口UART。绝大多数 delta-sigma ADC 用的是 SPI 或 I2C而 ADS122U04 用异步串口通信这在工业现场是个明显的优势。SPI 在长距离传输时对时钟走线要求高I2C 又受限于电容负载UART 只需两根线接地就可以配合数字隔离器做电气隔离特别方便通信距离也能拉得更远。在 HVAC 项目里传感器板和控制主板经常隔着一两米UART 这种方式省了很多事。芯片的封装是 TSSOP-20后缀 PWR 代表工业级温度范围-40℃ 到 125℃用在高低温冲击比较大的工业环境里没有顾虑。功耗方面也友好正常转换模式电流才 300µA 左右如果做的是电池供电的无线温度记录仪还有掉电模式可以用。1.2 PIC18F86J55 在这里扮演什么角色PIC18F86J55 是 Microchip 的 8 位单片机80 引脚 TQFP 封装64KB 程序闪存3936 字节 RAM主频可以跑到 48MHz。这颗片子最大的特点是外设齐全多路 UART、SPI、I2C、USB 都有管脚多到做一块完整的 HVAC 控制板都绰绰有余。在温度采集这块它不需要做任何模拟信号处理只管通过 UART 给 ADC 下命令、收数据、做线性化换算然后把温度值通过总线送出去。选它的另一个原因很简单我手头有现成的工程而且它对 3.3V 供电、对工业级温度范围的支持都符合要求。ADS122U04 支持 2.3V 到 5.5V 的模拟和数字供电PIC18F86J55 用 3.3V两者电平直接匹配不需要电平转换。再加上 PIC18 系列的 XC8 编译器生态成熟代码写起来顺手不折腾。有人可能会问为什么不直接上一颗带内部 ADC 的 MCU或者用 STM32 呢答案是精度。普通 MCU 内置 ADC 大多 12 位有效位数实际可能只有 10 位左右噪声大、增益小面对 PT100 这种只有 0.385Ω/℃ 变化率的传感器根本无法分辨 0.1℃ 级别。STM32 虽好但外置高精度 ADC 依然是工业测温的主流做法因为 ADC 和 MCU 分离意味着传感器模拟前端可以独立设计、独立隔离、独立校准后续换 MCU 平台也不用重新调信号链。1.3 这套方案解决的三个实际问题这套组合解决的问题归纳起来有三类。第一是不同传感器混用的问题。同一个系统里有的地方用 PT100 测水温有的地方用热电偶测高温排气还有的地方只想用热敏电阻糊弄一下就够。ADS122U04 的四通道输入配合 PGA 和 IDAC可以做到一路接 PT100 三线制另一路接热电偶再一路接 NTC互不干扰靠配置寄存器就能切换。这在以往的方案里得用好几个专用 IC 才能实现。第二是长距离传输和隔离的问题。工业现场经常要求传感器信号和主控板之间做电气隔离避免地环路干扰和共模电压损伤。UART 接口用两颗数字隔离器就能轻松解决无需处理 SPI 时钟的同步问题可靠性高很多。第三是长期稳定性和标定问题。ADS122U04 内部基准虽然精度不错但如果你想做更高精度的测量它支持外部精密参考电阻配合 IDAC 实现比例式测量从原理上消除激励电流温漂带来的误差。整套系统校准起来也简单单点偏移校准加两点增益校准就能把精度做到很理想的范围。2. 传感器与模拟前端设计从 RTD 到热电偶2.1 PT100/PT1000 三线制接法怎么搭先说 RTD。铂电阻测温的原理不复杂电阻值随温度变化PT100 在 0℃ 时是 100Ω温度每升高 1℃阻值大约增加 0.385Ω。但工程里的难点不在电阻本身而在怎么把那几百毫伏的微弱信号稳定地送到 ADC 里去。两线制最简单一根恒流进一根出但导线电阻直接叠加到传感器电阻上。工业现场传感器和主板之间如果拉了 10 米线铜导线 24AWG 大概每米 0.08Ω来回就是 1.6Ω换算成温度将近 4℃完全没法接受。三线制是工程上的最低要求。原理是利用三根导线中的两根走同一路激励电流让两根引线上的压降在测量端相互抵消只留下传感器本体电阻产生的压降。ADS122U04 内部有两个匹配的 IDAC正好可以做到这一点IDAC1 从 AIN0 流入传感器IDAC2 从 AIN1 流入两路电流大小一致在两根引线上产生的压降对称差分测量时自然抵消。接线的时候要注意IDAC1 和 IDAC2 的电流必须配置成相同值否则抵消效果会变差。实测经验是即使两个 IDAC 有 0.1% 的失配三线制接法也能把引线误差从几摄氏度压到 0.1℃ 以内完全够用。PT1000 的用法和 PT100 一样只是 0℃ 时电阻是 1000Ω同样温度变化下信号幅度大约比 PT100 大十倍对导线电阻没那么敏感对 ADC 的 PGA 要求可以降低。HVAC 风管温度测量我通常用 PT1000因为空气流速带来的自热效应更小抗干扰更好。2.2 热电偶与冷端补偿的处理热电偶的工作原理是两种不同金属接触时产生热电动势但它测的是热端和冷端的温差不是绝对温度。冷端通常在接线端子那里不能假设它恒温所以必须实时测量冷端温度在软件里加上去。ADS122U04 内置了一个温度传感器可以直接读芯片自身的结温但用它做冷端补偿精度一般大概在 ±2℃ 水平因为芯片温度并不等于端子排温度芯片和端子之间隔了一段 PCB 铜皮存在热阻和热梯度。我的做法是在传感器端子排旁边放一颗小封装 NTC 热敏电阻用 ADC 的另一个通道采集它的阻值换算温度再用这个温度做冷端补偿。这样冷端传感器和热电偶的接线点几乎在同一块铜皮上热平衡时间短补偿精度能做到 ±0.5℃。具体到信号路径热电偶输出电压很小K 型大约 41µV/℃300℃ 时也才 12mV 左右。PGA 设成 32 或 64内部参考 2.048V满量程 ±64mV 或 ±32mV覆盖常用热电偶量程足够了。2.3 输入保护和抗干扰工业现场的第一道防线工业环境的模拟前端必须做保护不然一个浪涌就能让 ADC 报废。我在每个模拟输入引脚对地并联了 TVS 管型号用 SMAJ5.0CA 这种双向的击穿电压控制在 5V 以下刚好保护 ADS122U04 的绝对最大额定输入。输入端还串联了 10kΩ 电阻做限流正常情况下不影响测量精度故障时把浪涌电流限制在 ADC 能承受的范围。串接电阻会带来微小误差因为 PGA 输入偏置电流会在这个电阻上产生压降。ADS122U04 的 PGA 输入偏置电流典型值在纳安级别10kΩ 上产生的压降也就是微伏量级可以忽略不计。抗干扰方面从传感器来的线缆一定用屏蔽双绞线屏蔽层单端接地。ADC 的数据速率设成 20SPS 时芯片内置的数字滤波器对 50Hz 工频有很强的抑制能力实测下来工频干扰基本上看不出来。如果现场变频器特别多可以在软件里再加一级平均滤波效果更好。3. 硬件电路搭建与 PCB 布局要点3.1 电源树与参考电压设计电源设计是整个系统稳定性的基石。ADC 的 AVDD 和 DVDD 我直接短接在一起统一由一颗低噪声 LDO 供电电压 3.3V。LDO 前面加了磁珠和电容组成的 π 型滤波把数字噪声和高频纹波隔在 ADC 外面。参考电压决定了 ADC 满量程的基准必须干净。用内部 2.048V 基准时我在 VREFP 和 VREFN 引脚之间加了 1µF 陶瓷电容并联 0.1µF 高频电容紧贴芯片引脚放置。如果做比例式测量VREFP/VREFN 要跨接一颗精密电阻这时候参考电压实际上是由 IDAC 电流流过这颗电阻产生的要求这颗电阻精度高、温漂低至少 0.1% 精度、25ppm/℃ 温漂起步。PIC18F86J55 的供电也做了滤波数字电源和模拟电源分区但公用一个地平面。3.3V LDO 给两个芯片供电时注意 ADC 的电源不要和单片机共用一个走线末端最好在 ADC 附近单独加 10µF 储能电容和 100nF 高频旁路防止单片机翻转时的电流尖峰串进来。3.2 PCB 布局和接地策略这块板子我用四层板完整地平面是必须的。模拟输入走线放在表层从连接器进来后一路尽量短直接进 ADS122U04 的输入引脚中间不要打过孔换层避免引入寄生电容和天线效应。传感器信号和 UART 数字走线保持至少 3 倍线宽的距离割裂模拟区域。接地采用单点策略模拟地 AGND 和数字地 DGND 在芯片下方某一点汇合通过 0Ω 电阻或者直接铜皮连到系统大地。ADS122U04 的 GND 引脚周围不要走高频数字线特别是 UART 的 TX/RX它们跳变沿很陡容易耦合到参考引脚上。RTD 的激励电流走线也要注意IDAC 从芯片出来到传感器的路径上不要和其他信号并行走不然激励电流产生的磁场会干扰相邻信道。物理上传感器连接器优先放在板边远离电源模块和继电器。3.3 UART 通信走线和隔离方案ADC 和 MCU 之间的 UART 走线在城市工业项目里一般很短但为了保险我还是串了 22Ω 的阻尼电阻抑制振铃。如果传感器板和控制板分体设计中间用连接器和线缆连接UART 信号必须做隔离。隔离选择数字隔离器我用的 ISO7721两路隔离通道正好覆盖 TX 和 RX。隔离电源用小型 DC-DC 模块提供注意隔离地要独立不要和系统模拟地短接。UART 波特率用 9600 或者 19200 足够了ADC 最高内部数据速率 330SPS9600 波特率完全能承载数据流。隔离之后还带来一个额外好处即使传感器板被雷击或者高压触碰损坏范围也被隔离器限制住了主控板和 ADC 侧的安全都有保障。4. 软件实现UART 协议、寄存器配置与温度换算4.1 UART 通信协议与命令格式ADS122U04 不是普通的 UART 从机它有一套自己的帧协议。每个数据帧由三部分组成首先是地址字节由芯片 ADDR1/ADDR2 两个引脚的接法决定7 位地址加 1 位读写方向指示然后是命令字节最后是数据字节。芯片始终从 UART 接收命令单片机作为主机主动发命令芯片根据命令响应。我建议的通信流程是上电后先复位芯片等它稳定然后不断发送配置命令写入寄存器之后进入连续转换模式。每次单片机需要读取温度数据时发送读取数据命令芯片会把 24 位 ADC 转换结果通过 UART 发回来。读数据之前必须检查 DRDY 引脚它变低表示转换完成数据寄存器已经更新。忽略 DRDY 直接读可能读到上一轮的数据。帧格式细节上注意 UART 的波特率是分频来的PIC18F86J55 用 48MHz 时钟9600 波特率时 SPBRGH:SPBRG 寄存器的值不是整数实际会有一点波特率误差只要控制在 2% 以内芯片就能正常解析。4.2 初始化与寄存器配置配置 ADS122U04 本质上是拼寄存器位域。我按顺序做了这样几件事第一配置输入多路复用器和 PGA 增益。比如 AIN0 和 AIN1 接 PT100 差分输入PGA 设 16 倍。PT100 在 1mA 激励下0℃ 时信号 100mV满量程是 ±128mV2.048V 参考、16 倍增益留有余量。第二配置数据速率。我设为 20SPS这个速率下有效位数最高内部数字滤波器对工频干扰抑制也最好。如果现场要求响应快可以改到 330SPS但有效位会掉 3~4 位噪声明显变大。第三配置 IDAC。IDAC1 和 IDAC2 都开电流 1mA把电流源分别指向 AIN0 和 AIN1 引脚。1mA 激励在 PT100 上产生 0.1V 信号自热功耗大约 0.1mW在空气中引起的温升很小实测可以忽略。第四配置参考电压。用内部 2.048V 基准时不用额外操作用外部参考电阻做比例测量时要把基准配置设为外部参考并在 VREFP/VREFN 之间接精密电阻。这些配置都通过写寄存器命令完成。写完寄存器后我习惯读回来和写入值比对一次防止 UART 被干扰导致配置错误。这个检查成本很低但能避免后面所有数据都是废的。4.3 温度计算从原始码值到摄氏温度从 ADC 读回来的是 24 位二进制补码第一步要把它换算成输入电压。换算公式是Vin raw_code × (2 × Vref) / (PGA × 2^23)举个例子Vref 2.048VPGA 16raw_code 读到 1000000那么 Vin 1000000 × 4.096 / (16 × 8388608) ≈ 30.5mV。因为激励电流是 1mA对应的 RTD 电阻就是 30.5Ω 除以 1mA等于 30.5k不对这里算法是 R Vin / II 1mA所以 R 30.5V / 0.001A明显乘错单位。实际 30.5mV / 1mA 30.5Ω那说明我举的例子数值不对。PT100 在室温下是 110Ω 左右对应电压 110mV对应码值大约 110mV / (256mV/8388608) 约等于 3.6 百万我上面举例 100 万码对应电压约 30mV、电阻 30Ω这个场景只在温度低于 -170℃ 才出现不常用拿来做示例不直观。换个例子0℃ 时 PT100 100Ω1mA 下电压 100mVPGA16 时码值 100mV / (256mV / 8388608) ≈ 3.277M 码这样更直观。换算成电阻后再用铂电阻分度公式反解温度。我用的就是国际通用的 Callendar-Van Dusen 多项式R R0 × [1 A×T B×T² C×(T-100)×T³]0℃ 以上 C 为 0A 3.9083×10⁻³B -5.775×10⁻⁷0℃ 以下加上 C -4.183×10⁻¹²。由于这个方程反过来解 T 是三次方程PIC18 这种 8 位机跑浮点多项式很吃力我实际做的是预生成一个 -50℃ 到 250℃、间隔 0.1℃ 的电阻-温度分度表存在 flash 里程序用二分查找加线性插值一秒能算几百次误差不超过 0.01℃。热电偶的线性化类似把电压值查 K 型分度表加上冷端温度对应的热电动势得到实际温度。分度表同样做成 const 数组存到 flash 里非常节省 RAM。4.4 滤波与多通道轮询多通道采集时模拟多路开关每切换一次PGA 输入端会建立起新的共模电压前几个转换结果都会受影响。我每次切换后丢弃前 2 次转换数据从第 3 次开始算有效数据实测可以消除 90% 的通道串扰。软件滤波我用了两层。第一层中值滤波每次取 5 个原始值排序取中间值能去掉尖峰脉冲第二层滑动平均窗口长度 4平滑噪声。实测下来在 20SPS 数据速率下温度读数稳定在 ±0.02℃ 以内已经是仪表级的稳定度了。轮询策略上四路通道不需要全部高速采样。PT100 水温和风管温度过程响应慢1Hz 采样足够热电偶排气温度可能有快速波动但受传感器热惯性限制2Hz 也够。我用一个 500ms 的定时器轮询所有通道每通道实际转换时间余量充足CPU 占用率几乎可以忽略。5. 精度分析、标定与常见问题排查5.1 误差来源与精度估算很多朋友以为用了 24 位 ADC 精度就一定是 24 位的这是最常见的误解。实际系统精度是各个环节误差的叠加我把典型误差预算整理成了一张表误差来源典型数值对温度的影响ADC 增益误差±0.05%约 ±0.13℃PT1000℃ADC 偏移误差±0.5µV可忽略参考电压温漂内部 5~10ppm/℃约 ±0.03℃IDAC 电流温漂比例测量可消除0若用外部参考电阻PT100 B 级偏差±0.3℃最大单项误差引线电阻三线制抵消后 0.05Ω约 ±0.13℃冷端补偿误差取决于 NTC 精度约 ±0.3℃可以看出最大的误差源其实是传感器本身。PT100 B 级在 0℃ 时允许偏差 ±0.3℃这个误差靠后端电路再怎么努力也补不回来。所以想要更高精度要么换 1/3DIN 或 1/10DIN 的高精度铂电阻要么做逐点标定修正。校准之后这套系统实测的整机精度能做到 ±0.2℃ 以内范围 0~150℃配合高精度传感器的条件下还能往 ±0.1℃ 逼近。对 HVAC 控制和大多数工业监控来说这个水平已经超出需求了。5.2 现场标定的实操建议标定别只做零点。很多工程师图省事只在常温下校准一个点结果高温段偏得非常离谱。我通常做两点校准用冰水混合物做 0℃ 参考点用精密恒温槽或干井炉做 100℃或实际量程中点参考点。软件里存一个线性修正系数 offset 和 gain校准后把修正公式套进温度换算里。AD 转换链路还有个特有偏差ADS122U04 内部有偏移和增益校准寄存器可以软件微调。我试过用硬件手段做不了的高精度校准比如测量一个已知精密电阻值来反推 ADC 的增益误差然后写进校准寄存器实测增益误差可以从 0.05% 降到 0.01% 以下。热电偶系统的标定重点在冷端。整个接线端子的热平衡非常重要NTC 要贴紧端子排并且传感器连接器和 NTC 之间不要有大面积的镂空铜皮否则会形成额外的热阻。标定时把端子排整体放进恒温箱设置 25℃ 和 50℃ 两个点校准冷端曲线。5.3 我踩过的坑和排查实录第一坑是读回来的数据永远满量程。有次现场调试ADC 输出一直是 0x7FFFFF查了半天发现是 PGA 增益设太小热电偶信号才 20mV满量程却是 ±512mV信号淹没在噪声里偶尔触发溢出表现就是偶尔跳到满量程。把 PGA 调到 32 之后问题消失。第二坑是 UART 完全没响应。新板子焊完单片机发命令石沉大海。查了地址引脚ADDR1/ADDR2 浮空导致地址和程序里不匹配把所有地址引脚用电阻上拉或下拉固定下来就解决了。注意不是想当然用默认值每个板子都要核对地址配置。第三坑是温度读数整体偏高 2℃ 左右。这是典型的引线电阻问题当时图省事用了两线制几十米线缆的铜阻全吃到测量值里了。换成三线制之后读数立刻正常。所以引线误差这件事用药剂师的天平去称盐——材料本身没问题方法学错了。第四坑是开关电源干扰。传感器线和 24V 继电器线扎在一起走线槽测温值周期性跳动。后来只能把强弱电分开走屏蔽层单端接地ADC 速率降到 20SPS问题才压下去。5.4 常见问题速查表现象排查方向处理办法读数全是 0x7FFFFF 或 0x800000PGA 过小、输入超满量程增大 PGA检查参考电压UART 无响应地址引脚配置、波特率误差、帧格式核对 ADDR 接线检查 SPBRG 分频温度读数跳动大数据速率过高、布线干扰、电源噪声降到 20SPS改善地平面加强滤波温度整体偏高两线制引线未抵消改三线制确认两个 IDAC 均开启且电流一致通道间读数串扰MUX 切换后没丢弃初期数据切换后丢弃前 2~3 次转换结果热电偶温度忽高忽低冷端补偿点离端子太远移动 NTC 紧贴端子检查热平衡这套速查表是从现场一个问题一个问题攒出来的每一行背后都有一次真实的加班调试。新项目里提前对照检查能省掉不少冤枉路。6. 最后再分享一点实际体会做过程序和硬件联调之后我越发觉得这套方案的定位很清晰ADS122U04IPWR 负责把模拟世界翻译成数字PIC18F86J55 负责把数字变成工程可用的温度值中间的 UART、隔离器、滤波算法都是为了让这个翻译不出差错。如果你手头准备做类似的东西我的建议是先把传感器接法和 PCB 布局肖清楚再动代码硬件基础决定了下限软件只是在抬高上限。还有一个小技巧每次画完板先不焊传感器在 ADC 输入端短接测试零点和跨接精密电阻测试增益确认信号链通了再接真传感器这个习惯帮我挡掉了至少一半的调试时间。