
去年做一版 HVAC 控制器的温度采集板时最难处理的问题不是控制逻辑而是把 -40℃ 到 150℃ 的温度信号稳定、准确、低成本地送进单片机。最终定下的方案是ADS122U04IPWRTI 的 24 位 ADC配PIC18F86J10Microchip 的 8 位 MCU这组组合在工业风机盘管和冷水机组的测温板上跑了两个冬夏实测稳定性不错。这篇文章把我从选型、电路到固件、校准、现场排障的完整过程梳理一遍给正准备做工业测温或 HVAC 温度采集的朋友一份可以直接参考的实操记录。需要用到的温度传感器无论是 PT1000、PT100 还是 NTC核心链路和排查思路基本通用文章后面我也会区别说明。1. 方案选型为什么是 ADS122U04IPWR PIC18F86J101.1 工业与 HVAC 测温场景到底需要什么工业现场和 HVAC 设备里的温度采集和实验室里搭个测温电路完全是两回事。先说几个我实际遇到的要求。现场环境温度可能从 -40℃ 到 80℃被测介质从冷水到热水、从回风到盘管温度范围大多在 -40℃ 到 150℃传感器线缆短的几米长的能穿墙走桥架十几米很常见设备附近不但有风机电机还有变频器、继电器、电磁阀这些东西一动作供电线上和传感器线上都会出现几十伏甚至上百伏的尖峰干扰。除了抗干扰HVAC 项目对成本极度敏感。一块工业温度变送器模块可能卖几百块但 HVAC 控制器整机 BOM 都要卡得很死。所以选型时要找的是“模拟性能足够、接口简单、供货稳定、封装不冷门”的料。运算放大器加分立 ADC 的方案虽然灵活但元件多、调试周期长直接用温控器芯片又不够灵活毕竟温度采集只是整个控制器的一部分还要把数据送到主控做 PID、报警和远程通信。从系统层面看温度采集链路拆成三块传感器信号调理、模数转换、单片机读取与处理。前两块最好集中在一颗专用的高精度 ADC 里后一块用低成本 MCU 来负责。这也是我最后确定 ADC MCU 两个芯片方案的出发点。1.2 这两颗芯片是怎么凑到一起的ADS122U04IPWR 让我最满意的地方是接口和集成度。它是一颗 24 位 delta-sigma ADC内置低漂移参考电压、可编程增益放大器PGA和两个用于 RTD 激励的恒流源。更关键的是它带UART 接口单片机用两根线就能和它通信不需要 SPI 的片选、时钟、时序协商非常省引脚。对 PIC18F86J10 这类资源不宽裕的 8 位单片机来说这个优势很实在。PIC18F86J10 属于 Microchip 的 J 系列64KB Flash 的型号带多个串口工业温度范围宽价格也低。它在整个系统里的角色很明确负责初始化 ADC、定时读取转换结果、做温度换算和滤波、跑 PID 或逻辑控制再通过另一路串口接 RS-485 或者 Modbus 和上位机通信。8 位处理器看起来不起眼但温度采集这种慢速工业应用20SPS 的采样率加简单滤波它完全跑得动。这套组合的本质是把“模拟前端”交给专业的 ADC把“通信和控制”交给皮实的 MCU。两者之间只有 UART 相连耦合弱、调试方便后期替换也不难。这个思路在当时帮我省掉了很多模拟电路调试时间也让后续固件开发变得清晰。2. 测量链路与温度换算逻辑2.1 从传感器到单片机的完整信号链路完整的信号链路是这样走的温度传感器PT1000 或 PT100先经过 R/C 滤波和防浪涌保护然后进入 ADS122U04IPWR 的模拟输入引脚ADC 内部先做输入多路复用再经过 PGA 放大再由 delta-sigma 调制器采样最后数字滤波器的结果通过 UART 发送给 PIC18F86J10单片机再把原始码转换成电阻值、查表得到温度。前端 R/C 滤波非常重要。传感器长线会引入共模噪声R/C 低通滤波器可以抑制射频和部分工频干扰。我常用 100Ω 到 1kΩ 的串联电阻加 100nF 电容具体值要结合传感器的激励电流算一下。比如 PT1000 用 500µA 激励1kΩ 串联电阻上会多出 0.5V 压降这会影响 ADC 的输入共模范围所以阻值不能随手选。接线方式根据传感器类型不同也有讲究。PT1000 自身阻值大通常可以两线制线阻带来的误差相对小PT100 阻值小最好用三线制或四线制。ADC 的两个 IDAC 恒流源正好可以支撑三线制补偿一路电流激励传感器另一路电流去抵消线电阻产生的压降。我在 HVAC 项目里大量用 PT1000 两线制因为风机盘管的测温点离控制器不远线阻影响经过校准之后可以控制在 0.1℃ 以内。2.2 RTD 比例法测温为什么能摆脱恒流源误差温度采集最怕的不是 ADC 位数不够而是激励源漂移。恒流源给 RTD 供电阻值不变时电流一旦变化测到的电压就会跟着变。ADS122U04IPWR 内部有恒流源但再好的恒流源也有温漂所以直接测量 RTD 上的绝对电压并不是最优做法。正确思路是比例法。用一个高精度参考电阻 Rref 和 RTD 串在同一激励电流回路里让同一个电流 I 流过两者。ADC 分别测量 RTD 上的电压 Vrtd I × Rrtd 和参考电阻上的电压 Vref I × Rref然后求比值Rrtd (Vrtd / Vref) × Rref因为电流 I 在分子分母里都被消掉了恒流源的绝对值精度不再影响电阻测量结果。PGA 的增益误差、参考电压的漂移也同样被抵消。这条链路上唯一决定精度的外部元件就是 Rref所以我选的是 5ppm/℃ 的低温漂精密电阻尽量放在 ADC 的参考引脚旁边。比例法里还有一个容易忽略的细节如果 RTD 和 Rref 不共用一个电流回路两路电流不一致比例法就失效了。设计时必须保证 IDAC 的激励电流先流经 RTD再流经 Rref或者按照芯片手册的推荐方式走不能随意串联两个独立电流源。这个点我见过不少新人在原理图阶段就画错。2.3 24位分辨率到底解决什么24 位听起来很吓人很多人觉得不就是要测个温度嘛用 16 位 ADC 不够吗。实际上delta-sigma ADC 的“24 位”指的是量化位数不是最终有效精度。实际能用的有效位数受噪声、基准漂移、PGA 失调和电路板布局影响可能只有 18 到 20 位。ADS122U04IPWR 的高分辨率真正解决的是两个问题一是低温信号被放大的余地大了PGA 增益可以设得比较克制避免放大噪声二是低数据速率下内部数字滤波器能提供很强的工频抑制50Hz/60Hz 的干扰会被压得很低。HVAC 现场交流供电是常态50Hz 串扰如果没有滤波器处理后面软件再怎么平滑都难受。实际使用中我大多把采样率设在 20SPS开启 50/60Hz 抑制模式。这样单次转换的有效分辨率可以达到很高温度读数稳定到小数点后两位完全没问题。工业现场要的不是“数字快速跳动”而是“长时间稳定不漂”所以低速率高滤波反而是首选。当然如果要用在快速温度变化场景比如压缩机排气温度保护20SPS 可能不够那时可以提到 1000SPS但噪声会明显增大要接受一定的读数抖动。3. 硬件接口与关键电路设计3.1 ADS122U04IPWR 的引脚级设计要点先说电源。ADS122U04IPWR 的模拟电源和数字电源我建议不要混在一起。HVAC 控制板常用 24V 供电经过板级 DCDC 降到 3.3V但 DCDC 的纹波不能直接给 ADC 供电。我一般用一颗低噪声 LDO 单独给模拟电源部分供电数字 3.3V 再单独走。ADC 的每个电源引脚旁边都放 100nF 陶瓷电容并联 10µF 电容容值不用太大关键是靠近引脚。模拟输入通道根据项目需求分派AIN0/AIN1 作为差分输入接 PT1000 温度传感器AIN2/AIN3 作为备用通道接 NTC 或第二路温度。如果只需要测一个点可以把另一个通道留给板载自检电阻非常实用。输入引脚对地各接一个 100nF 电容串联 1kΩ 电阻起到限流和滤波作用。IDAC 激励电流的大小取决于传感器类型。PT1000 常用 500µA因为 1kΩ 阻值在 0℃ 时也有 500mV 电压而 PT100 的 0℃ 阻值是 100Ω500µA 只有 50mV太小更适合用 1mA 甚至 1.5mA。注意激励电流越大RTD 自热越明显尤其在管道流体测量时还好但在静止空气里测环境温度时自热可能造成 0.5℃ 的偏差。HVAC 测回风温度时我习惯用 250µA 到 500µA可以明显减少自热问题。3.2 与 PIC18F86J10 的 UART 接口设计ADS122U04IPWR 和 PIC18F86J10 的连线非常简单ADC 的 TX 接单片机的 RXADC 的 RX 接单片机的 TX两边共地。如果你担心现场干扰通过地线耦合可以加一颗数字隔离器比如 ISO7721把传感器侧和控制器侧隔开。HVAC 项目里如果传感器线比较长我都建议加隔离成本增加不大但可靠性提升很多。UART 电平方面PIC18F86J10 我一般跑 3.3VADC 的通信引脚也支持 3.3V 逻辑直接对接没问题。如果 MCU 是 5V则需要在 ADC 输入线上加电阻分压或电平转换否则长期运行有风险。我在第一版实验板直接直连后来发现有轻微发热检查后确定是电平不匹配造成的改成 3.3V 供电才解决。波特率建议用 9600 或 115200。长线传输时 9600 更可靠但测温数据量不大9600 完全够用。通信线上各串一个 100Ω 到 1kΩ 电阻再在 ADC 的 REV 引脚附近加一个 10nF 电容滤波能减少串扰。如果板子上还有 RS-485 电路尽量让 RS-485 电源和地远离 ADC 的 UART 走线。3.3 PCB 布线别让数字噪声污染模拟信号这可能是整个项目里最容易被低估的一环。ADS122U04IPWR 是模拟器件但 PIC18F86J10 的数字脉冲、LCD 刷新、RS-485 收发器切换都会对 ADC 产生干扰。如果 PCB 上模拟地和数字地铺成一大片噪声电流就会在 ADC 的地引脚附近流动直接反映在转换结果里。我采用的做法是分区布局ADC、精密参考电阻、传感器接口和模拟电源放在板子一角PIC18F86J10、通信接口、DCDC 放在另一角。模拟区域单独设置一块 AGND 铜皮数字区域设置 DGND 铜皮在电源入口处用 0Ω 电阻或磁珠单点相连。ADC 的地引脚不要直接连接到周围的数字地平面而是先接到 AGND再通过单点汇聚。RTD 的走线要用开尔文连接思路。传感器回来的两根线和参考电阻的采样线尽量不要中间串太多过孔避免产生附加电阻和热电偶效应。PCB 上的铜箔和焊点本身就相当于一个热电偶如果一端温度高、另一端温度低测出来的电压会有偏差。虽然这个值很小但精度要求到 0.1℃ 时就要注意。所以我让关键模拟走线尽量对称、就近、短直两边线阻保持一致。4. 固件实现寄存器、状态机和数据解析4.1 ADC 寄存器配置与命令帧组织ADS122U04IPWR 虽然是 UART 接口但本质还是通过寄存器控制。上电后我需要依次配置输入多路复用、PGA 增益、数据速率、参考电压和 IDAC 电流。以下是我常用的一组配置动作寄存器地址可能因为芯片版本不同有差异但含义是通用的系统控制寄存器选择内部参考电压使能、数据速率 20SPS、开启 50/60Hz 抑制输入控制寄存器AIN0/AIN1 为差分输入PGA 增益设为 1 或 2IDAC 控制寄存器IDAC1 输出到 AIN2电流 500µA用于 PT1000 激励。配置命令的写法是“命令字节 寄存器地址 数据”。比如写寄存器时单片机发送写命令ADC 收到后返回确认然后我回读寄存器做校验。为避免误写我会在写入后再读一遍判断返回值是否和写入值一致不一致就重新配置。这套做法虽然多花几十微秒但能避免上电时序异常导致 ADC 处于未知状态。如果板上还有其他地址可配置的相同 ADCUART 接口还可以挂成多点总线。每个 ADC 设置不同地址单片机按地址发送命令实现多通道温度采集。在大型 HVAC 机组里这个特性可以用来扩展测温点数省掉一颗 MCU 加一颗 ADC 的重复配置成本。4.2 单片机端的状态机设计PIC18F86J10 和 ADC 的通信逻辑我建议写成状态机不要用 delay 死等。原因很简单ADC 的转换周期是毫秒级死等会浪费 CPU而且一旦 ADC 无响应程序会卡住。状态机结构大致是IDLE等待定时周期到达发起读取请求WAIT_READY等待 ADC 返回数据帧PARSE解析帧头、数据字节和校验字节CONVERT把原始码转换为电阻和温度OUTPUT更新温度变量置位数据处理标志。UART 接收用中断或 FIFO每个字节进来都更新接收状态。设置一个超时计数器如果在规定时间内没有收到完整数据帧就重新进入 IDLE 并记录一次通信错误。这个超时逻辑非常重要实测下来能避免很多现场偶发卡死问题。下面给一段示意性伪代码说明状态机主循环的思路typedef enum { IDLE, WAIT_FRAME, PARSE_FRAME, CONVERT_TEMP } temp_state_t; void temp_state_machine(void) { switch (state) { case IDLE: uart_send_read_cmd(); timeout_cnt 0; state WAIT_FRAME; break; case WAIT_FRAME: if (frame_received) { state PARSE_FRAME; } else if (timeout_cnt TIMEOUT_MAX) { err_count; state IDLE; } break; case PARSE_FRAME: if (checksum_valid 1) { raw_data combine_bytes(rx_buf 1, rx_buf 2, rx_buf 3); state CONVERT_TEMP; } else { state IDLE; } break; case CONVERT_TEMP: temp_value raw_data_to_temperature(raw_data); state IDLE; break; } }4.3 温度换算与滤波处理拿到 ADC 的原始码后先根据比例法换算成 RTD 电阻值。假设 ADC 输出码值直接对应 Vrtd/Vref 比例电阻值就是码值除以满量程再乘以 Rref。实际项目中我习惯把满量程码值定义为 2^23 或 2^24根据配置做对应缩放这样误差可控。得到电阻值以后查 RTD 分度表或直接用多项式换算温度。PT100/PT1000 在 0℃ 以上用 Callendar-Van Dusen 公式比较好0℃ 以下需要带 -100℃ 项。很多库函数能直接算但 HVAC 嵌入式系统要省 Flash我一般用查表法加线性插值把 -40℃ 到 150℃ 每 5℃ 建一个电阻表通过二分查找定位区间再做线性插值。精度可以做到 0.05℃ 以内Flash 消耗却很少。滤波方面一阶低通和滑动平均都很好用。系统采样率 20SPS对 HVAC 这种大惯性对象一阶低通的时间常数可以设在 2 到 5 秒。太强的滤波会让温度响应变慢影响控制效果太弱的滤波又会在压缩机启停时出现读数跳动。我在代码里把滤波系数做成参数现场调试时用串口或上位机实时调整非常方便。5. 校准和误差控制5.1 两点校准流程任何 ADC 加上外部电阻、端子、线缆以后都会存在系统误差。校准是必须做的不然芯片规格再好整机精度也可能超标。我最常用的是两点校准法一个低温点一个高温点覆盖实际工作范围。低温点用 0℃ 冰点槽或者精密恒温槽高温点用 100℃ 沸水或者干体炉。把传感器探头放进恒温源等读数稳定十分钟左右记录测量值。假设低温点标准值是 T0、实测值是 M0高温点标准值是 T100、实测值是 M100那么校正公式就是T (M - M0) / (M100 - M0) × (T100 - T0) T0把这个公式固化到固件里校准参数存入 Flash。对于 PT1000如果采用比例法系统增益误差通常很小校准后精度能达到 ±0.2℃ 到 ±0.3℃完全满足大多数 HVAC 要求。需要注意校准和实际使用时传感器的连接方式必须一致如果校准用短引线、现场用长引线线阻带来的误差会原样出现。5.2 温漂、自诊断与补偿温度采集系统的温漂最大来源不是 ADC 芯片而是外部参考电阻和传感器本身。Rref 我选的是 5ppm/℃ 低温漂电阻因为比例法里它是唯一决定精度的基准。PCB 上的焊点和铜箔走线也有温漂但影响相对小。ADC 内部基准已经是低漂移设计日常环境温度变化基本可以忽略。自诊断方面一定要做传感器断线检测。RTD 断了以后ADC 输入悬空读数会乱跳或者指向满量程。利用 IDAC 恒流源在输入通道上接一个上拉或下拉电阻正常测量时电压在一定范围内断线时电压会异常。固件里每过一段时间切换到诊断模式检查电压是否超限超限就置位报警标志。工业现场还常见传感器短路、线缆进水、端子氧化表现为读数偏低且不稳定。我试过在诊断通道上测量一个已知的精密电阻定期和初始值比对偏差超过阈值就通知维护。这个功能在 HVAC 项目中很受欢迎因为屋顶机房、管井里检修困难能远程知道哪一路传感器老化省去很多跑现场的时间。6. 现场问题与排查经验6.1 通信超时先查时序再查波特率和 ADS122U04IPWR 通信遇到最多的故障就是单片机读不到数据。我开始时怀疑芯片坏了后来排查发现八成是时序和配置问题。第一个坑是波特率误差。PIC18F86J10 如果只用内部振荡器出厂精度可能还行但温度变化后误差会超过 UART 允许范围。解决办法是使用外部晶振或者在初始化时用芯片自带的振荡器校准功能。第二个坑是 TX/RX 接反。ADC 的 TX 必须接单片机的 RXADC 的 RX 接单片机的 TX这看起来简单但画原理图时很容易写反。第三个坑是 ADC 上电后还没稳定就立刻发命令。我给 ADC 加了一个上电延时至少等 100ms 再初始化通信稳定很多。如果还是失败用逻辑分析仪抓 UART 波形确认帧头和校验字节是否符合预期。这个方法比盲改代码快得多。我习惯在调试时把 UART 波特率降到 9600降低码元宽度要求往往就能排除一部分信号质量问题。6.2 读数噪声偏大问题往往出在地和滤波现场最典型的问题就是温度读数跳字。表现是转换结果小数点后两位乱跳严重时后一位都跳。遇到这种情况先检查供电和地。如果 ADC 的模拟电源正好接到系统 DCDC 的输出纹波会直接影响转换结果。我在第二版板上给模拟电源专门加了一颗 LDO噪声下降了至少一半。然后是增益和采样率。PGA 增益过高会把噪声一起放大如果信号幅度并不小没必要用 8 倍或 16 倍增益。我之前把 PT1000 信号用 8 倍增益结果噪声明显变大改成 2 倍后信噪比更好。采样率从 1000SPS 降到 20SPS内部数字滤波器把高频噪声压掉读数立刻稳下来。还有前端 R/C 滤波。传感器线长时干扰能量很大单纯靠 ADC 的数字滤波器不一定够。我最终在输入引脚前加了 1kΩ 100nF 的 RC 滤波配合 20SPS读数噪声从 ±5 个字降到 ±1 个字以内换算成温度基本稳定在 ±0.02℃ 附近。6.3 长线传输和现场干扰处理HVAC 机房里变频器一启动温度显示偶尔跳一两度这就是长线耦合了干扰。处理方式分几层。第一层是传感器线用屏蔽线屏蔽层单端接地不要两端都接避免形成地环路。第二层是输入端加 TVS 管防止浪涌打坏 ADC同时串接电阻限制电流。第三层是通信链路隔离。PIC18F86J10 和 ADS122U04IPWR 之间如果距离近通常不需要隔离但传感器长线进入板子时我会在 ADC 前端加共模扼流圈或差分滤波。现场要是还有变频器的高频 PWM 干扰单靠 RC 滤波不够可以考虑在 ADC 和传感器之间加一个输入级有源滤波但成本和板面积都会增加。HVAC 项目中我先用 RC 加屏蔽大部分问题都能解决只有特别恶劣的机组才需要加强措施。最后分享一个我个人的调试习惯在固件里加一条诊断命令能够直接读取 ADC 的原始码和经过换算的温度值同时记录通信错误次数。现场排查时不用猜一条指令就能判断是传感器问题、ADC 问题还是单片机通信问题。这个习惯帮我解决了很多售后问题也让这套 ADS122U04IPWR 加 PIC18F86J10 的方案在实际项目中越用越顺手。