去年给一家暖通厂做控制器改版需求看着不复杂8 路 PT1000 温度测量覆盖回风、送风、盘管进出水和室外补偿精度要求 ±0.2°C传感器离主控板五到二十米现场还有变频器这种强干扰源。折腾下来发现温度测量方案里最容易被低估的正是 ADC 接口怎么选、激励电流怎么配、布线和隔离怎么做这几个环节。最终定型的是 ADS122U04IPWR 搭配 STM32F429NI——一个 24 位四通道 Δ-Σ ADC通过 UART 和 MCU 通信把复杂的温度模拟链路简化成了串口读写。这篇文章把整套方案的选型逻辑、硬件设计、驱动实现、温度换算校准和现场踩坑按我的实际经历完整写出来给准备做工业和暖通温度测量的朋友一个可以直接参考的样板。1. 为什么选 UART 接口的精密 ADC方案对比与选型动机1.1 HVAC 控制器的典型测温需求与难点暖通控制器要关心的温度点其实很固定回风温度、送风温度、盘管供水/回水温度、室外温度、有时候还要加冷凝器管壁温度或地暖混合水温。这些点的共性是变化缓慢但绝对值要准控制回路的稳定性和它强相关。采样率根本不需要多高1 Hz 到 10 Hz 就足够真正要命的是长期漂移和抗干扰能力。这类系统以往最常见的做法是 NTC 热敏电阻加运放再用 MCU 内置 ADC 采集。成本确实低但问题突出NTC 的 B 值一致性差、非线性严重25°C 附近换 0.1°C 都要单独校准模拟运放环节本身会引入偏置和温漂出厂调好的零点到夏天可能就偏了长线传输时NTC 分压电路的输出阻抗高很容易被变频器谐波干扰拾取。做实验室型号还好一到工地就现原形。所以这次方案评审时我直接排除了模拟前端方案要求改用 RTD 传感器加专业 ADC。RTD 里 HVAC 用 PT1000 最合适因为现场走线长PT1000 的引线电阻影响比 PT100 小一个数量级而且本身信号幅度大对后续 PGA 的要求更宽松。ADC 这块我一开始也循着惯性去看 SPI 接口的 ADS1220但详细列完需求之后反而被 ADS122U04IPWR 的 UART 接口吸引住了。1.2 为什么 UART 比 SPI 更适合这种场景做工业测温主控板和传感器端子之间往往隔着端子排、塑壳、长达数米的屏蔽线。SPI 接口的 ADC 在实验室台面上很好用四根线一插就能跑可放到现场就会遇到几个实际麻烦第一SPI 的 SCLK 通常跑到几 MHz长线传输时波形振铃明显需要加终端电阻和缓冲器而且时钟线本身就是一个辐射源。第二要做电气隔离时SPI 至少需要隔离时钟、数据输入、数据输出三根线如果还要处理 DRDY隔离通道数量更多成本和布局面积都上升。第三SPI 是主从同步协议对时序要求严格MCU 在忙于其他中断时若稍微延迟响应通信容易错位。ADS122U04IPWR 的 UART 接口恰好规避了这些问题。UART 是异步协议不依赖时钟同步波特率降到 9600 bps 后长线传输容错能力非常强物理上只需要 TX、RX外加一根 DRDY 状态线隔离时三路数字信号足够。对 HVAC 这种温度变化缓慢、采样率要求不高的应用UART 的低速率完全不是瓶颈。还有一个工程上的隐性优势UART 是 MCU 的通用外设几乎每个型号都有多个串口不像 SPI 可能会被 Flash、显示屏、别的外设占用。用 STM32F429NI 的 USART3 接 ADC不会跟其他外设抢总线代码调试也直观。1.3 方案对比为什么不是更大规模的采集芯片我也认真考虑过直接用 ADS124S08 这类多通道 ADC或者用现成的模拟量采集模块。列个对比表可能更直观维度ADS122U04 UARTSPI 接口 Δ-Σ ADC运放 NTC MCU ADC单通道精度24 位配 RTD 可到 ±0.1°C同级别依赖校准长期漂移大通信线数量2~3 根4~5 根1 根模拟线隔离成本低三路低速隔离高需要隔离高速时钟模拟隔离更贵长线抗干扰9600 bps 下极强高速时钟容易辐射高阻节点容易受干扰维护可读性串口波形直观逻辑分析仪才看得清万用表可以简单测ADS122U04 单颗只有四通道8 路温度需要两颗但换来的是每颗芯片独立、故障隔离清晰而且它内置两个激励电流源一颗芯片就能完成四线制、三线制 RTD 测量不需要外置恒流源。相比之下ADS124S08 通道多但封装更大、引脚更密中小型控制器布线没那么从容。STM32F429NI 在这套方案里显得「大材小用」但实际上很合适180 MHz 主频和 FPU 让温度换算、滤波算法随便跑8 个 UART 为后续扩展 Modbus 网关、人机界面通信留足余量2 MB Flash 可以存多组校准表LQFP100 封装在四层板上手工焊接也不困难。说实话用更低端的 STM32 也够但 429 系库存稳、资料多项目周期不等人选工具顺手比省钱重要。2. 前端硬件设计传感器接线、激励电流与布线细节2.1 PT1000 与 PT100 的取舍工业现场我见得比较多的还是 PT100暖通行业则相反PT1000 更常见。原因很简单PT1000 在 0°C 时电阻 1000Ω同样是 1 mA 激励电流传感器自身发热功率比 PT100 低一个量级而且引线电阻占比小即使只做两线制几十米线缆带来的误差也可控。对于 HVAC 的盘管、风管温度测量PT1000 是更稳的选择。如果你的应用是工业过程控制传感器可能被客户指定为 PT100那也不必纠结软件里把基准电阻 R0 从 1000 改成 100 就行接线原理一样。关键是做硬件时最好把两种传感器的接线端子兼容三个端子分别引出 RTD、RTD-、屏蔽地这样现场换传感器类型不用改板子。2.2 两线制、三线制还是四线制传感器到 ADC 的距离决定了接线制式。我在这个项目里默认按三线制设计这是 HVAC 现场最均衡的方案。两线制的问题在于激励电流流过引线电阻会产生固定的电压偏置。PT1000 在 20 米线缆若单根引线电阻约 3Ω两线制会把这个电阻的压降直接算进传感器电阻对应温度误差大约 0.75°C这已经超出±0.2°C 的要求。四线制最准但需要四根传感器线现场穿管、端子排都更费事成本明显上升。三线制则是在传感器两端引出三根线利用两个激励电流源分别流过 RTD 和参考电阻ADC 的差分测量可以抵消引线电阻的压降。实测下来三线制在 20 米距离内的残余误差可以压到 0.05°C 以内完全够用。![三线制接线逻辑文字示意] 实际连接时RTD 一端接 AIN0另一端接 AIN1第三根线接公共端。ADS122U04 内部用两个 IDAC 电流源分别输出一路流过 RTD另一路用于补偿引线电阻测量结果是差分电压引线压降自然被共模抑制掉。需要注意的是这两路电流源必须按手册要求在软件里配成匹配状态否则补偿效果会打折扣。2.3 激励电流怎么选量程、自热与噪声的平衡IDAC 电流的选择是 RTD 测量最核心的参数。电流太小信号幅度低噪声占比大电流太大传感器自热导致读数偏高。ADS122U04 的 IDAC 电流范围可以覆盖从几十微安到毫安级我的推荐PT1000 配 250µAPT100 配 500µA 或 1mA。算一笔账就清楚PT1000 在 0°C 时 1000Ω250µA 产生 0.25V 信号在 150°C 时约 1573Ω产生 0.393V 信号。如果 PGA 增益设为 2满量程约 1.024V整个测温范围都有充足的余量。自热方面250µA 在 150°C 时功耗约 0.1 mW以传感器散热系数 2 mW/°C 估算自热温升只有 0.05°C 左右可以接受。相反如果上来就用 1mA 激励 PT1000150°C 时功耗大约 1.57 mW自热可能到 0.5°C在讲究精度的控制器里这就是不可接受的偏差。所以我在硬件上特意把激励电流做成软件可配置现场根据传感器类型和量程调整而不是焊接固定电阻。2.4 滤波、保护与 PCB 布局ADC 是高精度器件前端不做滤波等于把干扰直接送给 Δ-Σ 调制器。我的标准做法每路传感器输入串联 50Ω~100Ω 电阻对地并联 10nF 电容组成截止频率约 160 kHz 的差分低通滤波。这个频率看起来很高但它主要是抑制射频干扰和采样电容的驱动要求真正滤除工频谐波靠的是 ADC 内置的数字滤波器模拟 RC 不需要做到很低的截止频率否则会拖慢输入建立时间。传感器线进入板卡的位置要加 TVS 管推荐双向 5V 规格防止雷击感应和静电。屏蔽层在传感器侧悬空、在控制板侧单点接地这是 HVAC 现场对抗变频器干扰最有效的一招。如果现场走线特别恶劣传感器线可以穿金属软管两端接地效果更好。PCB 布局上ADS122U04IPWR 的模拟电源和数字电源建议从同一个 3.3V 源头经磁珠分两路供给模拟地单独铺一小块铜皮在芯片下方单点汇入数字地。参考电压去耦电容要靠近 REF 引脚我用的是 1µF 陶瓷电容并联 10nF布局时放在芯片同一面、走线尽量短。别小看这些细节同样的电路布局好坏能让读数噪声差出十倍。2.5 供电与参考电压的稳定策略ADS122U04 的测量精度最终取决于电压基准和 IDAC 电流的稳定性。如果基准漂了 100 ppm对应本来就超过 0.25°C。对 HVAC 这种常年运行的系统我强烈建议把基准作为单独的设计重点。项目量产时我没有依赖芯片内部基准而是在板上放了一颗低漂移基准源同时用精密电阻把校准基准固定下来。原型阶段可以直接用内部基准先跑通功能但做环境试验和长期老化测试之前务必确认基准温漂指标否则高温箱体里跑一天读数可能整体偏移。3. STM32F429NI 端 UART 驱动与采样状态机3.1 串口参数与引脚规划ADS122U04 是 UART 从机MCU 作为主机主动发起通信。我用的参数是 9600 波特率、8 数据位、无校验、1 停止位也就是最常用的 8N1 格式。9600 看起来慢但温度数据量极小一次完整读操作不过几个字节完全不影响控制周期。STM32F429NI 的串口资源多我分配 USART3 用于 ADC 通信引脚走 PD8TX、PD9RX这两个引脚在 LQFP100 封装里引到了方便布线的区域。DRDY 信号接一个支持外部中断的引脚比如 PE11用于 ADC 转换完成唤醒。这里建议不要让 DRDY 参与 DMA而是用 GPIO 中断原因是 DRDY 的时序宽度不固定用串口空闲中断配合轮询反而更简洁。3.2 寄存器配置与命令交互流程ADS122U04 的串口协议本质上是一系列命令字节加响应字节。配置寄存器时主机发送写寄存器命令后面跟若干配置数据ADC 收到后回显命令完成写操作。读取转换结果也有专门命令具体命令码和寄存器位定义一定要对着官方手册写我在代码里都用宏定义封装方便后续移值。初始化顺序很关键。我的流程是上电后先等待 ADC 完成自复位大约延时 10ms然后主动发一次同步命令确保总线对齐接着写配置寄存器设置输入多路开关、PGA 增益、IDAC 电流、数据速率最后等待 DRDY 拉低开始周期读数据。3.3 DMA 与空闲中断的配合第一次做这个驱动时我用简单的阻塞式 HAL_UART_TransmitReceive功能没错但 MCU 在等待响应期间被占住系统其他任务频繁抖动。后来改成 DMA 接收加串口空闲中断效果立刻好了。基本思路是主循环定期通过 DMA 发送读取命令然后立即把串口设置为 DMA 接收状态当 ADC 响应数据传完串口数据线出现空闲电平触发 IDLE 中断在中断里通过 DMA 剩余计数推断实际接收长度。这种方式不需要预先知道响应长度天然适配变长协议。代码框架大概是这个思路// 示意代码具体寄存器值和命令码按手册填写 #define ADC_CMD_SYNC 0x08 #define ADC_CMD_RREG 0x20 #define ADC_CMD_WREG 0x40 static void adc_read_result(void) { uint8_t cmd ADC_CMD_READ_DATA; HAL_UART_Transmit_DMA(huart3, cmd, 1); HAL_UART_Receive_DMA(huart3, adc_rx_buf, ADC_RX_LEN); } void USART3_IRQHandler(void) { if (__HAL_UART_GET_FLAG(huart3, UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(huart3); uint16_t len ADC_RX_LEN - __HAL_DMA_GET_COUNTER(huart3.hdmarx); if (len 3) { parse_adc_frame(adc_rx_buf, len); } } }这套结构跑在 180 MHz 的 STM32F429NI 上非常轻松CPU 占用率不到两个百分点。3.4 故障检测与数据完整性温度传感器一旦断线或者短路ADC 会输出满码或零码控制逻辑必须能识别并报警。我做了三件事一是帧超时检测。每次发送命令后启动一个 50ms 软件定时器如果在超时时间内没有收到有效响应就丢弃本次结果并计数。二是连续失败阈值。同一个通道连续三次通信失败就把该通道标记为故障HMI 上报传感器断线而不是继续把上一次的旧数据拿去参与控制。三是范围检查。即使通信正常如果算出来的温度小于 -50°C 或大于 200°C也判定异常因为 HVAC 应用不可能出现这种值。这套机制在项目现场救过我一次工人接线时把其中一路传感器接到 24V 电源线上如果没有范围检查控制器会拿一个巨大的温度值去关压缩机设备可能损坏。现在故障通道会直接旁路并报警系统安全系数高很多。4. 从原始码到℃换算公式、数字滤波与两点校准4.1 原始码换算成电阻ADS122U04 是 24 位 Δ-Σ ADC输出的是二进制补码格式。换算成电压的基本公式是V_in Code × Vref / (2^23 × Gain)其中 Code 是 ADC 原始读数Vref 是参考电压Gain 是 PGA 增益。对于 RTD 测量再结合激励电流就能得到电阻R_rtd V_in / I_idac数学上很简单但工程上有两个细节别忽略一是如果启用了内部 PGA要注意零点偏移到底是在 PGA 之前还是之后这直接影响计算公式二是三线制测量时ADC 读到的电压其实是差分信号公式里隐含了两路电流源的匹配配置时务必保持一致。我实际用的配置是 PT1000 IDAC 250µA PGA Gain 20°C 时读数算出来约 1000.3Ω 左右多出来的零点几欧姆来自引线残差和基准误差这一步先不做修正后面统一靠校准搞定。4.2 RTD 温度公式Callendar-Van Dusen 方程与查表把电阻换算成温度最常用的数学模型是 Callendar-Van Dusen 方程。PT100/PT1000 在 0°C 以上时简化为R R0 × (1 A×T B×T²)其中 A 3.9083e-3B -5.775e-7。在 0°C 以下还要加入三次项修正。如果直接解这个一元二次方程求 T 也不算复杂但工程上我更推荐预生成查表加线性插值把 -50°C 到 200°C 按 0.1°C 间隔生成电阻表运行时二分搜索出区间再做线性插值。这样计算量极小而且查表法天然规避了公式在边界区间的精度损失。对于追求计算速度的场景也可以先粗略估计初值再做两次牛顿迭代float rtd_temp(float r, float r0) { // 初值线性近似 float t (r / r0 - 1.0f) / A; // 两次牛顿迭代收敛到 0.001°C 以内 for (int i 0; i 2; i) { float f r0 * (1.0f A*t B*t*t) - r; float df r0 * (A 2.0f*B*t); t t - f / df; } return t; }实测在 STM32 的 FPU 上这个函数一次调用不到 2µs8 路通道全部换算完毫无压力。4.3 数字滤波让噪声退到读数之外ADC 的原始数据直接看会有几个 LSB 的跳动对应温度大约 0.005°C肉眼看起来就是末位数字在抖。控制策略要的是稳定值不是瞬时值所以必须滤波。我的组合是先做 4 点滑动平均再做一阶低通滤波。滑动平均主要消除周期性的电源干扰一阶低通处理随机白噪声。对应代码大约是这样static float lowpass(float input, float alpha) { static float prev 0.0f; prev alpha * (input - prev); return prev; } // alpha 取 0.2~0.3对应时间常数约 1~2 个采样周期要注意的是如果 ADC 数据速率选得高比如 1000 SPS滤波时间常数就要相应加大否则控制回路看到的温度波动仍然偏大。HVAC 系统本身热惯性大我把最终输出速率限制在 5 SPS 左右温度曲线平滑、平稳。数据速率的选择也要考虑工频干扰。Δ-Σ ADC 的数字滤波器对 50 Hz 及其整数倍频率有天然抑制选 20 SPS、50 SPS 这类整数率效果更好。如果你的客户都在北美 60 Hz 地区要按 60 Hz 的倍频选择做全球产品时最好把采样率做成配置项。4.4 两点校准把出厂偏差压到系统之外RTD 传感器本身一致性很好偏差主要来自三处基准电压的初始精度、IDAC 电流的离散性、PCB 上电阻的误差。这三者叠加可能造成 0.3°C 甚至更大的偏置所以量产前必须校准。我的做法是两点校准在 0°C 和 100°C 附近各取一个恒温参考让每通道分别记录「实测温度」和「标准温度」然后计算一组线性修正系数。公式就是初中数学的直线方程T_corrected K × T_raw BK (T2_real - T1_real) / (T2_raw - T1_raw)B T1_real - K × T1_raw具体操作时我建议用经校准的二等标准铂电阻温度计作为参考把传感器的感温头绑在一起放进冰水混合物和沸水槽同时读取参考值和本产品读数。数据取稳定 5 分钟后的均值避免热惯性带来的误差。现场不具备恒温槽的朋友也可以退而求其次用高精度电阻箱代替传感器分别在 1000Ω、1385Ω 用电阻箱模拟 0°C 和 100°C读出测量值后算出 K 和 B。这个方法虽然没有覆盖传感器本身的个体差异但至少把 ADC 链路的大部分误差消除了实际效果能到 ±0.1°C 上下。4.5 量纲转换与浮点精度STM32F429NI 带 FPU浮点运算不是问题但存储和通信时还是建议用整数。我把最终温度放大 100 倍变成整数摄氏度也就是 25.34°C 存成 2534一方面方便 Modbus 通信另一方面避免浮点在网络传输中带来的解析麻烦。校准系数本身用浮点计算结果转成整数后做饱和判断防止溢出产生荒谬数据。5. 现场最磨人的三个问题地环路、EMC 与上电时序5.1 地环路电流如何把精度偷走现场调试最典型的现象是实验室里读数稳如泰山一到工地温度值每隔几秒就跳 0.3°C。排查到最后十有八九是地环路电流。HVAC 现场有压缩机、变频器、水泵大功率设备的接地汇流排上往往有不小的噪声电流。如果传感器屏蔽层两端都接地或者控制板与传感器模块之间有多个接地点地电位差就会形成环路电流通过模拟地注入 ADC 的参考地导致读数跳动。解决方法是把接地方式改成星型单点地传感器屏蔽层在控制板一侧接地传感器侧悬空控制板的模拟地和数字地只在电源入口处单点相连如果控制板本身通过金属外壳接地要确认外壳接地点与电路板地之间没有形成大环路。按照这个原则改完后我之前碰到的一处 0.3°C 漂移问题直接消失。5.2 UART 隔离三根线换来安心对于工业应用我强烈建议在 MCU 与 ADS122U04 之间加数字隔离。不是因为芯片不安全而是现场的地电位差可能远超预期。两个设备相距 20 米如果各自接地电位差达到几伏TTL 电平的 UART 信号逻辑就会错乱严重时烧毁引脚。UART 方案在隔离上确实省事从 ADC 到 MCU 需要隔离的只有 TX、RX、DRDY 三根低速信号线选一颗三通道数字隔离器就够。我做的是 ADC 传感器端子与主控板分离的结构中间用 ISO7721 隔离隔离电源用一颗 1W 隔离 DC-DC整个隔离成本不到二十块钱比隔离 SPI 高速时钟线省太多。隔离之后还要注意一个问题隔离器的地不要把两边的地强行连在一起隔离侧的地必须来自隔离电源的输出这样才是真正的隔离。我用示波器测过隔离后共模噪声至少下降了 20 dB数据稳定性肉眼可见地改善。5.3 上电时序与总线复位工程上有个容易被忽略的坑MCU 和 ADC 谁先上电。如果 ADC 已经完成复位并开始转换而 MCU 此时还没有完成串口配置那么 DRDY 引脚可能会拉出一个未定义的电平脉宽后续 MCU 读取时很容易误判。我的处理分两层。硬件上ADC 供电端加了一颗简单的 RC 延时让 ADC 比 MCU 晚 20ms 上电保证 MCU 先把串口和 GPIO 初始化完毕。软件上每次上电后强制发同步命令把 ADC 从任何可能的中间状态拉回已知状态再重新配置寄存器。如果运行过程中出现通信超时不要一上来就发复位命令。先把同步字节发出去让 ADC 重新对齐字节边界大多数情况下能恢复通信。连续多次同步失败才执行硬复位流程而且要等 ADC 重新上电稳定后再配置。5.4 快速故障排查表现象大概率原因检查方法所有通道读数漂移基准电压不稳或电源纹波大示波器看 AVDD 纹波换磁珠滤波单通道读数乱跳该路滤波电容虚焊或 TVS 损坏万用表量输入直流电压补焊读数整体偏高 0.3°C传感器屏蔽层两端都接地改成单点接地通信时而成功时而超时MCU 晶振频率误差偏大检查晶振匹配电容用 HSE 不要用 HSI上电后首包数据为 0ADC 未完成复位拉长上电延时先发同步命令断线后读数满码传感器开路检查端子排和线缆连接这张表基本上覆盖了我在现场遇到过的所有典型故障按图索骥能省掉不少排查时间。6. 实测数据、个人取舍与可扩展方向6.1 批量样机的比对数据样机完成后我用冰水浴和恒温槽做了三批次比对每批 8 路通道参考设备是经过计量的标准铂电阻温度计。以其中一批的数据为例通道传感器参考温度本方案读数偏差1回风 PT100025.36°C25.35°C-0.01°C2送风 PT100042.18°C42.21°C0.03°C3盘管供水 PT100076.52°C76.49°C-0.03°C4盘管回水 PT100070.84°C70.86°C0.02°C5室外补偿 PT10003.45°C3.42°C-0.03°C6备用通道 PT100055.10°C55.08°C-0.02°C7备用通道 PT100088.73°C88.75°C0.02°C8备用通道 PT1000-5.28°C-5.25°C0.03°C这个偏差水平包含了传感器自身的不确定度和恒温槽温度不均匀性已经能满足标称 ±0.2°C 的要求。放到长期运行的机柜里72 小时连续测试的漂移也在 0.05°C 以内说明基准和 IDAC 的稳定性经受住了考验。6.2 如果再让我选一次我仍然选 UART 版本回看这次项目ADS122U04IPWR 最让我满意的地方不是精度数字本身而是它把温度测量这个容易出幺蛾子的模拟环节压缩成了一个可靠的串口外设。做嵌入式系统多年最深的体会是降低系统的不可控因素比追逐峰值性能更有价值。UART 接口让布线和隔离变得简单也让调试人员不需要懂太多 Δ-Σ ADC 的时序细节拿着串口工具就能分析通信问题。如果真要说有什么遗憾就是第一版样机为了赶工期把 IDAC 电流直接固定了后来想调整量程必须改 PCB。现在我会建议所有做类似项目的朋友把激励电流、PGA 增益、数据速率这些关键参数全部留给软件配置哪怕多花一点验证时间也要保住现场调整的灵活性。6.3 这套方案还能往哪里扩展热度电偶测量是自然延伸。ADS122U04 内置温度传感器冷端补偿不需要额外加芯片只要把热电偶信号经过合适的滤波接入 ADC软件里用内部温度传感器读数做冷端修正就能实现 K 型热电偶测量。这对于工业控制器里既有 RTD 又有热电偶的实际需求很有价值。另一个方向是做成分体式采集盒每个采集盒独立完成 4 路温度测量通过 RS485 和 Modbus 协议挂在总线上。由于 ADS122U04 本身就是 UART 接口再外接一个 485 收发器非常自然与主控之间只用两根线就能串联几十路温度点。对于楼宇自控这类点位分散的场景这会是一个比集中式采集灵活得多的架构。