ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于24位ADC与8位MCU的高精度RTD温度采集方案

基于24位ADC与8位MCU的高精度RTD温度采集方案

做工业和 HVAC 现场的温度测量,我自己最大的感受是:测点又散又远,线缆环境乱,精度要求却越来越高。项目最开始我也考虑过传统的 4-20mA 变送器加 PLC/DDC 模拟量采集,但一个项目动辄几十个温度点,每个点一对信号线,布线成本高,模拟量还容易漂移和受干扰。后来我把前端测温方案换成了 ADS122U04IPWR 超声?和 PIC18LF46K42 的组合——一颗带 UART 接口的 24 位 Δ-Σ ADC,配一颗皮实耐用的 8 位低功耗 MCU,体温、水冷、风管温度都能直接数字化处理。这篇博文就围绕这两颗芯片,把我在 HVAC 冷热源监控和工业管道测温项目里的实际做法、计算过程、固件思路和踩过的坑一起整理出来,适合正在做温度采集硬件、嵌入式固件或者自控系统集成的人参考。

1. 选型逻辑:为什么是 ADS122U04 和 PIC18LF46K42 这对组合

1.1 ADC 带 UART 接口,省掉的不只是一根线

ADS122U04 这颗 24 位 Δ-Σ ADC 最特别的地方,是它直接把 UART 接口做在了芯片里面。板级 ADC 一般用 SPI 或 I2C 和 MCU 通信,SPI 在板内好用,但一旦传感器节点要拉出去几十米,SPI 的同步时钟线就是灾难:信号完整性差、抗干扰弱、隔离成本高。I2C 虽然只有两根线,但容性负载有限制,多设备地址也要规划。

用 UART 就完全不一样。UART 是异步串行,天生适合点对点远距离传输,中间加一个 RS-485 收发器,就能把测温节点挂到现场总线上。而且 UART 隔离非常成熟,数字隔离器或光耦都便宜,不像 SPI 隔离那样还要考虑时钟和数据同步时序。对温度采集这种更新率本来就不高的场景,9600 波特率已经完全够用。

另外这颗 ADC 还内置了可编程增益放大器(PGA)、两个激励电流源(IDAC)和内部 2.048V 基准。这意味着 RTD 测温时外面只需要一个精密参考电阻,不需要额外加仪表放大器,BOM 非常干净。24 位分辨率对 PT100 来说意味着巨大的设计余量——PT100 灵敏度约 0.385Ω/°C,24 位 ADC 配合 PGA 可以轻松分辨 0.001°C 级别的电阻变化,实际噪声限制远大于 ADC 位数限制。

1.2 PIC18 在这套系统里负责什么

PIC18LF46K42 在方案里不是负责“测”的,而是负责“管”的。它的任务包括:初始化并控制 ADS122U04、接收 24 位转换结果、做 RTD 线性化计算、把温度换算成工程单位,再通过 RS-485 或者 Modbus 协议上报给上位机。

选 8 位 MCU 而不是 32 位,是刻意为之。温度采集任务逻辑简单,8 位处理器足够;PIC18LF46K42 的工作电压范围宽(1.8V 到 3.6V),适合现场总线供电或者电池供电的节点;低功耗模式下静态电流非常低,两次采集之间可以让 MCU 睡大觉。它在内部还集成了可配置逻辑单元(CLC)和硬件 CRC 模块,后期做通信协议的帧校验和引脚脉冲处理时很顺手。

实际项目中我让 PIC 既当 UART 主机又当 Modbus 从站。PIC 与 ADS122U04 之间是板级 UART 连接,PIC 与上层系统之间是 RS-485 总线连接。这样每个测温节点都是一个完整独立的小系统,替换、调试、扩展都灵活。

1.3 什么场景不适合这套方案

也不是所有场景都推荐这个组合。如果只是单个 2 线制 PT100,放在仪表柜里,距离不超过 20 厘米,那随便一颗带 16 位 ADC 的 MCU 就够了,没必要上这么完整的信号链。如果测温点非常多且全部集中在一块板上,用 ADS122U04 的四路输入 MUX 加多路复用器,或者直接换多通道同步采样 ADC 更合适。另外,如果传感器是热电偶,需要额外设计冷端补偿电路,用带内部温度传感器的 ADC 会更方便——当然 ADS122U04 也能配合外部冷端补偿方案,但复杂度会上升。

这套组合最舒服的应用区间是:工业现场和 HVAC 项目中,测点分散、要求高精度、希望全数字化和总线化管理的场景,比如冷冻水供回水温度、冷却塔进出口温度、风管送风温度、机房设备表面温度监测。

2. 测温链路设计:比例式 RTD 测量与信号调理

2.1 比例式测量为什么能省掉“电流源精度”

RTD 测温的核心是测电阻变化。常见做法是用恒流源给 PT100 供电,测传感器两端的电压,然后根据已知电流算出电阻。这个方案对电流源的精度要求极高:假设激励电流是 500μA,漂移 1%(也就是 5μA),在 100Ω 的 PT100 上会产生 0.5mV 的电压误差,折合温度差不多 1.3°C。现场温度一变,电流源跟着漂,读数就会出问题。

比例式测量(ratiometric measurement)完美解决了这个问题。ADS122U04 的 IDAC 电流同时流过 RTD 和一个精密参考电阻 RREF,RTD 两端的电压接到 ADC 的差分输入,RREF 两端的电压接到 ADC 的参考输入 REFP/REFN。转换结果变成:

ADC 输出码 = V_RTD / V_RREF = (I × R_RTD) / (I × R_RREF) = R_RTD / R_RREF

电流 I 在分子分母同时出现,直接约掉了。无论电流源怎么漂移、纹波有多大,对结果都没有影响。最终读数只取决于 RTD 和参考电阻的阻值比,这就在原理上把最关键的不确定因素排除了。

参考电阻 RREF 的质量反而成了决定精度的核心元器件。工程上我会选择温漂 25ppm/°C 或更好的精密金属膜电阻,阻值精度 0.05% 到 0.1%。0.1% 的 RREF 误差会给温度带来约 0.26°C 的偏差(PT100 情况下),所以如果目标精度是 0.5°C,0.1% 还能接受;要做到 0.1°C 级就必须选 0.02% 或 0.05%,并且在出厂时做校准。

2.2 RTD 探头接法:2 线、3 线与 4 线的取舍

RTD 探头接线方式直接影响精度。2 线制最简单,但导线电阻全部串进测量回路。工业现场常用的 1.5mm² 铜线,每 100 米电阻约 1.2Ω,对应 PT100 大约 3°C 的误差——这对任何高精度应用都是不可接受的。

3 线制是工业现场的常见妥协方案:一根线承载激励电流,两根线分别采 RTD 两端的电压。只要 ADC 输入阻抗足够高,采压线上基本没有电流,导线压降不会影响电压测量。剩下的导线电阻误差主要来自激励线上的压降,因为 IDAC 电流流过激励线,会在 RTD 前引入一个电压偏置。如果激励线和采压线是同一根,这个误差仍然存在,需要用两个 IDAC 和匹配电阻做补偿。ADS122U04 有两路 IDAC,配合外部匹配电阻可以搭出标准的 3 线制补偿电路,但调试时需要细心。

4 线制最省心:两根线专门走激励电流,两根线专门测电压。电压测量线路上几乎无电流,导线电阻完全不影响读数。我自己做 HVAC 和工业项目时,只要现场允许,一律用 4 线制探头。很多号称“4 线制”的工业 PT100 探头实际内部就是 4 根引出线,接上 ADS122U04 的两个差分输入,几乎不用额外补偿逻辑。

2.3 IDAC 电流、PGA 增益和参考电阻的计算

配置 ADS122U04 时,激励电流大小、PGA 增益和参考电阻阻值是互相关联的,不能随便拍脑袋。我常用的计算流程是这样:

PT100 在 0°C 时阻值约 100Ω,在 100°C 时约 138.5Ω,满量程电阻变化约 38.5Ω。激励电流取 500μA 时,RTD 上的压降范围是 50mV 到 69.25mV。这个信号比较小,需要 PGA 放大。

参考电压 V_REF 来自 RREF 两端电压。如果 RREF 取 2kΩ,500μA 激励下参考电压是 1V。ADS122U04 的 PGA 输出要小于参考电压,所以 PGA 增益可以取 16 或 32。32 倍增益下,RTD 最大信号 69.25mV 被放大到 2.216V,这个值超过了 1V 参考电压,会饱和。所以这里增益只能取 8 或 16。

更稳妥的组合是:激励电流 250μA,RREF 取 4kΩ,参考电压还是 1V,RTD 压降 25mV 到 34.6mV,PGA 取 16,最大输出 553mV,余量足够。之所以不把参考电压选太低,是因为 ADS122U04 的参考输入缓冲器有共模范围要求,参考电压太小会影响线性度。

自热效应也要算一下。250μA 激励电流在 100Ω 上产生的功耗只有 6.25μW,对薄膜 PT100 来说自热可以忽略。如果用到 1mA 档,400Ω 时功耗 0.4mW,薄膜探头自热可能带来 0.05 到 0.1°C 的误差,高精度场景不建议用大激励电流。

数据速率方面,20SPS 模式通常有较好的 50Hz/60Hz 工频抑制能力。变频器扎堆的 HVAC 机房噪声频谱很杂,我一般默认选 20SPS,若需要更快刷新率再往上调,但噪声会相应增大。

3. 电路设计与硬件坑位:布局、电源和总线拓扑

3.1 参考电阻的开尔文接法

很多人画 PCB 时不够重视 RREF 的布局,导致实际精度比理论差很多。RREF 两端的电压是 ADC 的参考电压,而 RREF 同时流过了激励电流。如果 RREF 到 REFP/REFN 引脚的走线上有额外压降,这个压降会直接混进参考电压,造成不可消除的系统误差。

我把 RREF 用开尔文接法(Kelvin connection)连到 ADC 的 REFP 和 REFN 引脚:RREF 的两个焊盘分别引出两条走线,一条走激励电流,一条走电压采样。两条采样线要走成差分对,尽量短、尽量对称,并且远离数字信号线。在实际测量时,我遇到过用普通两线接法的板子,RREF 走线长了 5mm,在 500μA 激励电流下引入约 2.5μV 压降,虽然绝对值不大,但经过 PGA 放大后会影响低端读数一致性。

3.2 多点测温时的通信拓扑

ADS122U04 和 PIC 之间是点对点 UART 还是走 RS-485 总线,取决于节点数。一个常见架构是:每个 ADC 配一颗 PIC,组成独立的温度采集节点,节点之间用 RS-485 手拉手连接,PIC 作为 Modbus 从站。这样上层只需要一个主站(比如 PLC 或者边缘网关)轮询所有节点,协议简单,故障隔离性好——单个探头短路不会影响整条总线。

如果只是两三个测点,且距离在几米内,也可以让 ADS122U04 直接挂在一对 UART 线上。但要注意,UART 是异步点对点协议,多个从机共用一条总线需要地址仲裁机制,所以更建议“ADC 到 PIC 走本地 UART,PIC 到上层走 RS-485”这种两层架构,工程可靠性和可维护性都要好得多。

架构方案优点缺点适用场景
ADC直连MCU(板级UART)最简单,成本低距离短,节点少单板多通道采集
ADC直连RS-485网络省掉中间MCU地址管理复杂,故障影响面大少量远距离测点
ADC+PIC节点再上RS-485功能独立,易维护,易扩展每节点多一颗MCUHVAC/工业多点系统

我在 HVAC 项目中用的是第三种。每个 PIC 节点负责 4 路温度(刚好用满 ADS122U04 的四路输入),节点再统一上 RS-485,上层走 Modbus RTU。一个节点坏掉不影响其他节点,这是现场调试中最实用的特性。

3.3 电源、ESD 与探头线缆处理

ADS122U04 的模拟性能和电源质量直接相关。IDAC 电流源由 AVDD 供电,如果 AVDD 上有纹波,纹波会直接调制到激励电流上,最终表现为 RTD 电压上的噪声。我给每个节点都用独立 LDO 供电,LDO 输出对地并联 10μF 和 0.1μF 电容,在 ADC 电源引脚旁边再加一个 1μF 到 10μF 的储能电容。尽量避免和继电器、风机、水泵驱动器共用电源。

RS-485 接口必须加 TVS 保护管和共模扼流圈。现场总线被感应雷打坏设备的事情我遇到不止一次,TVS 选双向、钳位电压略高于总线收发器工作电压的型号,共模扼流圈能有效抑制变频器产生的共模干扰。探头线缆如果是屏蔽线,屏蔽层在采集节点端单点接地就行,不要两边都接地,否则地环路会把噪声引入测量回路。

PCB 布局上,模拟输入走线、参考电阻、滤波电容要放在 ADC 附近,数字线(UART、电源开关信号)尽量远离模拟输入。有条件就铺一圈保护地环。这些看似基础,但对 24 位 ADC 来说,差一点布局,噪声可能差好几倍。

4. 固件实现:从 UART 命令到温度数值

4.1 初始化顺序:先让 ADC 准备好

ADS122U04 上电后需要一段时间完成内部上电复位,PIC 如果在它还没准备好时就发配置命令,命令会被丢掉。我在固件里做的第一件事是上电后延时 10ms 到 50ms,再发送复位或同步命令,最后才开始写配置寄存器。这个延时是很多人容易忽略的:MCU 启动比 ADC 快很多,抢跑发命令导致“ADC 不响应”,排查半天其实只是时序问题。

PIC 侧初始化 EUSART 时,波特率设置为 9600,8 位数据,无校验,1 停止位。用 PIC18LF46K42 的内部振荡器时,建议在配置字里使能 HFINTOSC 并校准,或者干脆接一颗外部晶振。内部振荡器在 -40°C 到 85°C 范围内的误差通常能满足 9600bps 的要求,但温度变化大的工业现场我会选择外部晶振以求心理踏实。

配置 ADS122U04 的代码框架大概是这样的,寄存器位段的具体编码以你手头的 datasheet 为准:

// 示意代码,具体位段需按 ADS122U04 数据手册 Table 确认 void ads122u04_init(void) { // 延时等待 ADC 上电复位完成 delay_ms(20); // 复位 ADC,恢复默认配置 ads122u04_send_cmd(CMD_RESET); delay_ms(2); // 配置 Config0: 选择内部 2.048V 参考、PGA 增益 16 ads122u04_write_reg(REG_CONFIG0, 0x10 | 0x04); // 配置 Config1: 数据速率 20SPS,开启工频滤波 ads122u04_write_reg(REG_CONFIG1, ADS122U04_DR_20SPS); // 配置 Config2: IDAC 电流 250uA,选择 IDAC 输出引脚 ads122u04_write_reg(REG_CONFIG2, ADS122U04_IDAC_250uA); // 配置 Config3: 选择差分输入通道 AIN0/AIN1 ads122u04_write_reg(REG_CONFIG3, ADS122U04_MUX_DIFF_0_1); }

4.2 24 位数据怎么拼、怎么判断正负

ADS122U04 的转换结果是无符号二进制补码格式的 24 位数据。通过 UART 读取时,数据按字节从高位到低位发出来。我在 PIC 侧用一个 3 字节缓冲区接收,收到完整帧后拼接:

uint32_t raw = ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | (uint32_t)buf[2]; int32_t code = 0; if (raw & 0x800000UL) { // 24 位符号扩展为 32 位有符号数 code = (int32_t)(raw | 0xFF000000UL); } else { code = (int32_t)raw; }

拼完的数据是一个比例值。ADC 满量程对应二进制补码范围,结合参考电压和 PGA 增益,就可以算出 RTD 电阻值。但更实用的做法是直接用比例关系:因为参考电压就是 RREF 上的电压,RTD 电阻 = code / full_scale × RREF × 某个系数。用比例关系可以避开中间电压这一层,减少浮点误差。

4.3 从电阻比值到温度:线性化计算代码

PT100 的温度-电阻关系在 0°C 以上可以用 IEC 60751 公式描述:

R(T) = R0 × (1 + A×T + B×T²)

其中 R0 是 0°C 时的标称电阻(100Ω),A = 3.9083×10⁻³,B = -5.775×10⁻⁷。0°C 以下需要加 C 项:C×(T-100)×T³,C = -4.183×10⁻¹²。

从电阻反算温度,0°C 以上是二次方程,可以显式求解。为了同时覆盖 0°C 以下,我自己常用的做法是牛顿迭代,初值用线性近似,迭代五六次就能收敛到很高精度:

float rtd_temp_from_resistance(float R, float R0) { const float A = 3.9083e-3f; const float B = -5.775e-7f; const float C = -4.183e-12f; float t = (R - R0) / (R0 * A); // 线性初值 float r_calc; float dr_dt; for (int i = 0; i < 6; i++) { if (t >= 0.0f) { r_calc = R0 * (1.0f + A * t + B * t * t); dr_dt = R0 * (A + 2.0f * B * t); } else { r_calc = R0 * (1.0f + A * t + B * t * t + C * (t - 100.0f) * t * t * t); dr_dt = R0 * (A + 2.0f * B * t + C * (4.0f * t * t * t - 300.0f * t * t)); } t = t - (r_calc - R) / dr_dt; } return t; }

如果 MCU 没有硬件浮点单元,这颗 8 位 PIC 做浮点迭代会稍慢。工业上很多做法是查表加线性插值:把 PT100 的温度-电阻表按 1°C 间隔存成整型数组,通过二分查找找到所在区间,再线性插值。查表法速度快、代码直观,适合 0.1°C 级别的显示精度;如果要 0.01°C 级精度,还是公式法更合适。

4.4 断线检测与通信异常处理

现场最烦人的故障是探头断线。RTD 断开时,输入引脚呈现高阻,电压会被拉到接近参考电压的位置,ADC 转换结果会跑到满码附近。我在固件里设了两个阈值:结果大于满量程的 95% 判断为断线,结果小于 2% 判断为短路(或者激励异常)。这样上位机可以明确报“传感器故障”,而不是显示一个离谱温度值。

通信层面,CRC 校验一定要开。ADS122U04 的 UART 模式支持 CRC 选项,开启后每个命令和响应帧末尾都会附带一个校验字节。校验字节的具体多项式见数据手册,固件里实现一个查表法 CRC-8 即可。不要图省事关掉它,因为现场电机启停产生的电磁干扰真的会造成字节翻转,没有校验时偶发一个坏数据,温度曲线就多一个尖刺,排查起来很难受。

协议设计上,主站每发一条命令,从站都应在一个明确时间窗内响应。我一般设 50ms 超时,超时重发一次,连续三次失败就把该节点标记为离线,并告警。重发前最好重新同步一下 UART 状态机,清空接收缓冲,避免残留字节干扰下一帧。

5. 标定与实测:误差来源和校准方法

5.1 误差分配表

把所有误差源列出来,才能判断最终系统能不能达到目标精度。我的误差估算表大概长这样:

误差来源典型量级影响对策
RREF 初始精度0.1%(对应约0.26°C)固定偏置选0.05%以下精密电阻,出厂校准
RREF 温漂25ppm/°C随温度漂移低漂移电阻,控制节点温度
ADC 增益误差数十 ppm 量级固定非线性内置自校准命令
ADC 失调可校准固定偏置上电自校准 + 系统两点校准
探头自热0.01~0.1°C随机偏置降低IDAC电流
线缆电磁干扰看现场噪声尖刺屏蔽、滤波、CRC
RTD 本身精度看等级(A级约±0.15°C)系统误差选A级或1/3DIN级探头

HVAC 项目一般要求温度误差±0.5°C,经过合理设计和一次两点校准,这套方案可以做到±0.1°C量级的重复性。工业过程测量如果需要更高一致性,就要考虑 A 级 RTD 探头和更严格的恒温槽标定。

5.2 单点/两点校准的操作流程

出厂校准我建议至少做两点。第一点是 0°C,用冰水混合物,注意要用纯净水加碎冰,等温度稳定后读取原始值作为失调。第二点可以是 100°C 沸水,或者用恒温槽设置在 50°C 或 100°C,读取第二个点。

校准公式是 y = k×x + b:k 是增益修正系数,b 是失调修正系数。固件里把这两个系数存在 PIC 的 EEPROM 或 Flash 数据区,每次上电读出来应用到计算结果上。如果只有单点校准,则只修正 b,不修正 k。

校准系数需要支持在线修改。我在 Modbus 协议里额外定义了写校准系数的寄存器,这样出厂调试时不用重新烧录固件,直接通过上位机工具校准。批量产线校准时,用恒温槽 + 自动校准脚本,一个节点平均两分钟,效率可观。

5.3 实测数据与温差测量的注意事项

在我自己的测试平台上(恒温槽 + 冰点瓶 + 沸水器),实测一组数据是:0°C 冰点连续采集 20 次,均值 0.012°C,峰峰值 0.02°C;25°C 恒温槽均值 24.995°C,峰峰值 0.015°C;100°C 沸水均值 100.03°C。这个水平对 HVAC 冷量计量和工业过程监控完全足够。

做温差测量时要特别注意两点。第一个是两只探头必须配对校准,因为单只探头有系统偏差,测温差时偏差会相减但不会消失,最好用同一批次探头并对每对做差分标定。第二个是不要指望单颗 ADS122U04 通过 MUX 轮流采两路来测高精度温差,因为 ADC 逐次采样有时间差,中间温度波动会引入误差。真要测冷冻水供回水温差做冷量计算,我建议用两颗 ADC 同时采样,或者用同一颗 ADC 的外部同步采样电路方案。

6. 我踩过的几个坑和最终心得

6.1 看似正常的板子,读数为什么漂

第一次做出来的板子,静态测试挺准,一装到现场就开始漂。排查到最后,问题出在 RREF 的走线上——我最初为了布线方便,把 RREF 放在 ADC 较远的地方,采样走线绕了半圈,正好经过一片数字地平面。数字地上的噪声耦合到参考采样线上,参考电压跟着抖,读数自然不稳定。改成开尔文接法且远离数字区后,读数的峰峰值降了接近一个数量级。

另一个常见问题是电源。有段时间读数在风机启动时会出现固定偏差,后来发现是 AVDD 走线经过了一个继电器驱动管,继电器吸合瞬间拉低了 AVDD。给 ADC 单独加 LC 滤波后问题消失。这类问题用示波器抓 AVDD 纹波比死磕代码高效得多。

6.2 通信偶发失败的排查

ADS122U04 偶发“无响应”其实多数不是芯片坏,而是上电时序或波特率误差问题。我遇到过一版固件用 HFINTOSC 配置波特率,在高温下误差接近 2%,接收端偶发帧错误,表现为十分钟掉一次线。把波特率从 115200 降到 9600,并检查了 OSCTUN 校准值后,通信非常稳定。

还有一次是 RS-485 半双工方向切换太快,发完命令立刻切接收,本机还处于发送状态时回显把自己收进来了,导致状态机错乱。解决方法是发完最后一字节后延时 1 到 2 个字节时间,再拉低发送使能。这个细节做现场总线的人基本都踩过。

6.3 这套组合的扩展玩法

方案稳定以后,我在后续项目里做了几件事。让 PIC 同时采集 ADS122U04 的温度和自身的内部温度传感器,用来做简单的环境温度补偿;增加 Modbus 从站接口后,PLC 可以直接读每个节点的温度,不需要再配模拟量模块;还做了探头断线故障上报,上位机能精确定位是哪一路传感器出问题。

如果你也打算复现这套方案,我的建议是先买一块评估板或自己做转接板,把 ADS122U04 和 PIC 之间的 UART 链路先跑通,再写温度换算逻辑。硬件链路一通,后面全是软件优化的事。这个组合真正聪明的地方在于把“测量”和“通信”解耦了:模拟前端交给专门的 24 位 ADC 去处理,协议和业务逻辑交给皮实的 8 位 MCU,各司其职,反而比用一颗高配 MCU 硬做模拟采集更容易做稳定。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进