
每年一到现场调试验收的旺季工业测温和HVAC系统的温控问题就开始扎堆冒出来。热电偶信号只有几十毫伏PT100的阻值变化每摄氏度也就零点几欧姆而现场一开变频器、一碰大电机传感器线上的共模干扰和地噪声就能把信号彻底淹没。这种环境下靠单片机自带的ADC测温度基本只能得到一个“趋势参考”想拿来做精确计量或者闭环控制根本不够用。所以我在这一类项目里一直坚持一个组合思路MCU负责控制和通信外置高精度ADC负责信号采集和转换。今天聊的这套配置就是我在实际项目中反复使用过的ADS122U04IPWR配合PIC18F86J55的方案面向工业现场和HVAC系统的多点温度采集。无论是PT100/PT1000热电阻还是K型热电偶这套组合都能扛得住而且成本可控、开发周期短非常适合中小批量产品和自研控制器的场景。1. 项目全景这套测温方案到底要解决什么问题1.1 工业与HVAC测温场景的典型需求先别急着看芯片手册。做项目之前我习惯先列需求清单因为很多坑就是从“需求没想清楚”开始的。工业现场和HVAC系统里的温度测量表面上都是“测个温度”实际要求差别很大。HVAC场景比如楼宇自控的管道送风温度、回水温度、制冷机组蒸发温度特点是测点分散、线缆长、环境干扰复杂。风机的启停会拉低供电电压变频器会让电源线上出现明显的纹波空调机房里的动力线经常跟传感器信号线走同一个桥架。这类系统一般要求温度分辨率到0.1℃级别响应时间不要过长因为控制逻辑要频繁调节阀门和风机数据更新太慢会让控制滞后。工业场景就更苛刻一些。反应釜的导热油温度、热风干燥通道的出风口温度、空压机的高温报警、电机绕组的过温保护这些地方的传感器可能离控制器有几十米远现场还可能存在电磁阀吸合带来的脉冲干扰。精度要求往往是±0.5℃或者±0.2%而且要长期稳定不能因为环境温度变化或者器件老化导致读数漂移。另外这类项目通常会有集中监控的需求要么是RS485总线接上位机要么是Lora/以太网上传到平台。把这些需求放在一起可以提炼出几个关键技术指标高分辨率、低噪声、抗干扰、支持长线传感器、多通道扩展、稳定的参考基准、以及足够的通信能力。单独靠MCU内置ADC很难同时满足所有这些要求。1.2 为什么要用“MCU加外置高精度ADC”的组合我在很多入门教程里看到过“直接用MCU自带的ADC”的做法单片机引脚直接接PT100的分压电路就开测。这种方案能不能用在玩具级项目里能凑合在正经的工业设备里基本不能指望。MCU内置ADC一般是12位逐次逼近型SAR采样率虽高但有效位数通常只有9到10位。12位分辨率在3.3V参考电压下每个码字对应的电压是3.3V/4096约0.8mV。而PT100在0℃时电阻刚好100Ω温度每升高1℃电阻只变化约0.385Ω如果用1mA激励电流对应的电压变化也就0.385mV。也就是说MCU内置ADC的一个码字大概对应2℃以上的温度变化这么低的灵敏度直接决定它没法做精细测量。还有更麻烦的问题MCU内部的数字电路开关噪声会耦合到ADC参考电压和模拟输入上加上PCB上数字走线跟模拟走线离得近实测噪声经常会超过理论量化噪声。再有就是大多数MCU的ADC参考电压就是供电电压VDD稍微波动一点测量结果就跟着漂。外置高精度ADC芯片特别是ΔΣ型ADC通过高倍过采样和数字滤波把分辨率做到24位同时把量化噪声推到带外再加上内部PGA增益放大微弱信号整体有效分辨率能做到微伏级别。更重要的是专用ADC芯片的模拟前端电路设计考量完全不同输入结构、参考电压、激励电流源都是为传感器测量专门优化的。所以我选型的原则很简单控制器只做它擅长的事比如跑控制逻辑、通信协议和人机交互把模拟微弱信号测量交给专业的ADC芯片。这就是ADS122U04IPWR这类器件存在的原因。2. 芯片选型背后的逻辑2.1 ADS122U04IPWR一块较真的模拟前端ADS122U04IPWR是TI推出的24位ΔΣ模数转换器后缀里这个U代表接口是I²C而不是SPI04表示有4组差分输入或8个单端输入IPWR是封装和卷带信息TSSOP-16小封装。我最早接触的是ADS1220系列后来发现需要多接几个模拟通道并且不想多占用GPIO的时候就把方案换到了ADS122U04。这颗芯片内部集成了不少好用的东西。输入多路复用器支持4路差分输入或者8路单端输入这意味着一个芯片就能接多路热电阻或热电偶。内部PGA可编程增益从1到128能把热电偶那种毫伏级别的小信号放大到ADC满量程附近充分发挥24位分辨率的能力。两个完全匹配的可配置电流源IDAC是给RTD激励用的电流范围从50μA到1000μA可调。内部还有一个2.048V参考电压初始精度约±0.2%温度漂移控制在几十ppm/℃级别对大多数应用够用。更关键的是芯片允许用外部参考电阻做比例式测量这是消除激励电流误差的利器后面我会细讲。内部集成的温度传感器则为热电偶冷端补偿提供了专用通道。数据率从20SPS到4000SPS可配置低速率下噪声很低我记得在PGA增益是128的时候20SPS下的输入参考噪声能做到1微伏上下这个水平对应PT100大概就是0.005℃的分辨率相当可观。功耗方面正常模式大概几百微安量级还有一个省电模式可以待机很适合一些要求低功耗的无线采集节点。断线检测功能也内置了传感器断线或者短路时能给出明显的状态标志方便做故障诊断。2.2 PIC18F86J55一颗本分的控制核心PIC18F86J55这颗MCU在很多人眼里可能有点冷门但在工业测控产品里算是老面孔了。它是Microchip PIC18高端系列的一员80引脚TQFP封装工作电压范围1.8V到3.6V正好跟ADS122U04的供电电压完美对齐一块3.3V的LDO就全搞定了。它属于8位单片机但主频最高能跑到48MHz处理一个温度采样的控制逻辑绰绰有余。内部程序闪存64KB数据EEPROM也有1KB校准参数可以直接存在内部省掉一颗外挂EEPROM。外设资源很丰富硬件I²C、SPI、多个UART、CAN模块都有这些在工业系统里特别实用。我要接RS485跑Modbus用UART加收发器就行要接触摸屏或者上位机再开一组UART做协议解析完全不冲突。选它还有一个原因跟ADS122U04一样这两颗芯片都来自大型老牌半导体厂供货周期和生命周期都比较稳定不像某些小众芯片说停产就停产。而且PIC的生态成熟编译器和调试器都很顺就算团队里有人没接触过PIC学起来也不费劲。2.3 别的方案为什么不推荐也有朋友问过我用别家32位MCU测温度不行吗比如STM32加内置ADC甚至直接上FPGA加AD7190。我的回答是看项目定位。STM32内置的ADC同样是12位SAR只要你不是大几千路同步采集它的精度能力并不会因为芯片主频更高而变好。真正的问题在于模拟前端设计要想达到ADS122U04这个级别的噪声性能你得自己搭仪表放大器、滤波器、参考电压源PCB面积和调试成本都上去了最后的精度还不一定有人家集成方案好。FPGA方案就更不适合了。一上FPGA硬件成本翻几倍开发工具和调试复杂度也翻几倍一个温度采集项目要是没有十几路同步采样的刚需纯粹是浪费。数字温度传感器比如DS18B20虽然用起来简单但是分辨率只有12位精度典型值±0.5℃已经很不错了但整体的长期稳定性、响应速度和抗干扰能力离工业计量还是有距离。而且它没法直接接热电偶HVAC系统里测风道温度不少场合就是K型热电偶数字传感器就无能为力了。所以我给这类应用定的标准方案就两条路对精度要求高、通道适中的项目用ADS122U04这类外置ΔΣ ADC配一颗通用的8位或32位MCU对通道特别多、同步性要求高的项目才考虑多片ADC加FPGA的架构。用PIC18F86J55配ADS122U04属于前一条路线里性价比很高的代表。3. 硬件设计的核心细节3.1 RTD的接线、激励与比例测量先说不论是PT100还是PT1000测量原理都是通过测电阻来间接测温度。RTD阻值随温度变化但变化量很小所以需要给它一个稳定的激励电流把这个电阻变化转成电压变化再交给ADC去测。ADS122U04内部的两个IDAC电流源就是干这个的。接一个PT100的典型电路是这样的IDAC1输出恒定的电流比如500μA或1mA流过RTD再流回模拟地。RTD两端的电压就正比于阻值。这里有个问题如果只用两线制接法导线电阻会直接叠加到测量结果里。比如采用1mA激励每米导线的电阻如果有0.1Ω两米导线就贡献0.2Ω对应PT100就是0.5℃的误差长线下来根本没法看。解决方法是三线制接法。原理是再引一根导线出来把导线电阻的压降用差分输入抵消掉。更稳妥的做法是用两个电流源一个给RTD提供激励一个生成一个参考电压但RTD本身是两端器件三线制接法里第二根线其实起的是补偿导线的作用。ADS122U04的IDAC1和IDAC2是精确匹配的出厂时做了失配校准用它们做三线制补偿效果很好。为什么匹配重要因为补偿的出发点是假设两根导线的电阻和电流都相同这样减小压降误差匹配越好补偿越精确。再说比例测量这是个特别关键的设计思路。RTD的阻值测量其实可以跟激励电流的绝对精度脱钩。做法是把一颗精密参考电阻Rref串在IDAC回路上用Rref两端的电压作为ADC的参考电压。这样即使IDAC电流因为温度变化有漂移RTD和Rref上的电压成比例变化最后计算结果会自动抵消掉电流误差。让我举个例子。假设Rref取1500ΩPGA增益为1IDAC电流为1mA。RTD在0℃时电阻100Ω两端电压0.1VRref上电压1.5V。ADC的比例计算得到0.1V/1.5V×1500Ω正好是100Ω。如果激励电流从1mA漂到1.05mA两个电压都变成原来的1.05倍比例不变计算出的电阻还是100Ω。这就是比例测量的精华所在实际工程中比用内部参考电压要稳得多。硬件接法上Rref的选择要兼顾几个因素。电流源输出电压摆幅有限RTD两端电压加上Rref电压不能超过IDAC的输出合规范围。PT100满量程到300℃时阻值约212Ω1mA激励下RTD压降0.212VRref压降1.5V加起来在3.3V供电下没问题。如果选用PT10000℃时阻值1000Ω1mA电流就产生1V电压再叠加Rref的1.5V接近3V了电流源可能就要进入非线性区这时候我建议把电流降到500μA或者换低一点的Rref。3.2 热电偶的冷端补偿方法工业现场有大量使用热电偶的场景。K型热电偶测温范围宽、价格便宜、响应快但信号非常小常温下热电动势一般就在几十微伏到几十毫伏之间。比如K型热电偶在0到1000℃范围内对应的热电动势大约是0到41.27mV。这个信号直接超出MCU内置ADC的实用范围但对于ADS122U04来说只要设置PGA增益为32或64就能把信号放大到合适的量级。热电偶的测量有个绕不开的概念叫冷端补偿。热电偶产生的是热端和冷端之间的温差电动势也就是说如果你知道冷端参考端的温度才能从实测的电动势差值反推热端的实际温度。工程上有两种标准做法把冷端放在冰水混合物里维持0℃或者测量冷端温度并用软件做补偿。第二种方法在设备里当然更现实。ADS122U04内部集成了温度传感器通过多路复用器的选择可以直接测量芯片内部的温度。我把这个温度当作冷端温度Tref然后在固件里根据热电偶类型查多项式算出Tref对应的补偿电动势加到实测电动势上最后再反推热端温度。这样操作的关键在于冷端必须尽可能靠近热电偶接线端子否则接线端子处如果有温差补偿就不准了。实际项目里我会在PCB上留出热电偶端子的位置并且让内部温度传感器尽量靠近端子区域同时避免端子附近有大功率发热元件比如LDO或者功率电阻。冷端补偿的准确度直接决定了热电偶的整机精度这一块值得花精力去优化。3.3 布线与供电设计模拟电路布线是决定最后性能的一步。同样的芯片布线不同实测噪声可以相差一个数量级。铺地策略上我是严格把模拟地和数字地分开在板子的电源入口处单点汇合。ADS122U04的模拟输入、参考引脚、IDAC输出都属于模拟区域I²C信号属于数字区域两者的地平面不要有交叉覆盖。有些工程师贪方便所有地全铺在一起数字开关噪声就会通过地平面耦合到模拟电路最后的读数就是“毛刺一坨”。滤波和防护元件的摆放也很关键。RTD输入端我一般会串一个10Ω电阻加100nF电容组成RC低通带宽大概160kHz足以滤掉大部分射频干扰又不会对直流信号造成明显衰减。参考电阻Rref两端要加去耦电容我习惯在Rref上并联一个10μF陶瓷电容和一个0.1μF小电容给ADC参考输入提供一个低阻抗交流通路。I²C总线上的上拉电阻不能忘一般2.2kΩ到4.7kΩ都行上拉电阻接3.3V注意总线电容别太大否则高速读写会出错。供电方面ADS122U04和PIC18F86J55都用3.3V供电。很多小项目图省事直接用一颗LM1117-3.3给整个板子供电然后模拟部分跟数字部分共用。只要电路不是太苛刻这个做法一般能跑但容易在ADC结果里留下电源相关的噪声。比较稳妥的做法是用一颗LDO给数字部分单独供电再用一颗小LDO或者磁珠加π型滤波给模拟部分供电两个地单点连接。如果现场电网谐波重输入端还要加TVS管和共模电感防止浪涌和雷击打坏芯片。4. 固件实操从寄存器到温度值4.1 初始化流程与寄存器配置固件这部分我踩过的坑也不少先讲整体流程。上电之后首先要对ADS122U04做一次复位操作确保它从确定状态开始。可以通过I²C发复位命令或者直接拉REV引脚。复位之后依次配置四个配置寄存器每个都是8位。配置寄存器0地址0x00控制输入多路复用器和PGA增益。配置寄存器1地址0x01控制数据速率和工作模式。配置寄存器2地址0x02控制参考电压、温度传感器和电流源。配置寄存器3地址0x03控制IDAC的输出方向和比较器。我通常给PT100场景配置这样的值选择差分输入AIN0-AIN1PGA增益1数据速率50SPS内部参考电压IDAC电流设成1mAIDAC1输出到AIN0也就是RTD的激励端IDAC2输出到AIN2作为三线制补偿。注意寄存器值是位域的组合写的时候要按位操作防止覆盖掉其他配置。初始化完成后启动连续转换模式然后主循环里定时读取结果寄存器。如果系统需要多个通道轮询可以在每次转换完成后切换多路复用器配置再等下一次转换完成。PIC18F86J55这边的I²C配置比较简单设置为主模式选一个合适的时钟频率比如100kHz或者400kHz。ADS122U04的I²C地址是7位地址0x40或0x41由芯片的A0引脚电平决定。读写时序和普通I²C从机一样写配置时先发设备地址写命令再发寄存器地址然后发数据读转换结果时先从寄存器偏移0x00开始做一次写指针操作再发设备地址读命令连续读出4个字节。4.2 I²C读时序与数据合并很多刚上手的人第一次读ADS122U04的数据会懵因为转换结果不是简单的24位正整数。芯片输出状态字节加24位数据共4个字节其中前三个字节是高、中、低位数据最后一个字节是状态标志。数据格式默认是二进制补码也就是带符号数。如果是双极性模式正值和负值都能表示。读取的时候要把三个字节拼成一个32位整数然后做符号扩展。我贴一段我常用的PIC18 C代码逻辑实际项目里就是这么做的uint8_t reg_data[4]; int32_t raw_code; // 写寄存器指针到0x00 i2c_write(ADS122U04_ADDR, 0x00); // 连续读取4字节 i2c_read(ADS122U04_ADDR, reg_data, 4); // 三字节拼装注意最高位符号扩展 raw_code ((int32_t)reg_data[0] 24) | ((int32_t)reg_data[1] 16) | ((int32_t)reg_data[2] 8); // 算术右移8位得到24位有符号数 raw_code 8; // reg_data[3] 是状态字节可以检查传感器断线等状态位状态字节里的位数各有含义比如ALARM引脚状态、PGA饱和标志、传感器检测标志。代码里我会定期检查这些标志一旦发现输入超量程或者传感器异常就往上位机上报故障码这样现场运维人员能第一时间知道是传感器坏了而不是控制逻辑出了问题。4.3 温度换算的工程实现拿到原始码之后接下来就是把它换算成温度。这里分两种情况一种是PT100/PT1000一种是热电偶。PT100的换算流程是这样的。先用比例测量公式把原始码换算成RTD实际阻值R_rtd (raw_code / full_scale_code) × Rref / PGA其中full_scale_code是24位数据满量程对应的码值具体数值要看正负满量程的定义。以双极性模式为例正满量程大约是0x7FFFFF负满量程是0x800000。计算时要用浮点数或者适当扩大位数的定点数处理避免整数除法掉精度。拿到阻值之后再用Callendar-Van Dusen方程反推温度。这个方程有两个区间在0℃到850℃范围R(t) R0 × (1 A×t B×t²)。在-200℃到0℃范围R(t) R0 × [1 A×t B×t² C×(t-100)×t³]。其中R0是0℃时的标称阻值PT100就是100ΩPT1000就是1000ΩA3.9083e-3B-5.775e-7C-4.183e-12。有了这些参数可以预先在固件里建立一个查找表把阻值跟温度做好映射运行时用线性插值或者二分法查表查询时间非常短可以用于快速控制回路。热电偶的换算就多一步冷端补偿。代码逻辑大致是先用内部温度传感器读出一个冷端温度值比如26.4℃查K型热电偶多项式算出这个冷端温度能产生多少热电动势比如1.03mV把这个补偿值加上ADC实测的热电动势得到补偿后的总热电动势再用总热电动势查表反推热端温度。K型热电偶的多项式系数是NIST标准的网上可以查到我一般直接把系数表烧进程序里查表时间比在线算多项式快。无论是PT100还是热电偶最终我都建议在固件里预留一个“校准偏移”变量整机校准时把修正常量写进PIC18内部的EEPROM。这样产品出厂后还可以现场微调不用重新烧录程序。5. 常见问题与排查实录5.1 读数跳动越看越心烦这是最常见的问题。现象是ADC读出来的温度值在几个摄氏度甚至十几个摄氏度之间来回跳看着就像随机噪声特别大的样子。排查顺序我是这么定的先检查布线再看配置最后查外部干扰。布线方面重点看模拟输入导线是否跟数字信号线并行走线有没有跨越数字地平面。如果PCB已经定型改线不方便那就在输入端加一个从阻值稍大的RC低通滤波器比如100Ω加1μF电容让输入带宽降下来。配置方面确认PGA增益和数据率是不是匹配。很多人把数据率调到最高比如4000SPS这时候ΔΣ调制器的过采样率降低噪声会急剧上升看似“实时”其实根本没法看。工业测温度50SPS到200SPS已经足够快了再高并不会带来实际好处反而全是噪声。外部干扰方面现场变送器接线太长、没有屏蔽层、屏蔽层接地不良都会引入射频干扰和工频干扰。这时候把信号线换成屏蔽双绞线屏蔽层在控制器端单点接地就能明显改善。5.2 温度误差大测什么都偏如果读数稳定但跟水银温度计或者标准源一比总是偏高或偏低一大截那就是误差问题。先看是不是RTD的比例测量没做好。比如参考电阻Rref用的不是高精度低温漂电阻而是一颗普通贴片电阻温度变化时参考电阻自身漂移几百度ppm直接折算成测温误差。Rref我一般用精度0.1%、温漂25ppm/℃的薄膜电阻或者金属箔电阻别省这个钱。再看激励电流。有些电路里IDAC电流设得太大导致RTD自身发热产生自热效应。比如1mA电流流过100Ω电阻功耗是0.1mW虽然看起来不大但如果RTD探头被放在静止空气里热阻很大自热温升可能到0.1℃甚至更高。要检测这个问题可以分别用0.5mA和1mA电流测同一个温度看读数差异大不大。如果差异明显说明自热效应不可忽略要么降电流要么改善散热。热电偶误差还有一个常见原因冷端温度传感器测到的并不代表真正的冷端温度。安装位置如果靠近发热元件或者被风吹到测出来的补偿温度就会偏差最终热端温度也跟着偏。我一般会把冷端温度传感器放在远离发热元件的位置并且在程序里对内部温度传感器的读数做一次单点校准。5.3 I²C通信偶尔卡死I²C虽然只有两根线但也是整个系统里比较脆弱的环节。SPI偶尔还可靠点I²C一旦有一根线被外部设备拉死整个总线就瘫痪了。我遇到过几次是现场配电箱里的24V电源跟地线之间出现浪涌导致I²C总线上出现瞬间超过3.3V的电压把从机打死。所以我会在I²C线上加两个ESD保护管并且把上拉电阻接到3.3V的模拟电源上而不是数字电源上这样总线上噪声会小一些。代码层面也要做容错。我习惯给每次I²C读写加上超时判断如果连续几次读写都没有ACK回应就先把总线恢复发9个时钟脉冲释放总线再重新初始化ADS122U04并重读配置。这套“看门狗式”的重启逻辑能避免控制器因为一次总线错误就卡死特别适合无人值守的HVAC柜体。5.4 排查速查表我把几年下来整理的排查经验浓缩成一张表遇到问题直接按表查能少走很多弯路。现象可能原因检查项与处理手段读数乱跳布线干扰、数据率过高、电源噪声输入端加低通RC数据率降到200SPS内模拟电源加LDO/磁珠滤波温度恒定但偏大或偏小参考电阻精度差、PGA设置不对、传感器型号配置错误换0.1%参考电阻核对RTD是PT100还是PT1000校准电流源读数长期缓慢漂移参考电压温漂、传感器接到热源附近自热换低漂移参考、降激励电流、增加散热I²C读写报NACK上拉不足、总线电容过大、从机地址错误检查上拉电阻降总线速度复位后重新扫描地址热电偶读数明显偏低冷端补偿失效、端子接线反了检查冷端温度读数、校验接线极性6. 这套方案的扩展方向与我的实际操作体会做完一个项目我总会想想这套方案还能往哪里走。ADS122U04有8个单端输入如果只是测4路PT100浪费了一半通道。我会把这些通道用起来比如加几路NTC测环境温度或者再用一路通道测模拟量变送器输出的0-10V或4-20mA信号只要在输入前端加分压电阻和限流电阻把电压范围降到ADC允许范围内就行。这样一块板子能同时处理多种模拟量系统集成度一下子就高了。PIC18F86J55的多余外设也可以利用起来CAN模块可以接工业设备总线多个UART可以接触摸屏、RS485网关和打印模块。我自己做过一个版本用CAN把温度数据转发到上层PLC再用UART接一个OLED屏本地显示当前温湿度整个系统非常紧凑。最后再分享几个我个人积累的小经验。第一PCB设计时在ADC输入端、参考电阻两端、I²C线上都留好0欧电阻焊盘调试时可以根据实测表现快速切换滤波方案不用重新打板。第二固件里千万别忘了做“传感器断线检测上报”ADS122U04自带这个功能用起来很方便现场排查故障时能省很多时间。第三批量生产前对每块板子做一次两点温度校准把校准值写进EEPROM比靠元件一致性硬扛要靠谱得多。温度测量这件事方案选对了剩下的功夫都是在细节里打磨出来的。