做工业温控设备那几年最头疼的不是控制逻辑而是温度读数“飘”。明明传感器没动显示值却来回跳个零点几度换了几版电路、加了几次滤波始终治标不治本。后来我把前端换成了ADS122U04IPWR这颗带 UART 接口的 24 位 ADC结合PIC18F85J50做主控整套温度测量热电偶和 RTD 都支持才算真正稳下来。这套组合具体能做什么简单说就是传感器输出的微伏级或毫伏级信号进 ADS122U04 内部的可编程增益放大器由 24 位 Δ-Σ ADC 完成转换再通过 UART 把数字量丢给 PIC18F85J50最后在 MCU 里做线性化、冷端补偿和滤波输出一个稳定可用的温度值。工业设备里的电机过热保护、压缩机排气温度、HVAC 的风管温度和水系统温度都属于典型场景。如果你正在做板级温度采集又不想上昂贵的 PLC 模拟量模块这篇文章值得看完。我会把选型逻辑、硬件细节、固件驱动、温度换算和标定流程全部摊开讲包括我实际踩过的坑。1. 方案选型的底层逻辑为什么要外挂 24 位 ADC1.1 两颗芯片各自的身份定位ADS122U04IPWR 是 TI 推出的一款 24 位 Δ-Σ 型 ADCTSSOP-16 封装工业级温度范围。它最特别的地方是接口不是 SPI 也不是 I2C而是 UART。芯片内部集成了一路可编程增益放大器PGA、内部基准电压、两个可配置的激励电流源IDAC、一个片上温度传感器还内置了 50Hz/60Hz 工频抑制滤波器。这些特性让它天生就是为传感器信号采集设计的。PIC18F85J50 则是 Microchip 的 8 位 MCU80 引脚3.3V 供电内部外设丰富UART、SPI、I2C、定时器都很齐全运行温度范围宽工业现场长期运行的口碑也不错。之所以选它除了供货稳定、开发工具成熟之外还有一个实际原因在 HVAC 控制器这类设备里7 段式管理逻辑、风机盘管控制、Modbus 从机协议这些任务用 8 位 MCU 完全够用不必为了一个温度采集把主控升级到 32 位平台BOM 成本和软件复杂度都会显著上升。1.2 MCU 内置 ADC 为什么不够用很多人会问PIC18F85J50 内部不是也有 12 位 ADC 吗直接采样不行吗我的回答是做粗测可以做工业级温度采集不够。算一笔账就清楚了。K 型热电偶的灵敏度大概是 40μV/℃如果要分辨 0.5℃就需要识别 20μV 的电压变化。MCU 内置 12 位 ADC参考电压取 2.5V 的话一个 LSB 是 2.5V / 4096 ≈ 610μV。610μV 对应热电偶大约 15℃相当于你看到每一个数字跳动温度会跳超过十度。就算把参考电压降到 1V一个 LSB 也还有 244μV换算成温度依然是 6℃ 的量化台阶。而 ADS122U04 在 PGA 增益设为 128 时满量程约 ±2.048V / 128 ±16mV24 位分辨率理想情况下一个 LSB 约为 1.9nV 等效输入单看量化能力就完全不在一个量级。虽然实际噪声会让有效位数打折但做到 0.1℃ 分辨率和 0.5℃ 以内的重复性外置高分辨率 ADC 是必要的。1.3 用 UART 接口 ADC 的真正原因ADS122U04 在 ADS1220 系列里算是个“异类”因为这一系大多是 SPI 接口。我专门选 UART 版本有几个现实考量抗干扰和传输距离。UART 是异步差分电平逻辑只要波特率不高普通 PCB 走线和短距离排线连接都很稳。而 SPI 的时钟线和数据线在电磁环境差的工业现场容易受串扰也需要更多注意。布线简单、引脚占用少。SPI 接口至少要 SCLK、MOSI、MISO、CS 四根线UART 只需要 TX、RX 两根MCU 引脚资源被大量通信任务占掉时这个优势很明显。支持多设备组网。ADS122U04 有两个地址引脚可以在同一条 UART 总线上挂多个 ADC主机通过地址命令区分设备。在需要扩展多路温度采集的 HVAC 控制箱里这个特性非常实用。MCU 端软件负担低。PIC18 的 UART 模块非常成熟寄存器配置简单不像 SPI 从机模式还要时刻关注时钟极性和相位。我的结论很简单适合比新潮更重要。UART 接口在这个场景里不是技术倒退而是把复杂度和可靠性权衡之后的最优解。2. 传感器侧的关键选择热电偶还是 RTD冷端补偿怎么搭2.1 工业现场热电偶HVAC 水系统 RTD标题里同时提到工业和 HVAC这两类场景需要的传感器完全不同。工业设备里压缩机排气温度、电机绕组温度、管道外壁温度用 K 型热电偶最常见因为测温范围宽-200℃ ~ 1370℃ 上限、响应快、价格便宜而且传感器探头结构简单可以做成各种形状贴在设备表面。HVAC 系统里新风机组、冷冻水供水/回水温度、冷凝器管温用 PT100 或 PT1000 铂电阻更合适。RTD 的优点是线性度好、长期稳定性高虽然测温范围通常在 -50℃ ~ 300℃ 以内但这个范围完全覆盖了常规暖通空调场景。PT1000 比 PT100 多了 10 倍阻值同样的激励电流下信号幅度更大对引线电阻的容忍度也更高所以近年 HVAC 控制板越来越偏爱 PT1000。ADS122U04 的输入通道支持 2 路差分或 4 路单端。我的习惯是热电偶一律走差分输入RTD 也尽量走差分输入这样共模干扰会被 ADC 的差分结构抵消掉测量稳定性明显优于单端接法。2.2 PGA 增益和激励电流的配置思路传感器信号幅度差异很大热电偶在常温附近只有几毫伏而 PT1000 在 0℃ 时阻值 1000Ω给 500μA 激励电流时压降是 500mV。这两种信号不能共用同一组增益设置。我的配置经验热电偶通道PGA 增益设为 64 或 128。K 型热电偶在 0℃ 到 1000℃ 范围最大输出约 41mV配合增益 64 时满量程约 64mV刚好覆盖如果只用 0℃ 到 200℃ 的 HVAC 场景可以设到 128信号分辨率更高。RTD 通道PGA 增益设为 8 或者 16。PT1000 在 0℃ 到 100℃ 变化 385Ω激励电流 500μA 对应的电压变化约 192mV增益 8 时满量程约 256mV合适。增益太高会让电压幅度超出线性范围反而失真。激励电流ADS122U04 的 IDAC 可以设置 10μA、50μA、250μA、500μA、1000μA、1500μA 等档位。RTD 建议用 500μA自热效应小而且信号幅度充足。热电偶不需要激励电流把 IDAC 关掉即可。有一点要提醒PGA 增益越高等效输入噪声通常也会变大。所以平时我坚持“够用就好”的原则千万别觉得增益越高越精细高增益有时会让你在噪声和小信号之间得不偿失。2.3 冷端补偿内部温度传感器和外部传感器要怎么选热电偶测的是热端和冷端的电势差冷端必须补偿这是很多新手最容易忽略的问题。冷端就是热电偶和铜导线相交的那个接线点通常位于 PCB 端子座上。如果冷端温度发生变化而程序不知道读数就会出现一条直线漂移。基于 ADS122U04 做方案时冷端补偿我有两条路默认推荐用 ADS122U04 的片上温度传感器。芯片内部有一个二极管温度传感器通过内部通道采样后可以直接读到当前芯片温度精度大约 ±0.5℃。只要你让 PCB 上的 ADC 芯片紧挨着热电偶接线端子并用宽铜皮做热连接那么片上温度就能近似冷端温度。对大多数工业设备和 HVAC 来说0.5℃ 的补偿误差完全够用。更高精度外部 0.1℃ 精度的数字温度传感器。如果客户要求整机测温精度做到 ±0.3℃ 以内就建议在端子旁边放一颗高精度数字温度传感器比如 TI 的 TMP117 或 ADI 的 ADT7420通过 I2C 读冷端温度在 MCU 里做补偿计算。代价是 BOM 成本上浮软件也多一个通信任务。这里有个常见的错误做法很多工程师直接把冷端温度传感器放在单片机上而传感器离热电偶端子很远。结果 MCU 和端子的温差在设备内部空气流动时可能有 2~3℃补偿出来的温度自然不准。记住冷端传感器的位置比精度指标更重要。3. 硬件电路细节原理图里那些决定精度的环节3.1 电源、基准电压和去耦一个都不能省ADS122U04 内部虽然有基准但如果你追求高稳定性外部基准更好。热电偶信号本身就是微伏级的电源纹波和基准漂移都会被折算到最后的温度值里。我的做法是模拟电源 AVDD 和数字电源 DVDD 分开走各经过一个磁珠或 10Ω 电阻后再进入芯片引脚。两个电源之间用 0Ω 电阻单点连接数字地和模拟地在 ADC 下方汇合。AVDD 对地放 10μF 钽电容并联 0.1μF 陶瓷电容DVDD 对地放 0.1μF 陶瓷电容。注意放置位置要贴近芯片引脚走线先经过电容再进芯片。如果为了共同参考基准电压建议选 REF50252.5V温漂 3ppm/℃ 左右输出端加 10μF 电容和 1kΩ/0.1μF 低通滤波。ADS122U04 的参考输入要连接到 REF 引脚的电路如果做 RTD 比例测量则需要用外部基准电阻接法这个我后面会展开讲。很多人喜欢省掉磁珠直接铺一圈地结果样板调了两周都在跟噪声作斗争。电源去耦不是玄学是 ADC 性能的下限保障。3.2 模拟输入的 RC 滤波参数别拍脑袋定ADS122U04 的输入端虽然是高阻抗但直接接传感器信号的话现场的射频干扰、电机启停带来的尖峰干扰都会进到 ADC。输入滤波电路的标准做法是每个 AIN 引脚对地放一个电容同时信号路径上串联电阻。我常用的参数是串联电阻 10kΩ每个引脚对地电容 1nF并额外在差分两端之间并联一只 10nF 电容。这个组合的截止频率大约是 1 / (2π × 10k × 10nF) ≈ 1.6kHz对热电偶这种带宽极低的信号来说足够同时还能有效滤掉高频共模干扰。有个细节值得注意RC 滤波电阻串联在信号路径上会产生压降。对于 RTD 这种由恒流源激励的阻性传感器这个压降会影响比例测量的精度。所以 RTD 通道我建议串阻选小一点比如 100Ω然后适当加大电容热电偶通道则可以用较大的串联电阻因为热电偶输出阻抗本来就低串联电阻对测量影响极小。3.3 UART 电平连接与 ESD 保护ADS122U04 和 PIC18F85J50 都工作在 3.3VUART 直连没有电平匹配问题但需要注意两点两片芯片的 TX/RX 要交叉连接。ADS122U04 的 DOUT或 UART TX接 PIC18 的 RXADS122U04 的 DIN或 UART RX接 PIC18 的 TX。接线接反是样板阶段最常见的事故。现场设备有长线引出时UART 端口对地加 TVS 管或 ESD 保护阵列。不要省这几个器件工业环境下工人插拔端子、电机火花干扰都可能让 MCU 和 ADC 的 UART 引脚损坏。PCB 布局方面我的习惯是ADS122U04 尽量靠近传感器端子模拟信号走线最短PIC18F85J50 的晶振和数字走线远离模拟输入区UART 走线不要跨过 ADC 的输入走线。这些经验都是我调试噪声时一点点磨出来的很多问题看原理图发现不了只能看板子。4. PIC18F85J50 驱动先说通信再说数据4.1 UART 初始化PIC18 的老规矩PIC18F85J50 的 UART 模块用起来并不复杂关键是波特率发生器配置要算准。内部振荡器频率我用 40MHz目标波特率 9600这是 ADS122U04 默认支持的 UART 速率。我参考 ADS122U04 手册中的命令交互方式做了一套驱动封装。实际操作流程大致如下上电后发送复位命令0x06等待 10ms 以上让内部电路稳定。读取寄存器 0x00、0x01、0x02确认芯片应答正常。发送写寄存器命令写入输入多路选择、增益、数据速率、转换模式、激励电流等配置。启动转换等待数据准备好然后发送读取转换结果命令接收 3 字节拼合成 24 位补码。这段代码里值得注意的有两点UART 接收不要让主循环忙等待要放到中断里接收缓冲建议做成环形缓冲避免转换期间丢数据。4.2 寄存器配置别小看这几个字节ADS122U04 的重点寄存器大致分三个寄存器 0x00输入多路选择、PGA 增益、PGA 旁路。寄存器 0x01数据速率、转换模式、50/60Hz 滤波。寄存器 0x02IDAC 激励电流、内部/外部基准选择、温度传感器通道开关。给热电偶通道配置时我会把数据速率设为 20SPS打开 50/60Hz 滤波。给 RTD 通道配置时打开 IDAC 并设为 500μA然后选择比例测量所需的基准电阻端接方式。寄存器的具体位定义会因芯片版本略有差异所以我不在这里列出完整的位映射表实际开发时务必以你手头那一颗芯片的数据手册为准比如通过 TI 官网下载的最新版。但思路是通用的先把输入通道和增益配好再配速率和滤波最后开激励。4.3 读取转换值从 3 个字节拼出有符号数ADS122U04 的转换结果是 24 位二进制补码。接收时按 MSB 先行的顺序读回三个字节然后组合成一个 int32_t。组合之后要处理一下符号扩展uint8_t b2, b1, b0; // b2 为最高字节 int32_t raw ((int32_t)b2 16) | ((int32_t)b1 8) | b0; if (raw 0x800000) { raw | 0xFF000000; // 符号扩展 }如果按无符号方式计算再强制转有符号ADC 输出负值比如热电偶接反或冷端温度高于热端就会计算出完全离谱的温度。这个坑我在调试时踩过一次因为当时 RTD 通道一直是正数换成热电偶后怎么都读不到正常值最后发现就是符号扩展没做。此外连续转换模式下我建议在 MCU 端做滑动平均滤波比如取最近 16 次转换结果求平均。虽然 ADS122U04 自带数字滤波但叠加一层软件均值对读数稳定性的提升非常明显。代价是响应速度变慢HVAC 和工业温度监测对响应速度要求不高这个取舍完全划算。5. 温度换算与标定从 24 位码值到稳定读数5.1 先把 ADC 码值变成电压拿到 24 位 raw 值之后第一步是换算成模拟输入电压。如果使用内部基准基准电压 VREF 为 2.048V或按实际配置的外部基准电压来那么V_in (raw / 2^23) × VREF / Gain举个例子raw 524288满量程的 1/16Gain 128VREF 2.048V则 V_in (524288 / 8388608) × 2.048 / 128 ≈ 0.001V 1mV。这一步有个细节ADS122U04 的 2^23 是正满量程对应的码值24 位补码的正满量程是 8388607负满量程是 -8388608。工程上按 2^23 来当满量程计算误差极小可以忽略。5.2 热电偶线性化查表还是逼近K 型热电偶的输出电压与温度并非严格线性。最直观的做法是把 NIST 分度表做成二维数组用二分查找找到温度区间再做线性插值。分度表分度间隔是 1℃查表法精度在 ±0.1℃ 以内代码逻辑简单只是占用几百字节的 Flash。PIC18F85J50 的 Flash 足够所以这是我最推荐的方式。如果不想占用太多 Flash也可以用耦合多项式。K 型热电偶在 0℃ ~ 500℃ 范围内用一条三阶或四阶多项式就能逼近但这需要自己拟合系数工作量不小而且边界区间误差容易失控。我自己的项目里工业宽温区用查表HVAC 窄温区用一条二次多项式就够了。热电偶最终温度计算T_actual T_lookup(V_meas) T_coldT_cold 就是冷端温度来自 ADS122U04 片上温度传感器读数或者外部数字温度传感器读数。5.3 片上温度传感器读数怎么换算ADS122U04 的片上温度传感器输出也是一个 ADC 码值。具体换算公式以手册为准我这里说一个 I 在项目里验证过的通用处理思路先将温度传感器通道的 raw 值按照内部基准和增益换算成电压 Vtemp。芯片内部温度传感器的电压-温度关系近似线性典型斜率大约是 0.00156 V/℃在 0℃ 附近输出大约 0.375V。因此 T_cold ≈ (Vtemp - 0.375) / 0.00156。由于芯片个体差异这个公式算出来的绝对温度会有偏差可以在设备校准时用已知环境温度做一次偏移修正。对绝大多数 HVAC 和工业测温应用来说修正后冷端读数稳定在 ±0.5℃ 内是没问题的。5.4 RTD 比例测量和 Callendar-Van Dusen 公式RTD 我推荐用比例测量这是 ADS122U04 的 IDAC 配合外部基准电阻实现的经典接法IDAC 电流同时流过 RTD 和精密基准电阻 RREFADC 的参考电压取自 RREF 两端。这样得到的码值raw_ratio V_RTD / V_REF (I × R_RTD) / (I × R_REF) R_RTD / R_REF关键在于公式里 I 被消掉了VREF 也被消掉了。激励电流的漂移、基准电压的温漂都对最终结果影响很小这是比“测出电压再查表”高出一个量级的方案。得到 R_RTD 之后用 Callendar-Van Dusen 方程反算温度。PT100/PT1000 在 0℃ 以上时R_T R_0 × (1 A×T B×T²)其中 R0 是 0℃ 时的标称电阻A 3.9083×10⁻³B -5.775×10⁻⁷。解一元二次方程T ( -R0×A sqrt((R0×A)² - 4×R0×B×(R0 - R_T)) ) / (2×R0×B)如果项目要求 0℃ 以下还需要引入 C 系数公式会多一项。HVAC 场景一般不会用到这么低温但如果在冷库或冷冻水系统里用还是要补上。5.5 标定流程不做校正就是浪费 ADC我强烈建议所有温度通道出厂前做标定不做标定等于浪费 ADS122U04 的精度。标定分两步零位校准把输入信号短路记录 ADC 输出偏移量保存为 calibration_offset。每次读值后减去这个偏移。增益校准用精密电阻箱或高精度温度校验仪模拟传感器在两点输出测得实际增益与理想增益的比值得到 calibration_gain。最终修正公式T_corrected (T_raw - offset) × gain_factor标定数据存进 PIC18F85J50 的内部 EEPROM 或外挂 Flash换产线设备时校准参数跟着设备走。一次做 100 块板的批量标定工作效率会明显提升。6. 现场调试中踩过的坑从掉坑到稳住6.1 长线传输和端子热电势现场设备里热电偶可能需要从探头走一米甚至更长的线到 PCB。第一次做样机时我直接把热电偶延长线接到端子结果读数在设备启停时跳个不停后来测量发现现场的电机变频器产生的共模干扰被直接灌进了 ADC 输入端。解决方法是双管齐下热电偶延长线用屏蔽层在设备机壳单点接地的屏蔽电缆屏蔽层不要两端都接避免形成地环路。在端子和 ADC 之间加共模滤波也就是之前提到的输入端对地电容。这样干扰才真正被拦在 ADC 之外。还有一个隐蔽问题热电偶直接在 PCB 端子上连接时端子两端的两种金属如果不同会产生附加热电势。虽然铜-铜连接不会产生热电势但如果是镀金或镀锡端子连接点温度不均匀就会引入误差。这个误差通常是零点几度高级设备要用等温块设计来消除我的做法是把冷端温度传感器和端子靠在一起做热均温。6.2 地环路是如何毁掉精度的第二块样板我犯过一个错误为了图方便模拟地和数字地直接大面积相连结果 RTD 通道在白天读数正常晚上工厂设备一开读数就偏了 0.3℃。查到最后是地电位差通过回路变成了共模电压。正确做法是单点接地模拟地和数字地在 ADC 芯片下方的汇合点连接而且连接的“地平面”要完整不能有细长走线代替。同时外部现场接线引入的屏蔽层也要在机壳处接到大地不要引回到 PCB 模拟地上。6.3 固件层面的兜底机制硬件稳了不代表软件可以裸奔。现场环境总有异常我通常会在固件里加三件事对 ADC 通信做超时判断如果连续 200ms 收不到数据自动对 ADS122U04 做一次复位并重新初始化把错误记录下来。对读回的温度值做合理性检查比如温度超出传感器量程、变化速率超过每秒钟几十度都判定为异常读数不纳入控制逻辑。配合 PIC18F85J50 的看门狗定时器防止偶发干扰导致主循环卡死让系统自动恢复而不是等现场人员断电重启。这三件事看起来简单但在实际项目里帮我挡掉了很多售后问题。6.4 实测的一组典型数据我在一个 HVAC 控制箱的样机上做了连续 8 小时测试PT1000 水温度通道环境温度 25℃ 左右使用 500μA 激励电流、增益 16、数据速率 20SPS、软件 16 次滑动平均。最终读数稳定在设定温度 ±0.06℃ 内长时间漂移小于 ±0.1℃。热电偶通道K 型冷端补偿用片上温度传感器在 200℃ 附近的重复性约为 ±0.4℃完全满足设备工艺要求。对比之前用 MCU 内置 12 位 ADC 做的同规格产品温度波动范围从 ±1.2℃ 缩小到 ±0.1℃ 级别。客户反馈是“读数终于不跳了”对项目验收帮助很大。最后分享一个小技巧在固件里保留诊断模式通过串口打印每个通道的 raw 值、电压值、补偿温度。现场出问题时第一步不是拿万用表而是看诊断信息里 raw 值是否正常、冷端温度是否合理。这能帮你快速区分问题是出在传感器、接线、ADC 还是算法上。这个习惯帮我节省了大把现场排查时间你可以直接抄作业。