这几年做HVAC控制器和工业测温仪表,碰到的温度采集需求基本可以分成三类:空调风管和水管里的NTC热敏电阻,现场精度要求高的PT100/PT1000铂电阻,偶尔还有燃烧室、排烟口的K型热电偶。这些传感器信号量级差异非常大,从几十毫伏到几十微伏都有,直接用MCU内置ADC去采,分辨率根本不够。我在这类方案里常用的组合是ADS122U04IPWR加PIC18F87J50:前者是带UART接口的24位Delta-Sigma ADC,后者是Microchip的8位单片机。实测下来在20SPS采样率下,配合合理的滤波算法,这套系统能做到±0.1℃级别的重复性,满足工业HVAC的精度和抗干扰要求是够用的。
这篇文章把整个方案的硬件选型逻辑、传感器前端设计、UART通信实现、温度换算公式、以及现场调试踩过的坑都写出来。适合正在做暖通控制器、楼宇自控采集模块、工业仪表测温通道的嵌入式工程师参考;如果你只是想把一个PT100读准,里面的比例测量思路和寄存器配置思路也能直接抄。
1. 为什么选“24位ADC+UART”组合,以及整体方案拆解
1.1 两个核心器件的定位差异
先搞清楚一个容易被忽略的问题:为什么温度测量要用24位ADC,而不是直接用MCU自带的12位ADC?
以PT100为例,0℃时阻值100Ω,温度系数大约是0.385Ω/℃。想分辨0.1℃,需要分辨0.0385Ω的电阻变化。如果用1mA恒流源激励,0.1℃对应的电压变化只有38.5µV。MCU内置ADC在3.3V参考电压下,12位的LSB就是0.8mV左右,连0.1℃都看不到,更别说信号里的噪声和漂移。24位Delta-Sigma ADC的优势在于,它把高分辨率和大动态范围结合起来,配合可编程增益放大器(PGA),能把微伏级别的信号从噪声里“挖”出来。
ADS122U04IPWR这颗芯片实际做的事情,就是把传统SPI接口的ADS1220加了一个UART通信层。它内部有4通道输入MUX、PGA(增益1到128倍)、24位Delta-Sigma调制器、数字滤波器、内部2.048V基准源、内部温度传感器,以及用于断线检测的激励电流源。所有配置都通过寄存器完成,MCU只需要用三根线(TX、RX、GND)就能读写它。
选择UART版本而不是SPI版本,我的理由很务实:
- 工业HVAC设备里传感器和控制器经常分开安装,线缆可能走1到3米。UART是异步串行协议,对时钟同步不敏感,线缆长度和线间电容对通信的容错度比SPI高。
- 很多8位单片机硬件UART是标配,而SPI接口如果引脚复用,往往要跟别的外设打架。UART省引脚,PIC18F87J50的EUSART直接就能用。
- 调试方便,串口助手可以直接看ADC返回的数据帧,比SPI逻辑分析仪调试轻松得多。
PIC18F87J50也不是随便选的。它是80引脚TQFP封装的8位MCU,128KB Flash,3.8KB左右RAM,3.3V供电,主频最高到48MHz。做测温采集这种任务,运算量不大,但它自带两个EUSART、足够的I/O和定时器,尤其适合后面要扩展Modbus、BACnet或者人机界面。这种“高性能ADC完成模拟量采集,8位MCU负责协议和逻辑”的分工,是我这几年比较推崇的架构:模拟和数字分离,开发和维护成本都在可控范围。
1.2 系统整体信号流与硬件分工
整套系统的信号流并不复杂:
温度传感器 (PT100/NTC/热电偶) ↓ 模拟前端(恒流源、精密电阻、RC滤波) ADS122U04IPWR (24位ADC,UART输出数字结果) ↓ UART命令/响应帧 PIC18F87J50 (EUSART接收,完成滤波、线性化、控制逻辑) ↓ 显示 / 继电器 / RS485/Modbus / 上位机每个环节的分工需要提前划清楚。模拟前端负责把传感器信号转换成ADC可识别的差分电压范围;ADS122U04负责高精度模数转换和部分数字滤波;PIC18F87J50负责通信协议、温度线性化计算、数字滤波平均值处理,以及最终的PID控制或对外通信。这样每一个芯片只做自己擅长的事,出了问题也容易定位。
实际搭建的时候,我建议把ADC的模拟地和数字地单独铺铜,在ADC芯片下方用单点汇接,别让PIC18F87J50开关数字输出时的地弹噪声灌进ADC的模拟输入。HVAC场景里继电器、接触器、压缩机启停都是强干扰源,这一条在后续调试阶段能省很多事。
2. 传感器选型与模拟前端设计(这里决定成败)
2.1 常用测温传感器对比
HVAC和工业测温里,三种传感器几乎覆盖了全部场景,但它们的信号特性、接线方式、计算模型完全不同。我做了个对比表,方便方案选型时直接拍板:
| 传感器 | 精度/稳定性 | 信号量级 | 典型测温范围 | 主要难点 | 适用场景 |
|---|---|---|---|---|---|
| PT100/PT1000 | 高,长期稳定 | 0℃时约0.4Ω/℃,激励电流1mA时约0.4mV/℃ | -200℃~850℃ | 需要比例测量和引线电阻补偿 | 水管温度、风管温度、冷水机组、工业过程 |
| NTC 10kΩ | 中,响应快 | 25℃时约-4.4%/℃,分压输出明显 | -40℃~105℃ | 强非线性,需要查表或Steinhart-Hart公式 | 室内温度、回风温度、室温控制器 |
| K型热电偶 | 中高,耐高温 | 约41µV/℃ | -200℃~1250℃ | 信号极微弱,需要冷端补偿 | 锅炉排烟、燃烧器温度监测 |
PT100和PT1000怎么选?如果线缆不长、系统里MCU供电和ADC供电充足,PT100的成本更低;但PT1000因为阻值高,同样的引线电阻影响相对小,而且激励电流可以取得更小,自热效应低,更适合电池供电或低功耗场景。我在HVAC水系统里常用PT1000,配合PGA增益16,能拿到很好的分辨率。NTC则用在室温采集,成本低、灵敏度高,虽然没有PT100线性,但范围窄,查表之后精度也够。
2.2 RTD比例测量电路详解
用ADS122U04测PT100/PT1000,最容易犯错的地方是把ADC的基准电压和激励电流分开设计,结果ADC基准源纹波和恒流源噪声一起作用,精度大打折扣。正确做法是“比例测量”(ratiometric):让同一个激励电流同时流过精密参考电阻RREF和PT100,再用RREF两端电压作为ADC的参考电压。
这样做的妙处在于:测量结果只取决于PT100电阻和RREF电阻的比值,ADC内部基准源电压的长期漂移、激励电流本身的温漂都被抵消掉了。公式非常干净:
R_pt = RREF × (CODE / 2^23)其中CODE是ADC读到的24位二进制补码值,满量程对应2^23,这个关系只在比例测量成立,对应电压等于参考电压的瞬间。若用非比例方式,需要先算电压再除以电流,误差来源多了一倍。
三线制接法上,PT100的引线电阻每米可能有零点几欧姆,双线制会把这段电阻串联进测量结果,直接导致几度的误差。四线制最准,但现场很多HVAC传感器只出三根线。这时候利用ADS122U04的两个IDAC恒流源就能做引线电阻补偿:一路电流流过引线电阻和PT100,另一路电流流过另一根引线电阻,通过差分测量把引线压降抵消掉。如果只有一路IDAC配置简单,就尽量用四线制,让引线电阻不进入测量回路。
RREF电阻的选择直接决定测量精度。我建议用低温漂(25ppm/℃以下,有条件上10ppm)的精密电阻,阻值跟PT100在量程中点的阻值接近。PT100量程0~100℃,取RREF=100Ω或者150Ω比较合适;PT1000则取1000Ω。RREF的功耗也要算一下,激励电流如果取250µA,100Ω的RREF上功耗只有6.25µW,温升可以忽略。
2.3 输入滤波与抗干扰防护
工业HVAC环境最大的敌人不是白噪声,而是变频器、继电器、接触器产生的共模和差模干扰。ADS122U04的PGA输入端是高阻抗开关电容结构,外部RC滤波不能随便加,加不好会跟内部开关电容相互作用,导致增益误差。
我实际使用的输入滤波结构是每路输入串1kΩ电阻,然后在差分对之间并一个1nF到10nF的C0G电容。这个RC的截止频率大概在16kHz到160kHz,足够滤掉大部分开关噪声,又不影响20SPS到1000SPS的采样信号。要注意的是这个电容不能太大,超过10nF之后,Delta-Sigma调制器的输入带电时间会变长,可能出现比例误差或偏移,具体上限以数据手册里面的输入阻抗分析为准。
线缆入口处还要加ESD/TVS保护。HVAC现场的传感器线缆经常是沿着强电线槽走的,感应出来的浪涌能量非常大。我在ADC输入端对地并了BAT54S这类低漏电二极管做过压钳位,然后在电源入口加一个LC滤波或者磁珠,实测能过IEC 61000-4-2接触放电4kV的等级,不至于一打静电就复位。
3. 固件实现:UART通信、寄存器配置与温度计算
3.1 与ADS122U04的UART通信基础
ADS122U04的UART接口是典型的主从命令响应模式。MCU发送命令帧,ADC回传响应帧,帧格式里包含地址、命令类型、数据和校验。通信参数我固定在9600bps、8位数据、无校验、1位停止位。9600在长线缆下误码率最低,虽然吞吐量低,但测温应用每秒也就几次到几十次转换,完全够用。
通信流程大概是这样:
- MCU发送“开始转换”命令,ADC进入连续转换模式;
- MCU发送“读取数据”命令,ADC返回当前最新转换结果(3字节24位数据);
- MCU发送“寄存器写”命令,配置输入通道、PGA增益、数据速率、IDAC电流等;
- MCU发送“寄存器读”命令,回读当前配置用于诊断。
具体的命令字节需要以TI数据手册的最新版本为准,不同批次固件可能存在细节差异。我的习惯是写一个独立的命令封装层,把所有命令码用宏定义集中管理,这样后期更换固件版本或者调整协议,只需要改一个头文件。
3.2 关键寄存器配置示例
ADS122U04的寄存器配置是整套固件的核心,配置错了哪怕一Bit,采集结果就是错的。下面给出我在PT1000场景下的一套典型配置参考,寄存器地址和位定义以实际芯片手册为准:
| 配置项 | 寄存器/位 | 设置值 | 含义 |
|---|---|---|---|
| 输入通道 | MUX[3:0] | 0000 | AIN0-AIN1差分输入接PT1000 |
| PGA增益 | PGA[2:0] | 100 | 增益16倍 |
| 数据速率 | DR[2:0] | 000 | 20SPS,50/60Hz工频抑制最好 |
| 参考电压 | REFSEL | 内部/外部 | 比例测量时选外部RREF电压作为参考,或内部2.048V+恒流源,视具体接法 |
| IDAC电流 | IDAC[2:0] | 010 | 250µA激励电流,用于PT1000 |
| 断线检测 | BURN-OUT | 10µA | 检测传感器开路,防止误显示 |
我最常用的是将RREF接在REFP和REFN之间,同时复用IDAC激励电流。这样配置的好处是ADC参考电压直接来自RREF,比例关系从硬件层面保证,固件里不需要额外校准参考电压漂移。
数据速率这里多说一句。20SPS时Delta-Sigma调制器的数字滤波器会对50Hz和60Hz工频有很强的抑制能力,这是普通逐次逼近ADC做不到的。HVAC现场如果既有50Hz电网又有变频器谐波,这个滤波特性比单纯在软件里多加一阶平均滤波有效得多。
3.3 温度换算实操与代码片段
数据从ADC回来只是原始码值,把它变成温度要分三步:码值换成电阻、电阻换成温度、再做数字滤波。码值换电阻在比例测量下就是一句乘除法:
// 比例测量模式下,PT100/PT1000电阻值直接由码值比例得到 float rtd_resistance(int32_t code, float rref) { // code为24位二进制补码,转成浮点数后除以2^23 return (float)code / 8388608.0f * rref; }电阻换成温度,PT100/PT1000用IEC 60751的Callendar-Van Dusen方程。0℃以上用下面的公式:
R(t) = R0 × (1 + A×t + B×t²) A = 3.9083e-3 B = -5.775e-7 C = -4.183e-12(0℃以下另有项)实际固件里我不用解析反算,而是先在PC端用Matlab生成一张0~150℃的温度-电阻查找表,每0.1℃一个点,烧进Flash,然后运行时在表里二分查找加线性插值。这样计算量小,8位MCU也跑得飞快,查表插值精度完全够用。如果正好在0℃以下,就需要用包含C系数的完整公式,建议直接用迭代法或者二次方程求解,注意现场别把符号写反。
NTC 10kΩ热敏电阻用Steinhart-Hart方程:
1/T = A + B×ln(R) + C×(ln(R))³A、B、C三个系数由厂家提供,或者用三个标准温度点的阻值反推。NTC的灵敏度在低温区低、高温区高,所以室温段精度不错,但做大范围高精度测量还是得靠PT100/PT1000,这点别反过来用。
最后在PIC18F87J50里加一个滑动平均滤波。20SPS下我取8次平均,延迟只有0.4秒,对暖通温控环路的响应速度没有明显影响。如果现场有脉冲干扰,先做一次中值滤波剔除野值,再做滑动平均,效果比单纯平均好得多。
3.4 PIC18F87J50侧的程序框架
PIC18F87J50的EUSART初始化和普通PIC18系列没什么区别。波特率寄存器BRG值根据Fosc和9600bps配置,48MHz时钟下大约是312,取整后实际波特率误差在0.16%以内,远小于UART的容差范围。
主程序我习惯用状态机而不是裸奔阻塞方式:
- 初始化时钟、EUSART、定时器;
- 每100ms触发一次“读ADC数据”命令;
- 对返回的3字节数据做校验和判断;
- 通过状态机将原始码值填入环形缓冲,供温度换算和滤波使用;
- 输出结果给PID控制器或RS485协议栈。
这里最需要注意的坑是:UART接收是异步的,ADC可能还在转换中,读数据命令发过去之后,响应帧可能延迟几个毫秒,千万别发完命令立刻阻塞收数据,一定要加超时保护。我在实际代码里统一用“发送命令→等待响应→超时重发”的三步框架,超时时间设为10ms,如果连续3次超时就报通信故障,这样现场即使线缆接触不良,系统也能安全进入报警状态而不是显示乱跳的温度。
4. 实际调试中的关键参数与性能验证
4.1 实测精度与噪声表现
在实验室用精密电阻箱校准,室温环境下对100Ω(即PT100 0℃)连续采集1小时,码值波动折算成电阻大概是±0.008Ω,对应温度±0.02℃。这个结果是在20SPS、PGA增益16、比例测量、8次滑动平均条件下测得的。如果把数据速率提高到1000SPS,噪声会明显变大,但供热通风管路控制的响应速度并不需要那么快,所以20SPS是性能和稳定性的折中点。
现场实测比实验室要差一些。空调机组启停时,附近的接触器和压缩机产生的电磁干扰会串进来,同样的代码和数据速率下波动可能到±0.05℃。这时候先别急着改滤波,优先检查ADC输入端的RC滤波和电源去耦,很多时候把模拟电源从开关电源改成LDO,噪声就降了一半。
4.2 采样率、噪声与响应速度的取舍
Delta-Sigma ADC的数据速率和有效分辨率是互为代价的。采样率越高,数字滤波器带宽越宽,进入结果的高频噪声越多;采样率越低,滤波器对高频噪声衰减越厉害,但同时温度变化的响应也变慢。这是物理规律,任何数字滤波都改变不了。
| 数据速率 | 典型噪声 | 等效温度分辨率(PT1000) | 适用场景 |
|---|---|---|---|
| 20SPS | ±0.03℃ | 约0.01℃ | 恒温控制、暖通水系统 |
| 90SPS | ±0.06℃ | 约0.02℃ | 常规HVAC,兼顾速度和精度 |
| 330SPS | ±0.15℃ | 约0.05℃ | 快速报警、启动过程监测 |
| 1000SPS | ±0.5℃以上 | 约0.2℃ | 高速同步测试,测温场景慎用 |
我实测下来,HVAC温度控制最常用的就是20SPS和90SPS两档。如果系统要响应风机盘管的快速启停,90SPS加上一阶低通滤波就足够;如果做冷水机组出水温度的精确控制,20SPS的噪声抑制优势更明显。
4.3 PCB布局与强电环境抗干扰经验
现场抗干扰能力,一半靠器件选型,一半靠PCB布局。我总结了几条在工业HVAC设备上反复验证过的原则:
- 模拟地和数字地分开铺,在ADC芯片的单点汇接;继电器、驱动电路的地线绝对不要和模拟地共路径。
- ADS122U04的电源引脚用10µF和0.1µF两级去耦,小电容紧贴引脚,大电容靠电源入口。
- PIC18F87J50的晶体和复位电路远离模拟输入走线,数字I/O翻转频繁的线不要跨越ADC输入区域。
- 传感器线缆如果在机箱内走线较长,使用屏蔽双绞线,屏蔽层单端接地。
- ADC输入走线尽可能短而宽,差分对等长等距,减少共模噪声转化为差模的概率。
遵循这些原则之后,我在一个带变频器的HVAC控制器样机上做过EFT/Burst 2kV测试,测温通道的数据没有明显跳变。这个结果比单纯堆软件滤波要可靠得多,软件滤波只是“事后弥补”,前端设计好才是“事前解决”。
5. 常见问题与排查技巧实录
现场调试和售后反馈里,测温通道的问题翻来覆去就那么几类。我整理了一张排查表,基本覆盖了90%的故障:
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 温度显示持续偏高且非线性 | PT100引线未做四线/三线补偿,引线电阻串入测量回路 | 改为比例测量+差分输入,检查IDAC电流走向 |
| 温度跳字严重,呈±几度抖动 | 模拟电源纹波大,或输入RC滤波缺失 | 增加LC滤波/LDO,检查RC参数是否过大硅片开关 |
| 通信偶发失败或读数为零 | UART波特率误差、线缆过长、命令时序超时 | 用示波器看TXD/RXD波形;降低波特率到9600;增加重试机制 |
| 传感器断线后显示300℃以上 | 断线检测没有开启,输入悬空被干扰拉偏 | 配置BURN-OUT电流源,断线时输出错误码并报警 |
| 温度响应慢,恒温时有振荡 | 滤波窗口太长,PID采样周期不匹配 | 缩短滑动平均窗口,重算PID采样周期 |
| 零点漂移大,每次上电不一致 | PGA偏移未校准,或RREF电阻温漂过大 | 上电执行系统偏移校准,换用低温漂RREF |
在这里特别强调两件事。第一,系统偏移校准不是可选项。ADS122U04这类Delta-Sigma ADC的PGA在增益较高时会有微伏级别的偏移,虽然不大,但在0.1℃精度的目标下必须校准。我通常在设备上电时,用ADC内部输入短接(或者外部用零欧通道)采集100次取平均,作为偏移存在Flash里,之后每次换算前先减掉。第二,RREF的温漂是“隐藏杀手”。很多工程师把注意力放在ADC和传感器上,却忽略了基准电阻自身随温度变化带来的误差。一个100ppm/℃的100Ω电阻,环境温度变化10℃,测温误差可到0.25℃以上,这在HVAC现场是完全不可接受的。
还有一个从售后反馈里总结的经验:HVAC设备出厂校准用的是25℃环境,但现场空调箱内部温度可能是40℃甚至更高,而冬天室外安装的传感器可能是-10℃。如果RREF和PT100离得太近,RREF的温度会跟着被测温度走,比例测量的优势就没了。因此PCB布局时RREF要尽量远离散热片、加热器和大功耗器件,必要时给它一个小的隔热罩或远离热源区域。
6. 从测温模块到系统集成:我的几点体会
这套方案做完测温这个核心功能之后,往后再扩展就顺了。因为ADS122U04带了4通道MUX,单颗ADC就能同时采集多路温度;PIC18F87J50剩余的资源还可以跑Modbus RTU协议,把温度数据送到楼宇BA系统。如果产品是电池供电,ADC支持低功耗模式,MCU可以进入睡眠,定时唤醒采集一次再发出去,整体功耗控制很方便。
我自己在实际项目中踩过几次坑之后,最大的体会是:高精度测温不难,难的是在工业现场干扰和成本约束下保持高精度。芯片选型只是第一步,模拟前端设计、PCB布局、固件滤波校准、系统级联调,每个环节都在贡献误差。如果让我给后来者一个最朴素的建议,那就是先把比例测量和四线制接法吃透,再把偏移校准当成标配,最后才去追求更花哨的数字滤波算法。这三件事做好了,你这套测温系统不管配什么MCU、什么ADC,精度都不会差。
最后分享一个调试小技巧:现场排查温度误差时,我习惯用一根已知精度的标准电阻箱临时替换传感器接入ADC输入端,如果此时读数跟电阻箱阻值对应温度一致,问题就在传感器或线缆;如果读数都不对,那就是ADC配置、前端电路或固件换算的锅。半小时内就能把故障范围缩小一半,比拿万用表盲测高效得多。这套ADS122U04加PIC18F87J50的组合,我自己还在继续用,也期待看到它在更多HVAC场景里折腾出新花样。