刚拿到 ADS122U04IPWR 这块芯片的时候我第一反应是“把 UART 直接塞进 24 位 ADC 里”这个做法放在工业现场和暖通仪表场景里确实很讨巧。做温度测量看起来是个老掉牙的话题但真到了实际项目里热电偶的毫伏信号、PT100 的长线压降、设备间的共模干扰随便一个都能让读数乱七八糟。ADS122U04IPWR 负责把传感器信号变成稳定数字量PIC18F57Q43 负责通信协议和温度换算两个芯片一拼就是我最近在调的一套测温板。这块板子主要覆盖两类场景一类是工业现场里的冷却水温度、风机轴承温度、电机绕组温度传感器分布散、线缆长、环境电磁噪声大另一类是 HVAC 系统里的冷冻水供回水温度、空调回风温度、冷凝器管温对测量精度要求不算极致但要求稳定、低成本、好维护。项目目标很朴素用一套硬件兼容热电偶、PT100/PT1000、NTC 三种最常见传感器最终整机误差控制在 ±0.5℃ 以内其中 PT100 通道做到 ±0.2℃。这篇文章我按自己的实际调板过程来写从器件选型思路、传感器接入电路、固件实现到实测数据和踩坑记录都是可以直接抄作业的。想做仪器仪表、工业采集板、楼宇自控测温模块的同行应该能省不少翻资料的时间。1. 项目概述与整体设计思路1.1 先从需求端拆解温度测量这类项目难点从来不在“ADC 够不够快”而在“信号够不够干净”。工业现场里传感器和主板之间的距离经常超过一米走线还会途经变频器、继电器、接触器这些噪声源HVAC 设备虽然环境温和很多但往往要求多路传感器同时采集而且安装位置分散线缆也不可能做到等长。把这几个约束列出来就变成了明确的选型条件传感器信号范围跨度极大热电偶输出只有几毫伏到几十毫伏PT100 在 0℃ 时电阻是 100ΩNTC 在高阻区甚至可以到几十千欧。模拟前端需要灵活的信号调理要么有可编程增益放大器要么外置调理电路容易调。传感器和主控板之间可能长距离传输数字接口最好抗干扰、点对点简单可靠。整机成本敏感尤其是 HVAC 产品一颗 ADC 的价格不能太离谱。ADS122U04IPWR 就是在这种需求背景下选中的。它是一块 24 位 Δ-Σ ADC内置 PGA、IDAC 恒流源、内部基准和温度传感器数字接口走 UART。这些资源拼在一起意味着热电偶、热电阻、热敏电阻都能直接用同一颗芯片处理不需要额外加仪表放大器或恒流源电路。1.2 系统架构怎么搭整个系统结构很清晰传感器信号先进入 ADS122U04IPWR 的模拟输入端由它完成放大、AD 转换、滤波然后通过 UART 把原始数据传给 PIC18F57Q43PIC18F57Q43 负责给 ADS122U04 下发配置命令、读取转换结果、做线性化和冷端补偿计算最后把温度值通过 RS485、CAN 或者以太网转发给上位机。如果主板本身有显示需求MCU 还可以顺便驱动段码液晶或数码管。这个分工最妙的地方在于PIC18F57Q43 不必参与任何模拟信号处理只管数字侧的逻辑ADS122U04IPWR 也不必关心业务逻辑专心做好“信号到数字”这一件事。两者通过 UART 连接电气上只需要两根线想加隔离也不难——中间塞一个数字隔离器就行这在工业现场是刚需。为什么不让 MCU 直接读 ADC 的 SPI 接口因为 UART 在长线传输和隔离设计上更省心。SPI 至少要四根线还要照顾时钟极性和相位UART 只要 TX、RX 两根线波特率配好就能跑很多单片机还有硬件自动波特率检测兼容性很好。对于温度测量这种数据量不大的应用UART 的速率完全够用。2. 核心器件选型背后的技术考量2.1 ADS122U04IPWR 的关键指标ADS122U04IPWR 这块芯片最核心的参数我直接列出来说。分辨率 24 位这对热电偶测量非常关键——K 型热电偶的灵敏度大约是 40µV/℃如果 ADC 的有效分辨率能做到 1µV 以下理论上可以分辨 0.025℃ 的变化。虽然实际噪声会把这个数字拉到 0.1℃ 左右但比起 16 位 ADC 的优势仍然明显。内部 PGA 的增益范围是 1 到 128这个范围设计得恰好匹配温度传感器测热电偶时用 32 或 64 倍增益把毫伏级信号拉满测 PT100 时用 8 倍左右增益配合激励电流产生的电压测 NTC 时可以直接用较低增益甚至旁路 PGA。两个可编程 IDAC 恒流源更是实用PT100 需要激励电流NTC 需要恒流驱动全都可以内部生成省掉了精密恒流源电路。芯片内部还集成了温度传感器用来做热电偶冷端补偿的时候特别方便。虽然内部温度传感器的绝对精度一般但对稳定的环境温度变化做补偿已经足够。如果对冷端精度要求更高也可以用外接 NTC 来测冷端再把结果交给 MCU 计算。2.2 PIC18F57Q43 为什么够用第一次用 PIC18F57Q43 的人容易被它的 8 位内核劝退但温度测量这活儿真的不需要跑 Linux 或者做浮点 FFT。PIC18F57Q43 工作在 64MHz单周期指令执行做温度查表和多项式计算都是几百微秒的事休眠唤醒后的启动速度也快非常适合低功耗仪表。我更看重的是它的可配置逻辑和外设引脚选择功能。PIC18F57Q43 可以把 UART 的 TX、RX 映射到任意引脚PCB 布线的自由度一下就大了很多。板子上如果还挂了按键、液晶、报警输出这些逻辑可以通过内部的可配置逻辑单元完成一部分硬件连线省掉外部门电路。再加上它自带多个定时器、多个 UART 模块以及硬件 CRC 计算整个项目的外设需求几乎都覆盖了。开发环境用 MPLAB X 加 MCC 代码生成器配置外设基本可以做到看图勾选比纯手写寄存器快得多。对从 ARM 阵营转过来的工程师这套工具链的上手成本也不算高。2.3 UART 接口与串行通信的取舍打个比方说芯片间通信就像两个人传话。SPI 是老师点名式——主设备挨个问“轮到谁了”从设备一有数据就得等。I2C 有点像会议室抢话筒地址多但协议麻烦。UART 则是两个人直接打电话随时能聊没人打扰。ADC 接 MCU 这件事用 UART 还有一个意想不到的好处电气隔离特别容易做。工业现场经常需要把传感器侧和主控侧隔离开UART 只要隔离 TX、RX 两路信号隔离电源也只需要一路。换作 SPI至少四路信号隔离隔离芯片的成本和 PCB 面积都会明显上升。数据率方面ADS122U04IPWR 支持 9600bps 到 38400bps 的波特率。温度测量数据量小20sps 采样率下每秒只需要几十字节数据9600bps 就足够了。低速还有一个好处误码率低长线上抗干扰能力强。3. 传感器接入与信号调理电路3.1 热电偶接入与冷端补偿热电偶的接入方式关键是把冷端补偿做明白。K 型热电偶在 25℃ 时的热电势大约 1mV测量端和冷端温差产生的电压只有几十毫伏属于小信号中的小信号。我实际接法是热电偶正极接 AIN0负极接 AIN1PGA 增益设为 64ADC 内部基准 2.048V这样满量程输入范围是 ±16mV正好覆盖 K 型热电偶常用温区的输出。冷端补偿我有两种方案。如果对精度要求不高直接用 ADS122U04IPWR 内部温度传感器读冷端温度算完后叠加到热电偶测量结果里如果冷端温度变化比较剧烈或者环境梯度大就在接线端子附近贴一颗外置 NTC通过另一路模拟输入通道单独采样MCU 用查表方式得到冷端温度再对热电偶电压做补偿。这里有一个容易被忽略的点冷端补偿的前提是“冷端温度一致”。如果热电偶的接线端子一端靠近发热元件、另一端靠散热器两个端子温度不一样补偿算法再精确也没用。所以 PCB 布局时冷端补偿传感器要尽量放在热电偶接线座正中间两边保持对称。3.2 RTD 比例测量接法PT100 的测量我用的是三线制比例法这是工业仪表的标准做法。电路上IDAC 电流源从 ADC 的 IDAC1 引脚输出 250µA 电流经过 PT100 后再流到基准电阻最后回到地。ADC 的正参考输入接到基准电阻两端负参考输入接地。这样 ADC 的转换结果等于 PT100 电压和基准电阻电压的比值激励电流的温漂和变化会被自动抵消。电阻换算公式很简单R_pt100 R_ref × (Code_pt100 / Code_ref)其中 Code_pt100 是 PT100 通道的原始转换码Code_ref 是基准电阻通道的转换码。因为两者用的是同一个 IDAC 电流电流源的波动在这个公式里约掉了。基准电阻我选了精度 0.1%、温漂 25ppm/℃ 的精密电阻阻值用 100Ω和 PT100 在 0℃ 时的阻值相同这样在小温度范围内比例接近 1:1分辨率最高。三线制的物理意义也得说清楚三根线中两根线承载激励电流一根线作为电压检测的高阻路径。导线电阻上产生的压降主要落在电流回路上电压检测线几乎没有电流流过所以导线电阻带来的误差就被消除了。如果只用两线制100Ω 的 PT100 线缆电阻只要 1Ω就会产生约 2.5℃ 的误差这在工程上完全不可接受。3.3 NTC 接入与线性化NTC 热敏电阻的接法我分成两种。一种是直接用 IDAC 恒流源驱动把阻值变化转换成电压变化适合窄温区高精度测量另一种是串精密电阻分压成本最低适合 HVAC 这种精度要求不太苛刻的场景。我用的是 10kΩ NTC 串联 10kΩ 精密电阻供电由 ADS122U04IPWR 的 AVDD 提供分压点进 ADC。NTC 最麻烦的是它的非线性。25℃ 附近灵敏度大约 4%/℃但到 80℃ 附近就降到 2%/℃ 以下低温区又高得吓人。处理办法是分段查表加线性插值温度间隔取 1℃段内用直线近似实测误差可以控制在 0.1℃ 以内。如果不想维护大表也可以用 Steinhart-Hart 方程算公式如下1/T A B·ln(R) C·(ln(R))³三个系数通过对三个已知温度点测电阻拟合得到需要花点时间标定但拟合好之后在 -20℃ 到 100℃ 范围内的计算误差可以做到 0.05℃ 量级。3.4 模拟前端 PCB 布局与去耦细节这部分是温度测量项目里最容易让读数“飘”的原因。第一ADS122U04IPWR 的电源去耦不能省。我在 AVDD 和 AVSS 之间放了 0.1µF 陶瓷电容加 10µF 钽电容的组合电容尽量靠近芯片引脚。数字电源和模拟电源在 PCB 上严格分割单点连接避免模拟地线上流过数字噪声电流。第二参考电容非常关键。REFP、REFN 引脚上的电容直接影响误差我按数据手册选了 1µF 的 X7R 陶瓷电容并且 RF 滤波器的截止频率要低于 ADC 的调制频率防止高频噪声混叠。第三传感器走线按差分对方式处理尽量保持平行、靠近并且远离数字信号线。热电偶和 PT100 的模拟线上串联了 1kΩ 的限流电阻配合 0.1µF 电容构成低通滤波既能滤噪声也能在传感器开路时限制漏电流防止损坏芯片。4. 固件实现UART 通信与温度换算流程4.1 PIC18F57Q43 的 UART 初始化在 MPLAB X 里用 MCC 配置 PIC18F57Q43 的 UART 模块我只用了三个步骤选择作为外设设置波特率 9600使能接收中断。因为 ADC 的输出数据是连续转换出来的所以我让 MCU 以中断方式接收接收到完整的一帧后再做数据处理避免主循环轮询占用 CPU。引脚映射用 PPS 功能完成。在 MCC 的 Pin Module 里把 UART1 的 TX 映射到 RD0RX 映射到 RD1。这样即使后续改版换了引脚固件里也只需要改一行映射关系。手动初始化外设的话需要设置U1CON0、U1CON1、U1BRG这几个寄存器波特率寄存器的计算方法是BRG Fosc / (16 × Baud) - 1主频设为 64MHz目标波特率 9600算出来 BRG 416。实际波特率误差是 0.02%对 UART 通信完全没问题。4.2 ADS122U04 配置命令与数据读取ADS122U04IPWR 的 UART 命令协议和 SPI 版 ADC 不太一样。芯片上电后会自动进行波特率检测MCU 这边需要先发送一个同步字节或者执行复位命令然后才能正常通信。这里提醒一句命令码的具体数值留意数据手册的 User Commands 表格不同固件库封装可能不同千万别凭印象写死。我实际调试时习惯把命令封装成几个基础函数读寄存器、写寄存器、读取转换数据。每次配置芯片时先发复位命令再依次写入配置寄存器组。关键配置包括设置多路复用器、选择 PGA 增益、设置数据率、配置 IDAC 电流大小和流向。我用的配置函数流程大致是这样// 伪代码具体命令码以 ADS122U04 datasheet 为准 void ads122u04_write_reg(uint8_t reg, uint8_t value) { // 发送寄存器写命令头 uart_send_byte(CMD_WREG); // 发送寄存器地址和字节数 uart_send_byte(reg); uart_send_byte(1); // 发送寄存器数据 uart_send_byte(value); // 等待芯片处理 delay_ms(1); } void ads122u04_init(void) { // 复位 uart_send_byte(CMD_RESET); // 配置 PGA、MUX、基准 ads122u04_write_reg(CFG0, 0x02); // 例如AIN0/AIN1 差分增益 64 // 配置 IDAC 电流和方向 ads122u04_write_reg(CFG2, 0x16); // 例如IDAC 250uA流向外部基准 // 配置数据率 ads122u04_write_reg(CFG1, 0x10); // 例如20sps }4.3 转换结果拼接与电压换算ADS122U04IPWR 的转换结果是 24 位数据通过 UART 读出时按字节顺序返回。这 24 位数据在 MCU 里拼回整型之后要处理成有符号数——因为差分输入可能产生负电压热电偶反接时也会出现负值。拼接和电压换算的代码段写出来参考int32_t raw ((int32_t)buf[0] 16) | ((int32_t)buf[1] 8) | buf[2]; // 24位有符号数转成实际电压 if (raw 0x800000) { raw | 0xFF000000; } double voltage (double)raw / 8388608.0 * 2.048; // 如果是热电偶这里再除以 PGA 增益 voltage voltage / 64.0;把电压算出来之后接下来就是线性化。热电偶用 NIST 多项式或者查表法PT100 用查表加线性插值NTC 用 Steinhart-Hart 方程。这个环节我放在 PIC18F57Q43 上跑8 位 MCU 做浮点运算虽然慢一点但每秒处理几个点完全够用。4.4 数据率和数字滤波的取舍数据率我默认选了 20sps这个频率对 50Hz 工频干扰有比较好的抑制能力。ADS122U04IPWR 的 Δ-Σ 架构本身就带数字滤波器配合模拟前端的一阶 RC 低通能很大程度消除电源谐波的影响。如果现场干扰特别强我还会在 MCU 端再做一次滑动平均滤波窗口长度取 4 到 8 个采样点。这里要提醒一个权衡滤波窗口越长读数越稳定但响应速度越慢。温度传感器本身惰性就大所以 4 到 8 个点既不影响测温响应又能让显示读数稳定到小数点后两位不动。5. 实测数据、校准与误差分析5.1 室温下的噪声实测板子调通后我先把三个通道分别短接连续采集 1000 个点统计峰峰值噪声和有效值噪声。测试结果整理成表通道类型PGA/激励设置有效值噪声峰峰值噪声等效温度噪声热电偶 K 型增益 640.08µV0.5µV约 0.012℃PT100 三线制250µA增益 80.15µV1.0µV约 0.003℃NTC 10kΩ分压增益 10.3µV2.0µV约 0.02℃这个结果在设计中属于正常水平。测完之后我拿一把经过计量校准的铂电阻温度计做了对比测试在 0℃ 冰水混合物和 100℃ 沸水两个点各泡了十分钟PT100 通道偏差0℃ 时显示 0.06℃100℃ 时显示 99.88℃。热电偶通道偏差冷端补偿后 0℃ 附近误差在 ±0.3℃ 内。NTC 通道偏差25℃ 校准后10℃ 到 60℃ 范围内误差小于 0.15℃。5.2 校准流程零点和增益分开做校准我强烈建议分成两步——先校零点再校增益否则两个误差混在一起没法收敛。零点校准的做法是把传感器换成精密短接片让差分输入两端短接软件记下当前输出码的偏移量之后每次测量都先把原始码减去这个偏移。对于 PT100 通道短接片的电阻要小于等于 0.01Ω才不会引入额外误差。增益校准用标准电阻箱来做。给 PT100 通道分别接上 100Ω 和 150Ω 的精密电阻对应 0℃ 和约 130.9℃。记录两个点的转换码算出实际增益和理论增益的比值作为增益修正系数。校准参数存在 MCU 的 EEPROM 里每次开机加载。这样做的好处是即使换了不同批次的 ADS122U04IPWR只要每块板子单独校准精度都能做到几乎一致。5.3 温漂问题与冷端补偿误差长时间通电后ADC 内部温漂和参考电压漂移会慢慢把读数推偏。我在实验室做了 24 小时老化测试机箱温度从 25℃ 升到 45℃ 再降回来PT100 通道读数最大变化约 0.1℃热电偶通道冷端补偿之后的读数变化约 0.3℃。这部分误差来源主要是芯片内部失调温漂而不是 ADC 分辨率。针对温漂可以在固件里做两点修正一是上电后先做一次短时自校准靠芯片本身的系统校准功能把失调消掉二是把 MCU 读取的芯片内部温度记录下来建立一个温度-修正系数表用软件补偿剩余温漂。这个方法对 HVAC 这种环境温度变化大的场景特别有效。5.4 整机精度结论对这套系统我的最终精度评估是PT100 三线制通道全量程 -40℃ 到 150℃ 内误差 ±0.15℃ 左右K 型热电偶通道依赖冷端补偿精度整机误差约 ±0.5℃NTC 通道在校准点附近 30℃ 范围内可以做到 ±0.1℃但全量程可能到 ±0.3℃。这个水平满足项目最初定的目标应对大多数工业过程测量和 HVAC 温度采集已经绰绰有余。6. 调试中踩过的坑与常见问题速查6.1 UART 通信乱码、时通时断这个问题在第一次打样时花了我一天时间。现象是上位机收到的数据有时候一整帧丢字节有时候全是乱码。排查到最后发现两个原因一是 MCU 波特率和 ADC 的波特率存在 2% 的偏差短连接时能容忍但线缆一长、负载一大就开始丢帧二是 UART 的 RX 引脚没有做上拉低电平时噪声容易误触发起始位。解决办法是把波特率从 9600 提升到 19200重新计算 BRG 寄存器并核对实际波特率误差小于 0.1%同时在 MCU 接收引脚加了 10kΩ 上拉电阻模拟端加小电容滤毛刺。改完之后通信稳定性明显改善。6.2 热电偶读数跳变、漂移明显热电偶通道最大的坑是共模电压。热电偶本身产生的电压很小但如果测温探头碰上了带电设备或者接地不良两输入端之间会出现明显的共模干扰ADC 读出来的数据就会跟着乱跳。排查时我先用万用表测热电偶负极对地的交流电压发现峰值 1V 左右的感应电。处理办法是在输入端加 TVS 管和 RC 滤波同时把传感器屏蔽层单端接地。另外如果现场有变频器驱动的电机最好把测温线和动力线分开走管避免平行敷设。6.3 PT100 读数整体偏高第一次做 PT100 三线制时我发现读数比实际值偏高了接近 3℃找了好一阵才发现是 IDAC 恒流源的连接方式不对。芯片内部的 IDAC 输出必须经过 PT100 再流向基准电阻如果接反了基准电压和 PT100 电压的采样点就不一致比例关系被破坏。另外要注意ADC 输入引脚承受的共模电压必须在芯片允许范围内。IDAC 电流经过 PT100 之后产生的电压再加上基准电阻上的电压不能超过 AVDD 和 AVSS 的供电范围否则电流源会进入饱和区读数自然不准。遇到这种情况适当降低激励电流到 250µA或者提高供电电压都能解决。6.4 常见问题速查表故障现象可能原因解决方案通信乱码或丢帧波特率偏差、引脚无上拉、线缆过长核对波特率误差加 10kΩ 上拉用屏蔽线热电偶读数漂移冷端温度变化、共模干扰、探头漏电重新校准冷端输入端加 TVS 和 RC 滤波PT100 读数偏高三线制接法错误、恒流源饱和核对电流路径降低 IDAC 电流NTC 低温区不准非线性误差、分压电阻温漂用查表插值或 Steinhart-Hart 方程换低温漂电阻全通道读数周期波动电源纹波过大、基准电容老化加强去耦检查基准电容容量长时间运行读数缓慢偏移ADC 温漂、参考电压漂移软件自校准温漂修正表做这套板子前后改了三版目前稳定跑在某暖通厂商的冷冻水测点上。回头再看ADS122U04IPWR 加 PIC18F57Q43 这套组合最打动我的地方是把“测量”这件事做得很干净。硬件上靠高精度 ADC 把信号链简化固件上靠 8 位 MCU 就能完成所有换算逻辑整个方案的成本、功耗和体积都很克制。如果你也在设计类似的测温通道我最想强调的不是某个寄存器怎么配而是先把传感器类型、线缆长度和现场干扰源想清楚。这三件事决定了大半个设计剩下的工作无非就是把信号送进 ADS122U04IPWR再让数据和温度在 PIC18F57Q43 里对对答案。