
做工业测控这些年温度测量永远是最常见也最考验基本功的环节。手头正好落地过一套实际方案用 TI 的 ADS122U04IPWR 这颗 24 位 Δ-Σ ADC内置 PGA、激励电流源带 UART 接口搭配 Microchip 的 PIC18F57Q43 单片机专门处理工业和 HVAC 场景下的温度采集。这篇文章就把这个方案的完整设计过程、硬件电路、固件算法、抗干扰处理以及调试中踩过的坑都摊开讲一遍。如果你准备做 HVAC 温度控制器、工业 RTD 变送器或者想找一套性价比够高、精度能打的前端数据采集架构这篇应该能省下不少摸索时间。这套组合的精髓是分工明确ADC 干模拟前端最脏最累的活把微弱电压信号变成稳定数字量单片机则负责通信时序、数学换算、控制逻辑顺便把数据通过 RS485、Modbus 或 PWM 输出去。ADS122U04IPWR 的“U”后缀代表 UART 接口正好能省掉传统 SPI 的接线和时序开销对 8 位 MCU 非常友好。1. 方案解析ADS122U04IPWR 和 PIC18F57Q43 为什么这么搭1.1 温度测量场景的两类典型需求工业测温和 HVAC 测温看起来都是“测温度”但实际需求差别很大选型之前必须先把需求理清楚。先看 HVAC 场景。楼宇自控里的温度点很多回风温度、送风温度、盘管温度、压缩机的吸排气温度、室外补偿温度。温度范围一般不算极端-40°C 到 150°C 基本覆盖但成本非常敏感而且现场干扰复杂——风机启停、压缩机启动、可控硅调压都会带来强烈的电磁干扰。这类产品通常还要和楼宇自控系统通信协议五花八门不少是老旧的 UART/RS485 总线。再看工业场景。化工、电力、制药这些行业更看重长期稳定性和可追溯性RTD 尤其是 Pt100 是绝对主力。量程可以到 -200°C 到 850°C精度要求经常是 ±0.1°C 甚至更高。现场往往有长线缆、变频器、大电机变压器地电位不干净。仪表一般需要 24V 供电同时输出 4-20mA 电流环和 RS485 Modbus。这两类需求放一起就会得出一个典型硬件画像一个高分辨率 ADC 前端外加一个足够处理通信和逻辑控制的 MCU。而 ADS122U04IPWR PIC18F57Q43 正好就站在这个交叉点上。1.2 ADS122U04IPWR 的核心优势ADS122U04 是 TI 新一代 24 位增量-总和Δ-ΣADC它最吸引我的是三个点。第一内置可编程增益放大器PGA增益可以做到 1 到 128。测 RTD 时Pt100 在 0°C 下只有 100Ω如果用 500μA 激励电流压降只有 50mV 左右没有 PGA 根本没法用。增益放大器把微伏级信号放大后再采样那 24 位分辨率才算真正有意义。第二内置两个可编程激励电流源IDAC。测电阻类传感器最怕激励电流漂移而 ADC 的跳码恰恰跟电流有关。如果激励电流和参考电压来自同一个电流源那电流的变化在分子分母上同时抵消这就叫“比率测量”。ADS122U04 的 IDAC 天生就是干这个的不用外加恒流源电路。第三UART 接口。这对于 PIC18 这种 8 位 MCU 是大优势。SPI 要接片选、时钟、数据线还得用 GPIO 模拟或硬件 SPI而 UART 只需要两根线TX/RX就够了。很多 HVAC 主板上还有一些隔离要求UART 也更容易做光耦隔离。ADS122U04 还带内部温度传感器做热电偶冷端补偿时可以作为参考依据。1.3 PIC18F57Q43 承担的角色PIC18F57Q43 是 Microchip 新一代 8 位 MCU虽然叫“8 位”但外设一点不寒酸。它有两个 EUSART、一个 SPI、一个 I2C、两个可配置逻辑单元CLC、多个 PWM 定时器、ADC、DMA 类似的外设接口还有硬件看门狗。用在这套方案里它做的事情其实不复杂但很关键初始化并控制 ADS122U04收发 UART 命令解析 24 位 ADC 数据换算成电阻再计算出温度做数字滤波和线性化消除噪声跑 PID 或者其他控制逻辑输出 PWM 控制风机/加热通过另一个 UART 接 RS485 收发器跑 Modbus 协议上报温度。有人会问为什么不用 STM32 这种 32 位 MCU答案是没必要。温度采集不是速度密集任务20SPS 的采样率就够用了。PIC18F57Q43 在 64MHz 下跑浮点温度换算完全没问题成本还低XC8 编译器免费版就够用。供应链上 Microchip 的 8 位产品生命周期长、供货稳定这对做产品的团队是很重要的考量。2. 硬件设计实战从传感探头到 ADC 外围电路2.1 传感器选择NTC、Pt100、Pt1000 还是热电偶先泼一盆冷水ADS122U04 再高级也救不了传感器本身。选错传感器后面怎么调都白搭。传感器类型典型量程常温精度成本适用场景NTC 热敏电阻-40~150°C±0.5~1°C很低HVAC 回风/送风温度Pt100-200~850°C±0.1~0.3°C中工业过程、盘管温度Pt1000-50~300°C±0.1~0.3°C中高HVAC 精密点、医疗K 型热电偶0~1100°C±1~2°C低工业高温排气、压缩机排气我在 HVAC 项目里最常用的组合是常规温度点用 NTC 10K防冻保护点和盘管温度用 Pt1000压缩机排气温用 K 型热电偶或 Pt100。因为 NTC 响应快、便宜但老化后会漂移只能用在控制精度要求不高的地方。Pt1000 比 Pt100 信号幅度大十倍用 250μA 激励时电压更充足PGA 压力小适合走线不长但精度要求更高的场景。工业场景则基本是 Pt100 三线制这是行业标准。2.2 RTD 测温原理与引线补偿RTD 测温的本质是利用金属电阻随温度变化的关系来反推温度。Pt100 在 0°C 时电阻为 100Ω温度每升高 1°C电阻大约增加 0.385Ω。但这个关系不是纯粹线性工程上常用 Callendar-Van Dusen 方程描述R(T) R0 × (1 A·T B·T²)其中 A 约 3.9083×10⁻³B 约 -5.775×10⁻⁷0°C 以上。所以固件里不能简单做一个“电阻→温度”的线性算式更通用的做法是查表和插值或者用上面的多项式迭代求解。RTD 最坑的是引线电阻。如果只是用两线制把 RTD 接进 ADC那 1 米线缆可能就有 0.1Ω 到 0.5Ω 的电阻折合温度误差就是 0.3°C 到 1.3°C。解决办法有三线制、四线制。ADS122U04 支持四线制比例测量但工业现场为了省线材绝大多数用三线制。三线制实测的接线逻辑是第一根引线给 RTD 送激励电流第二根引线接回 ADC 输入的负端第三根引线再接一路 IDAC 去补偿引线压降。关键点就在于同一路 IDAC 的电流同时流过精密参考电阻 Rref 和 RTD而 ADC 转换得到的是两者电压的比例跟电流绝对值无关。只要引线电阻被对称地抵消掉读到的比例就是真实的 RTD 电阻与 Rref 之比。2.3 激励电流与参考电阻设计这里是整个硬件设计的核心数学我把计算过程列出来。假设目标量程为 -50°C 到 300°CPt100 在该区间电阻约 80.31Ω 到 212.02Ω。选激励电流 IEXC 500μA则 RTD 上的最大电压为Vmax 212.02Ω × 500μA ≈ 106mV为了留出信号余量PGA 增益选 8。ADS122U04 在 PGA8 时满量程输入范围约 ±256mV以内部 2.048V 基准换算106mV 不到一半的量程但已经足够信噪比也好。如果选 PGA16满量程只有 ±128mV106mV 顶得太满一旦线缆引入一点共模干扰就容易超量程所以我不推荐在宽量程场景用高增益。参考电阻 Rref 的选择用一个公式直接算Rref VREF / IEXC 2.048V / 500μA 4096Ω选一个 0.1% 精度、温漂 10ppm/°C 的 4.096kΩ 精密电阻即可。这样激励电流流过 Rref 时产生 2.048V 参考电压和 ADC 内部参考满幅一致整个量程利用率最高。关于激励电流和自热误差这里必须提到一个容易忽略的问题电流越大信号幅度越大对 ADC 有利但电流流过 RTD 本身会产生热量导致温度测量往上偏。Pt100 的自热系数一般在 0.01~0.05°C/mW 之间500μA 在 212Ω 上消耗约 0.053mW自热误差通常小于 0.01°C可以接受。但如果你做的是高精度计量最好把激励电流降到 250μA代价是需要把 PGA 提高到 16。2.4 周边电路、保护器件与 PCB 布局ADS122U04 数据手册推荐在每个模拟输入端串一个 RC 滤波这不仅是抗干扰更是为了配合 Δ-Σ ADC 内部的开关电容结构。实测下来串联电阻建议取 10Ω 到 100Ω对地电容取 1nF 到 10nF过大的电容会导致 ADC 采样建立时间不够反而引入误差。输入端要加 ESD/TVS 保护器件。工业现场长线缆感应雷击浪涌是常态虽然 TVS 不能完全挡住传导瞬变但至少能把 ADC 输入扛到 2kV ESD 级别。保护器件要放在靠近接口端子的位置串阻在保护器件和 ADC 输入之间这样 TVS 泄放电流不会直接流过 ADC 内部。电源方面HVAC 场景常是 24VAC 供电整流滤波后必须加 LDO。ADS122U04 的模拟电源 AVDD 建议由 LDO 单独供给数字电源 DVDD 可以和 MCU 共用但中间要穿磁珠。我习惯在 AVDD 引脚放一个 10μF 钽电容加一个 0.1μF 陶瓷电容靠近引脚放置地回流直接进模拟地。PCB 布局有一条铁律模拟输入走线必须短、对称、差分处理。RTD 的两根信号线要并行走不要跨分割底下完整铺模拟地。参考电阻 Rref 要离 ADC 引脚尽可能近因为它两端的电压直接就是 ADC 的基准走线长了会感应噪声。如果把 Rref 放在板子远端然后走很长的线到 REFP/REFN那精度直接报废。3. 固件与算法把模拟信号变成稳定温度值3.1 UART 通信与命令时序ADS122U04 的 UART 接口和传统 UART 器件有个差别它是“命令响应式”的主机发命令ADC 回数据或回寄存器内容。通信波特率我一般在 9600 或 19200足够支撑 20SPS 的转换输出。调试的时候有几个经验。第一先把使能/片选脚拉低把 ADC 从低功耗休眠状态唤醒。第二初始化完成后一定要做一次寄存器回读校验防止命令帧因为上电时序没对齐而丢字节。第三也是最重要的不要盲目用定时器去读数据要用 DRDY 引脚作为中断或轮询信号。DRDY 在 ADS122U04 上是转换结果就绪的标志拉低时表示新数据可读。我在固件里做了个简单的状态机DRDY 变低后给 ADC 发一个读取命令然后接收 3 个字节的数据和 1 个状态字节。状态字节里的故障标志非常有用比如传感器开路或基准超范围都会在里面反映固件里每帧都要检查。3.2 初始化配置参考下面这段初始化逻辑是我实际用的XC8 编译器下编译通过。具体寄存器的位域定义建议以 TI 数据手册为准我这里写的是配置思路和检查点。void ADS122U04_Init(void) { // 1. 拉低使能引脚等待稳定 CS_EN 0; __delay_ms(10); // 2. 发送软复位命令重新同步内部状态机 ADS122U04_SendCommand(CMD_RESET); __delay_ms(10); // 3. 写 CONFIG0-CONFIG3 // CONFIG0选择输入通道、启用 PGA // CONFIG1连续转换模式数据速率 20SPS // CONFIG2外部参考电压、激励电流 500uA // CONFIG3IDAC 路由到指定引脚、其它额外开关 ADS122U04_WriteReg(REG_CONFIG0, 0x??); ADS122U04_WriteReg(REG_CONFIG1, 0x??); ADS122U04_WriteReg(REG_CONFIG2, 0x??); ADS122U04_WriteReg(REG_CONFIG3, 0x??); // 4. 回读校验 if (ADS122U04_ReadReg(REG_CONFIG0) ! 0x??) { ErrorHandler(ERR_ADC_CFG); } }我没有把所有寄存器的数值写死因为具体值取决于你的传感器类型和量程。但有一个调试建议第一次上电时把 CONFIG0 的转换模式设为单次转换one-shot先把一帧数据读出来确认通信链路通了再切到连续转换。这样排查问题会快很多。3.3 数据读取与温度换算读取 24 位数据的核心问题之一是符号处理。ADS122U04 支持双极性输入输出可能需要补码处理。我统一按补码解析先判断最高位如果是 1 就用负值计算避免在负数温度时出现跳码。拿到补码后按比率测量计算 RTD 电阻R_RTD (ADC_Code / (2^23 - 1)) × Rref因为 ADS122U04 的比例输出等于 RTD 电阻与参考电阻的比值所以激励电流的绝对值在这个式子里消失了这就是选择 IDAC 做激励的最大意义。得到电阻值后我用二分查找在 Pt100 的电阻-温度表里插值。查表比纯多项式更可靠因为对全量程的线性误差控制得更好。下面是一段简化示例double RTD_To_Temperature(double resistance) { uint8_t lo 0, hi 90; // 查找表索引对应 -200~700°C // 二分查找找到相邻的两个表项 while (hi - lo 1) { uint8_t mid (lo hi) / 2; if (lookup_R[mid] resistance) lo mid; else hi mid; } // 线性插值 double t0 -200.0 lo * 10.0; double r0 lookup_R[lo]; double r1 lookup_R[hi]; return t0 (resistance - r0) / (r1 - r0) * 10.0; }实际产品里我会把查表间隔改成 5°C 甚至 1°C再配合校准偏差修正温度准确度能到 ±0.1°C 以内。3.4 数字滤波与联动控制单次 ADC 读数不可能直接用20SPS 下依然能看到个位数到十几位的峰峰噪声。软件上我常用的组合是中值滤波做脉冲剔除再接滑动平均。#define FILTER_LEN 8 uint32_t filter_buf[FILTER_LEN]; uint8_t filter_idx 0; uint32_t DigitalFilter(uint32_t raw) { filter_buf[filter_idx] raw; filter_idx (filter_idx 1) % FILTER_LEN; // 复制排序剔除最大最小 uint32_t sorted[FILTER_LEN]; memcpy(sorted, filter_buf, sizeof(sorted)); // 冒泡排序8个元素足够快 for (uint8_t i 0; i FILTER_LEN - 1; i) for (uint8_t j 0; j FILTER_LEN - 1 - i; j) if (sorted[j] sorted[j 1]) swap(sorted[j], sorted[j 1]); uint32_t sum 0; for (uint8_t i 2; i FILTER_LEN - 2; i) sum sorted[i]; return sum / (FILTER_LEN - 4); }之所以要剔除最大值和最小值是因为现场会有脉冲型干扰比如可控硅导通瞬间挤压到模拟前端产生一个异常大的跳码。如果不过滤PID 控制器就会被这一跳吓一跳风机忽快忽慢用户体验非常差。温度值滤波后再进 PID 控制。HVAC 场景的控制周期一般取 100ms 到 500ms20SPS 的采样率配合 8 点平均完全跟得上。PIC18F57Q43 的 PWM 模块可以直接驱动风机调速或加热器功率控制一个芯片就把采集、控制、通信都办了。4. 系统级可靠性工业现场真正的考验4.1 供电与地电位问题很多人在实验室调好板子一到现场就翻车。最大的问题往往不在 ADC而在供电和地。HVAC 主板上常有一个 24VAC 次级绕组同时给继电器、风机、控制板供电。继电器吸合瞬间有比较大的电流浪涌地电位会瞬间抖动几十到上百毫伏。温度信号本身是毫伏级这点地弹就足以把 24 位 ADC 淹没。解决思路是把模拟前端供电和数字逻辑供电彻底分开用 LDO 单独给 ADS122U04 的 AVDD 供去耦电容加大同时 ADC 的地单点连接到 MCU 的数字地避免继电器大电流回流经过 ADC 的地路径。还有一种做法是加小功率隔离 DC-DC把模拟前端完全浮起来但成本会上升HVAC 量大的产品不一定适合。工业场景则建议直接隔离RTD 模拟前端和 MCU 数字侧用数字隔离器隔开UART 两根线穿隔离。这样即使现场地电位乱跳也不会烧 MCU。4.2 长线缆、EMC 与 ESD工业现场从传感器到仪表常有三五十米线。这类长线主要被 RF、变频器谐波、感性负载启停干扰。硬件上能做的有限但一定要做对。首先RTD 信号线用屏蔽双绞线屏蔽层在仪表侧单端接地不要两端都接以免形成地环路。其次在 ADC 输入端串 100Ω 到 1kΩ 的电阻视传感器类型和精度要求定太大会影响信号建立和线阻补偿并到地加 TVS。最后软件上要把丢帧、异常帧、超时都处理掉不要因为一帧坏数据就把 PID 输出打到极端。ADS122U04 内部的数字滤波器对 50Hz/60Hz 有天然的凹陷特性选 20SPS 或 5SPS 的数据速率能获得较好的工频抑制。如果现场干扰特别严重把数据速率降一档噪声能显著下降。4.3 校准、自检与故障诊断温度测量如果只靠 ADC 本身的精度长期下来是不够的。我习惯在产品出厂前做两点校准一个零点基准一个高档基准。用精密电阻箱模拟 0°C 和 100°C 时 Pt100 的电阻值分别记录 ADC 原始码算出增益系数和零点偏移存到 PIC 的 EEPROM 里。设备每次上电读出来温度换算时叠加这个修正。ADS122U04 也支持自诊断。固件里要定期做以下四件事检查状态字节的故障标志传感器断线检测PT100 开路时激励电流无法形成回路输入会偏到某个固定值一旦发现这个特征就报警ADC 自检命令定期执行把偏移误差校准掉读取内部温度传感器至少用于判断板温是否异常。这套自检机制在 HVAC 项目里特别有用。压缩机排气温度传感器一旦断线如果不报警而继续让压缩机运行可能造成更大损坏。4.4 看门狗与通信异常恢复PIC18F57Q43 的硬件看门狗开着别关。ADC 的 UART 通信也要做超时重试。我在代码里每发一帧命令都启动一个超时计数器如果 10ms 内没有收到响应或 DRDY 没变化就重发命令连续 5 次失败就软复位 ADC。实操中还有一个经验不要一遇到通信异常就反复复位 ADC。有些复位命令需要特定时序反而会让 MCU 阻塞在这里。更稳妥的做法是先重新拉一次使能脚等待 ADC 上电完成再做一次寄存器回读如果没有错误就继续往下跑。5. 常见问题速查与调试心得5.1 症状-原因-对策速查表症状可能原因解决对策读数乱跳波动超过 ±0.5°C电源纹波、输入滤波不匹配、PGA 过高加大去耦电容检查 RC 时间常数确认 PGA 是否留有余量读数稳定但整体偏移大参考电阻精度低、校准系数丢失换成 0.1%/10ppm 电阻重新两点校准读数为满幅 0xFFFFFF传感器断线或输入超量程检查 RTD 接线查看激励电流回路是否闭合UART 偶发丢字节波特率误差、通信线过长、干扰用外部晶振或校准内部振荡器降低波特率到 9600温度响应明显慢输入电容过大、滤波窗口太长平衡 RC 截止频率和数字滤波长度不要过度滤波同一传感器换块板读数不同Rref 温漂/替换批次、校准系数不一致开机读取或统一烧写校准系数使用低温漂 Rref5.2 调试现场的几个关键观察点调试时别急着看温度值先把几个底层信号看明白。第一看 DRDY 波形。用示波器抓 DRDY 引脚正常情况应该以稳定的周期拉低。如果波形忽长忽短说明 ADC 配置或时钟有问题先解决这个再谈温度精度。第二看 UART 波形。确认波特率是否准确帧格式有没有错位。我遇到过 PIC18 内部振荡器校准不到位UART 在高温时偶发误码的问题后来切换到外部晶振才彻底消除。第三看原始码的噪声分布。把 ADC 原始码直接打印出来连续采 1000 个点看峰峰值和分布形态。如果噪声呈现“阶梯状”而不是随机分布往往是 PGA 或滤波器配置有问题如果是周期性脉冲大概率是某个 PWM 或继电器干扰。5.3 独家经验与避坑技巧做这套方案的几轮迭代里有几个坑值得单独记下来。激励电流的档位不要迷信数据手册的最大值。实测下来Pt100 用 500μA、Pt1000 用 250μA 是比较稳妥的组合。电流大了确实信号强、信噪比好但自热误差和传感器老化速度都会增加。对 HVAC 这种要长期稳定运行的产品宁可把 PGA 调高一档也不要把激励电流调得过大。还有一个非常容易被忽视的细节Rref 电阻的温漂比 ADC 本身的增益温漂影响更大。一块板子在室温校准很准拿到太阳底下暴晒后读数偏高第一个怀疑对象就是 Rref 的温度系数。选型时不要省这几毛钱0.1% 精度、10ppm 温漂是最低底线。调试阶段还有一个操作习惯不要用示波器探头直接去戳 ADC 的输入引脚。ADC 前端是高阻抗差分输入探头电容会把电压拉歪导致读数瞬间漂移你还会以为电路有问题。正确的做法是留出 TP 测试点或者用高阻抗差分探头甚至先把 ADC 焊下来单独测传感器电阻。最后是软件层面的一个习惯ADC 读数和温度换算之间中间结果不要只用 float必要时用 double 保存比例值。24 位 ADC 的比例计算如果用 16 位变量做中间量一旦超范围就全是错。我早期踩过这个坑32 位 MCU 上没问题换到 PIC18 这种 8 位机上 float 丢了精度温度在 300°C 附近差了 0.6°C排查到后来才发现是中间变量类型的问题。做温测板这么多年我越来越觉得一颗好的 ADC 只决定了这个方案的“上限”在哪真正决定产品最终精度的是激励电流、参考电阻、PCB 布局和校准流程。ADS122U04IPWR 和 PIC18F57Q43 这套组合上限足够高成本又足够低做 HVAC 控制器和工业温度变送器都非常合适。如果你正准备搭一个类似的最小系统我的建议很简单先把 ADC 的原始码裸读出来别急着写 PID 和控制逻辑把裸码的稳定性调到最好后面的所有功能都会顺理成章地稳定下来。