工业测温实战:ADS122U04与PIC18F85J50的多路温度采集方案

发布时间:2026/11/5 7:38:04
工业测温实战:ADS122U04与PIC18F85J50的多路温度采集方案

做工业现场测温的项目,最先卡住你的往往不是算法、更不是仿真,而是模拟信号到数字量这一小段路。去年给一套HVAC系统做多路温度采集节点,要求同时覆盖回风、送风、冷媒管表面和环境补偿四点温度,传感器既有PT1000又有NTC,精度指标是全程±0.5℃以内。当时我放弃了一直以来的SPI接口ADC习惯,最终选用了TI的ADS122U04IPWR搭配Microchip的PIC18F85J50,整套系统跑了半年多,表现稳定。这篇文章就把当时的选型逻辑、硬件搭建、固件设计和调试中踩过的坑完整复盘一下,给同样在工业测温、HVAC控制领域折腾的人一个参考。

1. 为什么是ADS122U04IPWR加PIC18F85J50:这个组合的定位

1.1 先看ADS122U04IPWR解决了什么痛点

很多做单片机出身的人习惯用ADS1115、ADS1220这类SPI或I2C接口的ADC,但在工业HVAC控制柜里,SPI总线有几个让我很难接受的问题。

第一是距离。SPI在板级通信没问题,可一旦ADC板要通过排线或连接器放在靠近传感器的地方,时钟和数据线在超过半米的排线上就开始出现振铃和误码。第二是引脚占用。SPI至少四根线,加上片选、数据就绪信号,一个ADC就要占掉MCU五六个IO,对PIC18F85J50这种IO资源并不算宽裕的8位机来说不划算。第三是隔离和线缆成本。工业现场经常要把模拟前端单独做一块小板,挂在传感器端子旁边,SPI做隔离和长线驱动既麻烦又增加BOM。

ADS122U04IPWR的定位恰好切在这些痛点上:它把24位ADC的控制和结果输出全部收敛到一条UART串口上。24位分辨率,4通道模拟多路开关,集成可编程增益放大器(PGA,增益1到128倍),两个可编程电流源IDAC,内部温度传感器和2.048V基准,几乎把一条RTD、热电偶、热敏电阻测量链路上需要的模拟功能都做进了芯片里,MCU只负责发命令、收结果。实际接线只要三根:电源、地、一根UART数据线。如果只开连续输出模式,理论上一根发送线就够用。在DIN导轨安装的HVAC控制柜里,这个优势非常明显。

1.2 为什么绕开PIC集成的ADC

有人可能会问,PIC18F85J50不是自带ADC模块吗,为什么还要外挂一颗?这个问题的答案,恰恰是这个项目最核心的取舍逻辑。

PIC18F85J50内置的ADC分辨率有限,而且没有可编程增益放大器和恒流源。如果要直接测量PT1000或NTC,外部得加精密电阻分压、仪表放大器或运算放大电路。更关键的是,HVAC现场存在变频器、压缩机启停这类强干扰源,片内ADC的基准源和采样电容都很小,抗工频干扰能力远不及一颗完整的24位Δ-Σ型ADC。把模拟精度的活单独交给ADS122U04IPWR,本质上是把“模拟难题”从MCU里剥离出来,MCU只做数字活,系统的可维护性和精度边界都清晰得多。

1.3 PIC18F85J50在这个项目中的准确角色

PIC18F85J50是Microchip的8位MCU,64KB Flash加约4KB RAM,放在今天的温度采集任务里性能绰绰有余。它在这里做的事情其实不多:初始化UART,向ADS122U04下发配置命令,定时读取转换结果,做软件滤波和温度换算,最后通过Modbus协议上报给上一级PLC或控制器。

选它的理由也很实际。3.3V供电与ADS122U04的模拟电源范围匹配,整个板子单电源、单电压域,不用做电平转换。8位机在这个任务里完全够用,代码逻辑简单,出问题好查。而且PIC18系列供货周期长、工具链成熟,工业产品最怕选个最新旗舰然后几年后就停产,硬件工程师都懂这个代价。

提示:工业产品选MCU,稳定供货、工具链熟悉度和长期可维护性,往往比“跑分”更重要。PIC18F85J50的优势不在性能,而在生态。

2. 硬件搭建:从传感器端子到MCU引脚的信号链路

2.1 传感器类型与接法怎么定

HVAC系统里,我把整个项目的测温点分成了三类,分别对应不同的传感器方案。

送风和回风温度,装在风管里,环境范围大概-10到70℃,用的是PT1000铂电阻。选PT1000而不是PT100,是因为HVAC现场风管传感器的引线通常有几米长,PT1000的自阻大,导线电阻引入的误差比例更小,工程上省事。

冷媒管表面温度,用10kΩ NTC热敏电阻,B值3435或者3950都行。冷媒管路在制冷工况下温度较低,贴片传感器必须带绝缘护套,不能直接用裸电阻。这类位置还有压缩机带来的机械振动,传感器封装要能扛住。

环境补偿和柜内温度,也用NTC,成本低,精度要求没那么高。

ADS122U04IPWR有四个模拟输入通道,AIN0到AIN3,搭配两个IDAC电流源,通道分配如下:

  • AIN0/AIN1:PT1000风管温度,差分接法,IDAC1提供1mA激励电流。
  • AIN2/AIN3:NTC冷媒管温度,差分接法,IDAC2提供0.15mA恒流。
  • 内部温度传感器:保留,用于将来热电偶冷端补偿或芯片温度监测。

关于RTD接法,两线制最简单,但导线电阻会直接算进测量结果。PT1000配1mA激励,1米导线若按0.1Ω计算,折算到温度方向大约0.025℃的误差,通常能接受。如果走线超过3米,强烈建议用三线制或四线制。我这个项目里PT1000探头都在机柜附近,两线制够用,但PCB上预留了三线制的直插焊盘,以防后期更换远距离探头。

2.2 激励电流、基准电阻和PGA的配合逻辑

RTD测量我用了比例法,这是ADS122U04这类带IDAC的ADC最经典的用法。简单说:让IDAC电流同时流过精密基准电阻和RTD,基准电阻上的压降当作ADC的参考电压,RTD上的压降就是测量信号。因为电流源的不稳定度会同时出现在参考电压和信号电压里,比例运算时正好消掉,电流源的绝对误差和温漂对最终结果的影响可以降到极低。

具体参数我这样定的:IDAC1输出1mA,基准电阻选2kΩ 0.1%精度、25ppm温漂的金属膜电阻,参考电压就是2V。PT1000在0℃大约是1000Ω,100℃时约1385Ω,信号电压从1.0V到1.385V。PGA增益选2,满量程范围内留出充足裕量,24位分辨率实际能响应的温度分辨率轻松达到0.01℃量级,足够HVAC正常的控制需求了。

NTC那边没有用比例法,因为NTC本身阻值随温度变化大,用恒流加差分采样更直接。IDAC2输出0.15mA,流过NTC后电压在-10℃约为1.5V,在70℃约为0.3V,配合PGA增益4倍,动态范围覆盖得很好。要注意的是NTC激励功率不能太大,0.15mA在10kΩ电阻上功耗约0.3mW,自热影响已经很小,再往上就要担心误差了。

2.3 输入滤波、保护和电源设计

每个模拟输入引脚上,我串了100Ω电阻,再接0.1μF电容到地,组成一阶低通,截止频率约16kHz。这组RC的价值在干扰大的现场才能体现:变频器输出侧的高频噪声、压缩机电磁阀动作的尖峰,都会被滤掉一大部分。如果省掉这几个小元件,后期排查数据跳变会非常痛苦。

电源方面,ADS122U04IPWR的AVDD和DVDD都用3.3V,整个板子由一颗LDO供电。AVDD引脚旁边放10μF钽电容加0.1μF陶瓷电容,组成低阻抗电源网络。PIC18F85J50和ADC共用同一颗LDO,但MCU的IO翻转噪声可能耦合进模拟电源,所以ADC的AVDD走线从LDO输出单独拉出来,不要经过MCU区域。

PCB布局上有一条教训值得说:ADC芯片要尽量靠近传感器接线端子,让模拟信号线走短直线,让长线走数字UART。我第一次布板图方便,把ADC放到MCU旁边,结果模拟输入走线绕了大半个板子才到端子,调试时花了好几天排查干扰问题,最后重新走线才解决。模拟信号线短、数字线长,这个原则在混合信号板上永远优先。

3. 配置ADS122U04IPWR与实现UART协议

3.1 寄存器配置思路

ADS122U04的配置寄存器按功能分组,主要涉及输入多路开关选择、PGA增益、转换模式、数据速率、IDAC电流大小与输出源、基准电压源选择、内部温度传感器开关这几类。

我的配置流程分三步走。上电后先发复位命令,等待芯片完成内部初始化。然后写配置寄存器,把PGA设成2倍、数据速率设为20 SPS、选择连续转换模式、使能IDAC1输出1mA到RTD通道、使能IDAC2输出0.15mA到NTC通道、基准电压选择内部2.048V并配合外部基准电阻。最后进入工作状态,主循环周期读取转换结果。

这里想专门说下为什么选20 SPS。很多人看到这个速率会觉得慢,但Δ-Σ型ADC的数字滤波器对50Hz工频干扰有天然衰减,20 SPS档位下,50Hz及其谐波正好落入滤波器凹陷点,抑制效果非常理想。HVAC现场所有设备都跑在50Hz电网下,用20 SPS等于白送一套强大的工频滤波。如果以后要响应制冷系统快速动态过程,再考虑提高数据速率,但要接受噪声相应增大的代价。

3.2 通信帧结构与可靠性设计

ADS122U04走的是UART,我这边协议设计得很保守,毕竟工业通信最怕的就是状态跑飞。

波特率用了19200,HVAC柜内走线距离短,这个速率兼顾速度和抗干扰,再往上必要性不大。帧结构很简单:命令字节加可选参数字节加校验字节,返回数据是24位转换结果三字节加一个状态字节。

MCU侧的接收全部走中断,环形缓冲区暂存,主循环里用状态机解析,避免串口处理阻塞主流程。每收到一帧完整数据就置个标志位,主循环在合适的时机处理。这样即使ADC偶尔吐出一帧异常数据,MCU也不会因此卡死。

注意:UART和ADS122U04的通信必须保证上电顺序,先让ADS122U04完成上电初始化,MCU再发第一条命令。我最初把MCU初始化放在前面,结果第一帧命令经常丢失,后来加50ms延时再发第一条命令,问题消失。

3.3 PIC18F85J50侧的初始化代码

用XC8编译器写PIC18侧的串口初始化,核心代码如下:

// 假设使用16MHz外部晶振 #define _XTAL_FREQ 16000000UL void UART_Init(void) { TRISCbits.TRISC6 = 0; // TX引脚设为输出 TRISCbits.TRISC7 = 1; // RX引脚设为输入 TXSTA1 = 0x24; // 使能发送,8位数据,异步模式 RCSTA1 = 0x90; // 使能串口,使能接收 BAUDCON1bits.BRG16 = 1; // 16位波特率发生器 // 19200bps 波特率设置 SPBRG1 = (unsigned char)((_XTAL_FREQ / (16UL * 19200UL)) - 1); }

ADC数据读取的主流程大概是:先发一条读命令,然后从环形缓冲区里取24位数据,组合成32位变量,再交给温度换算模块处理。注意字节序,ADS122U04返回的数据是三字节,高位在前还是低位在前必须按数据手册确认,我第一次就弄反了,整整半天查出来是字节序问题,明明协议文档里写得清清楚楚。

软滤波我用了“中值加均值”的组合:连续采16次,先去掉最大值和最小值,再把剩下14个做算术平均。20 SPS下这个滤波延时只有0.8秒,既保住了响应速度,又把偶发尖峰彻底压掉了。这个技巧在工业采集里非常实用,比单纯滑动平均抗干扰能力强很多。

4. 从ADC原始值到物理温度:算法与校准细节

4.1 RTD的比例法换算

RTD的比例法换算公式非常简单,但工程实现里有细节。核心关系是:

R_rtd = (采样码值 / 满量程码值) × R_ref

实际代码里,我直接用24位码值和满量程码值相除,再乘以R_ref的标定值,得到RTD当前电阻。然后用查表加线性插值的方式把电阻换成温度。查表用的RTD分度表覆盖-50到250℃,每1℃存一个电阻值,线性插值在1℃间隔下的误差小于0.05℃,完全够用。

如果追求更高精度,可以使用Callendar-Van Dusen方程。但8位机上跑浮点运算效率不高,我的建议是离线算好分度表,在线只做整数查表和线性插值,又快又稳。这个方案在HVAC和普通工业场合下精度足够,还省MCU资源。

4.2 NTC与Steinhart-Hart方程

NTC这边,恒流激励下的原始码先换算成NTC电阻值,再套Steinhart-Hart方程转换成温度:

1/T = A + B·ln(R) + C·(ln(R))³

三个系数A、B、C可以根据NTC厂家给的B值和标称阻值算出初值,再用实测点校准。我没有直接用厂家默认系数,而是在10℃、25℃、60℃三个点实测后反算系数,这样全温区误差更均衡。

4.3 冷端补偿储备

这个项目没启用热电偶,但ADS122U04内置温度传感器这个功能我保留着。如果以后要接K型热电偶,冷端温度可以直接从内部温度传感器读出,省掉一颗独立的冷端补偿芯片。这里还有一个PCB层面的知识点:冷端温度要尽量让热电偶连接端子和芯片处于同一块覆铜区域,减小两者之间的温差。内部传感器测的是芯片结温,如果接线端子离芯片太远,结温和端子温度不一致,补偿精度就废了。

4.4 校准流程与验证结果

温度测量精度一半靠算法,一半靠校准。我的校准流程分三步。

第一步,冰点槽校准。把PT1000探头和0.01℃精度的参考温度计放进冰点槽,记录ADC原始码,得到零点偏移。第二步,干井炉或沸点校准。100℃附近取第二个点,修正增益误差。第三步,温箱验证。从-10到80℃每10℃取一个点,和参考温度计对比,画出误差曲线。

实测下来的数据是:系统在-10到80℃区间最大偏差约±0.2℃,计量器具比对合格,满足HVAC领域±0.5℃的要求。这个结果在工业现场已经算相当扎实,毕竟实际工况里的误差来源比实验室里多得多。

5. 调试实录:那些不会出现在数据手册里的问题

5.1 偶发跳变:压缩机启动瞬间的数据尖峰

现象非常典型:温度曲线偶尔出现4到5℃的瞬间跳变,持续几十毫秒后自己恢复。用示波器看模拟输入引脚,没有明显的工频干扰,但盯住3.3V电源轨,发现LDO输出在压缩机启动瞬间有约80mV的跌落。

根因找到了:UART数据线和模拟电源走线在PCB上靠得太近,数字信号翻转的噪声通过寄生耦合串进了AVDD。解决方法很直接,把AVDD滤波电容从10μF加大到22μF,同时把模拟输入走线改到远离串口线的一侧。改版后同样的工况下再没出现过跳变。这个案例说明一个道理:模拟电路里的“幽灵干扰”,很多时候不是来自外部,而是自己板上的数字电路。

5.2 系统性偏差:所有通道都低0.3℃

第二批板子调试时,四路温度全部比参考温度计稳定地低约0.3℃,而且是固定偏差,不是随机波动。一开始怀疑传感器批次差异,换了探头还是一样。

最后逐颗检查BOM,发现基准电阻出问题了。物料清单里写的2kΩ 0.1%精密电阻,实际批次标称值其实是2.008kΩ,比例法换算时我用了理论值2kΩ来计算。2.008kΩ和2kΩ的偏差,折算到PT1000测温结果正好是约0.3℃。这事给了我两个教训:一是比例法虽然消除了电流源误差,但基准电阻的初始精度和温漂必须自己保证;二是BOM物料到位后要抽测关键器件的实际参数,不要只信原理图上的标称值。

5.3 长时间运行后UART通信挂死

这是压轴问题,也最折腾人。系统连续运行几天后,ADC模块怎么叫都不应,只有断电重启才能恢复。一开始怀疑是MCU死机,但看门狗还在喂,UART发送准备标志位也正常。

最后定位到:异常时序下MCU给ADS122U04发送了一个无效命令字节,把芯片内部的UART状态机带进了未定义状态。修复方案是从软件“抗造”角度入手:每发一条命令都检查响应状态,发现无响应或响应异常就立刻发复位命令,而不是傻等。加了这个重发和恢复机制之后,整套系统连续运行几个月没有复现挂死问题。嵌入式通信的健壮性不是靠祈祷不出错,而是靠出错后能自己恢复。

5.4 自热问题:NTC读数的“温水煮青蛙”

NTC通道在通电后温度读数会缓慢上升,头三分钟能漂0.5℃。这是典型的自热效应:恒流源持续给NTC供电,电阻自身发热,改变其阻值。我把恒流值从0.25mA降到0.15mA之后,自热改善了一些,但没有根治。

真正的根治方案是“短时激励采样”:软件里只在读取前的50ms打开NTC激励电流,读完成马上断开。这样NTC的发热量降到连续激励的几十分之一,读出来的温度就是环境真实温度。这个技巧简单有效,而且顺带省电,强烈推荐给所有做电池供电或低功耗采集的朋友。它的副作用是采样前需要等待电压稳定,但50ms的延时在温度采集场景里完全不是问题。

6. 这套方案后续扩展和维护的几点建议

6.1 传感器与通道的模块化预留

这轮项目做完,我最大的体会是硬件设计一定要给扩展留余地。ADS122U04IPWR有四个模拟通道,这次只用了两路,剩下两路空着。后来客户要求在现有板卡上增加一路风管湿度传感器,我直接在备用通道上加了个温湿度变送器的模拟输出,固件里加一路采集配置就完成了,不用改板。通道预留也是选型的一部分,如果当时选个双通道ADC,现在就得重新走一遍硬件流程了。

6.2 数据速率的动态切换思路

还有一个可以深耕的方向:根据HVAC运行阶段动态切换ADC的数据速率。正常回风温度调节时用20 SPS,慢且稳;遇到压缩机启动、需要快速计算过热度变化的瞬间,可以临时把数据速率切换成高两档的档位,处理完再切回来。ADS122U04支持运行中改写配置寄存器,所以这个动态切换在固件上完全可行,只要把滤波窗口也相应调整,就能兼顾稳定性和动态响应。我下一步计划在样机上先跑通这个逻辑,预计能让过热度控制的波动再收敛一些。

6.3 量产前的筛选建议

如果这套设计要批量生产,建议在出厂测试环节增加一个简单的温度自检:板上预留一个精密电阻通道,通过ADC测量该电阻值与标定值做比对,可以直接筛查出焊接不良、ADC损坏和基准电阻贴错的问题。这个做法成本极低,却能避免大量现场返修。工业品返修一次的成本,足够做几十次出厂测试,这笔账怎么算都划算。