做工业温度测量尤其是 HVAC 里的冷媒管道、风道温度和变频器柜内发热设备表面温度这种活很多人第一反应是选个铂电阻再配一颗调理芯片。但真正画过几次板子你就会发现传感器选 PT100 还是 NTC 其实不纠结真正让人头疼的是后级信号链和主控之间的连接方式。我最近一个项目要同时测两路热电偶和一路 PT100主控选了 ST 超值系列的 STM32F100ZE前级 ADC 定了 TI 的 ADS122U04IPWR。这颗 24 位 delta-sigma ADC 自带 UART 数字输出和 STM32F100ZE 之间只走两根线就把模拟前端、激励源和数字化采样的脏活全包了。这篇文章把整套方案从选型逻辑、硬件电路、通信协议到标定实测的完整链路捋一遍给正在做工业过程仪表或者 HVAC 温控、也准备用这两颗料的朋友当个参考。1. 为什么是 ADS122U04 STM32F100ZE一套务实的工业测温选型1.1 ADC 选型时绕不开的三个痛点工业温度采集跟实验室环境完全是两码事我踩过的坑基本可以归纳成三类。第一分辨率不够。STM32F100ZE 片内那个 12 位 ADC测 0 到 100 度的 PT100满量程压降也就 400mV 上下12 位量出来一个 LSB 对应大约 0.1 度看着还行可一旦传感器信号只有几毫伏比如 K 型热电偶在常温附近的温电系数大约 40µV/度12 位 ADC 直接就废了。第二共模干扰和噪声太凶。工业现场电机、变频器、继电器一开合信号线上感应出来的噪声比你传感器本身的信号还大没有可编程增益放大器和差分输入根本压不住。第三接口和布线。传统的独立 ADC 多是 SPI 接口SCK/MOSI/MISO/CS 四根线起步在多路传感器、多从机板卡上排线非常痛苦电气隔离也更麻烦。ADS122U04IPWR 恰好把这三个问题一起解决了。它是一颗 24 位 delta-sigma 架构的 ADC内部带了 PGA增益从 1 做到 128 可配这意味着热电偶那点µV 级信号进来先在芯片内部放大再做模数转换分辨率根本不用担心。它还有两个可编程激励电流源叫 IDAC输出 50µA 到 1500µA专门给 PT100 这类电阻型传感器做激励不需要额外的恒流源电路。更让我看重的是它的通信接口只有一根发送脚一根接收脚UART 协议物理层干净随便一个隔离芯片就能拉远距离。1.2 STM32F100ZE 在这套方案里到底负责什么很多人觉得 STM32F100ZE 是入门级 Cortex-M3主频只有 24MHz干不了什么重活。但在这个项目里它反而是很合适的选择。温度测量的计算量核心是 RTD 线性化多项式和热电偶的温度-电压反查表这些运算虽然有浮点但 24MHz 主频配合硬件乘法器单次查表和插值也就几十微秒完全够用。F100ZE 属于 Value Line 超值系列但外设给的很大方LQFP144 封装提供了丰富的 USART、SPI 和 GPIO后续要接 LCD、RS485、以太网口都有足够引脚。我选择 F100ZE 的另一个原因是它的生态和经济性。这颗料在通用市场流通很多年固件库和例程非常成熟我团队里新来的工程师也能快速上手。整套方案算下来主控加 ADC 的物料成本比用一颗带高精度模拟前端的高端 MCU 还便宜而性能上 24 位 ADC 反而是独立的后面标定好了精度完全可以对标很多商用温控仪表。1.3 为什么 UART 比 SPI 更适合这类应用ADS122U04 名字里的 U 就是 UART 接口版本与它对应的 ADS1220 是 SPI 接口。当初选型时我专门对比过这两个型号。SPI 接口的好处是速率高可以到几 Mbps 甚至更高适合高速采集但温度信号本身就是缓变信号2000SPS 的采样率对温控来说已经是天花板了115200bps 的 UART 在 20SPS 数据率下毫无压力一帧 3 字节数据加命令头尾整个链条非常轻松。更关键的是 UART 在系统集成上省事。第一只需要 TX、RX、GND 三根线走线、接插件、线束成本都降低第二如果现场需要隔离UART 隔离比 SPI 简单得多光耦或者数字隔离器都是现成的第三F100ZE 的 USART 资源比 SPI 多分配起来灵活。实际项目里我把 ADC 的通信挂在 UART2主控的调试串口在 UART1两个串口互不打扰调试时可以直接抓 ADC 的原始码流好用得很。2. 硬件设计传感器接入、基准源与保护电路的关键细节2.1 热电偶、RTD、NTC 三种传感器怎么接到 ADS122U04ADS122U04 有四路模拟输入通道 AIN0 到 AIN3可以配置成差分对或者单端我项目里同时接了 K 型热电偶和 PT100实际是这么分配的。热电偶是差分小信号我把它接到 AIN0 和 AIN1 上。K 型热电偶的输出电压范围大约从 -6mV 到 55mV取决于测温区间为了在常温段拿到足够的精度PGA 增益设在 32 或者 64 比较合适。热电偶本身没有激励需求但它的输出阻抗很低不会给 ADC 带来负载问题需要注意的反而是共模电压。热电偶悬挂在工业设备上时两根引线的对地共模电压可能不稳定所以我在 AIN0 和 AIN1 对公共点分别接了一个 1MΩ 左右的偏置电阻把输入共模拉到芯片允许的范围内防止输入超出 PGA 的共模范围后读数跳变。PT100 我接在 AIN2 和 AIN3 上用三线制接法避免引线电阻直接串进测量回路。三线制需要一个 IDAC 电流源比如 500µA 或者 1mA流过 PT100 和两条引线再用一根单独的引线感知 PT100 另一端的分压点接入一个通道这样电桥就把引线电阻的影响抵消掉了。ADS122U04 有两个 IDACIDAC1 接到 RTD 电源端IDAC2 接到参考电阻网络做匹配两路电流源大小一样只要引线规格一致压降误差基本抵消。这里有个细节500µA 激励下 PT100 在 100°C 时也就产生约 65mV 信号PGA 增益 8 就行要是用 1mA100°C 时约 154mV增益 4 就够。激励电流越大信噪比越高但自热效应也越明显PT100 在这个电流下自热约 0.1°C工业场合可以接受。至于 NTC 热敏电阻它的接入方式和 PT100 不太一样需要一个分压电阻。ADS122U04 可以工作在单端模式比如 NTC 串联一个固定电阻接到 AVDD分压点进 AIN再用另一个通道测一下 AVDD 的实际电压做比例计算。我这次 HV AC 环境监测里用了一片 NTC 做辅助环境温度就是这个接法。2.2 比例测量原理与外部基准电阻设计ADS122U04 内部有 2.048V 基准电压源但做电阻型传感器测量时强烈建议用外部基准电阻做比例测量。道理很简单内部基准源虽然稳定但它的绝对精度受温度影响而比例测量可以把基准源的误差抵消掉。具体做法是在 IDAC 电流通路上串联一颗精密电阻 R_BIAS这颗电阻的压降直接作为参考电压 VREF。PT100 上的压降 V_RTD 和 V_REF 是同一个电流源产生的电桥输出的比值 V_RTD / V_REF 就等于 R_RTD / R_BIAS。这样一来即使 IDAC 电流有漂移只要电流是一样的漂移比值不变最终算出来的电阻只取决于 R_BIAS 的准确度。R_BIAS 我用的是 25ppm/°C 精度 0.1% 的金属膜电阻参考电压通过 REFP0/REFN0 引脚接入 ADC。你可以把 R_BIAS 理解成一把尺子尺子准量出来的东西就准其他部分再漂也不影响刻度。设计时需要注意参考电压不能超过 ADC 的允许范围R_BIAS 阻值要匹配电流源。比如 IDAC1mAR_BIAS 选 2kΩ那 VREF 就是 2V留了余地不会超过 AVDD。参考输入两端并上一个 0.1µF 的旁路电容非常必要去掉这个电容在高速转换时读数会有周期性扰动。2.3 电源、去耦和布局这几个容易翻车的地方ADS122U04 是典型混合信号芯片AVDD 和 DVDD 分开供电。我 AVDD 用 3.3V 线性稳压DVDD 直接接数字 3.3V 平面中间用磁珠隔开。每个电源引脚都放 10µF 陶瓷电容加 0.1µF 高频去耦电容模拟差分输入对地各加一个 10nF 电容组成 RC 低通截止频率根据传感器带宽选一般几 kHz 到几十 kHz既抑制高频噪声又不让温度信号失真。布局上最重要的一条模拟地和数字地单点连接并且这个连接点选在 ADC 芯片附近的地焊盘下。千万不要把大电流数字走线从 ADC 下面穿过这会让数字开关噪声耦合进模拟回路。STM32F100ZE 和 ADS122U04 之间的 UART 线尽量短如果必须走长线加个 100Ω 串阻做阻抗匹配。电源入口处我加了一颗 TVS 管做浪涌保护传感器端子进板处也放了 RC 滤波实测在变频器旁边长期运行没出过问题。3. ADC 配置与 UART 协议从寄存器到一帧温度数据的完整链路3.1 UART 通信初始化与自动波特率同步ADS122U04 上电后默认是固定波特率还是自动波特率取决于 M1/M0 两个引脚的电平配置我把它们配置成了自动波特率检测模式因为这样软件上不用预先规定电流家MCU 只要能输出任意常见波特率ADC 自己会校准。自动模式的同步流程很关键许多第一次用的人在这里翻车。MCU 复位后先要把 USART 配成预期波特率然后给 ADC 至少等待 2ms 电源稳定再发一个同步字节 0x00ADC 会基于这个字节的边沿自动识别波特率。注意同步字节发完后必须等待一段时间期间不要往 ADC 发其他命令否则 ADC 可能把后续指令的起始位误认为同步的一部分。我工程里发完同步字节后固定 delay 5ms实测 115200、57600、38400 都稳定。TXD 和 RXD 记得交叉连接也就是 STM32F100ZE 的 TXD 接 ADS122U04 的 RXDRXD 接 TXD共地。3.2 配置寄存器里的关键位ADS122U04 有约十个配置寄存器每个寄存器分配不同功能。配置完成后建议回读一遍确认写入成功这是排查通信问题的基本手段。我常用的配置项和理由如下。输入通道选择和 PGA 增益放在同一组配置逻辑里。对于热电偶通道切换成差分输入增益 32数据率 20SPS 或者 80SPS。温度信号变化慢20SPS 的采样率足够而且数据率越低 delta-sigma 调制器的滤波能力越强50Hz 工频干扰在低数据率下被内置滤波器压得很干净。PT100 通道增益 4 到 8开启 IDAC1 和 IDAC2电流大小设成 1mA。转换模式我配置成连续转换这样 MCU 想取数据随时发读命令就行不用每次触发一次转换。另外把内部温度传感器开起来虽然板子上已经有一路 NTC 环境温度但 ADC 内置温度传感器可以拿来互相校验也能估算芯片结温凌晨和中午数据差太多时能知道是不是芯片自身发热影响了精度。3.3 数据读取与码值换算实战读数据流程不复杂发读数据命令然后连续收 3 个字节MSB 在前。我给 F100ZE 的 USART2 配了 DMA 接收三字节定长缓冲区每次 DMA 完成中断里解析码值。24 位数据是二进制补码正负号需要自己做符号扩展把最高字节的 bit7 扩展成 32 位整型的高位。换算公式是电压 ADC_Code × VREF / (PGA × 8388607)这里注意ADS122U04 的满量程其实是 ±VREF/PGA24 位二进制补码的满量程对应 8388607所以电压等于 ADC_Code 乘以 VREF 除以 PGA 再除以 8388607。因为用了比例测量外部基准VREF 等于 IDAC 电流乘以 R_BIAS。实测时 PT100 的 ADC 码值在 25°C 附近大概是 1000 出头取决于基准电阻阻值这个数值量级对定位问题很有帮助如果读出来接近满量程 800 万大概率是 PGA 增益或通道配置错了。我在代码里把原始码值、换算后的电压和最终温度同时发到串口调试线上开发阶段特别好用看原始码值能快速判断是算法问题还是硬件问题。3.4 一个最小的读写驱动骨架下面这段是我从项目里抽出来的核心读写流程去掉业务逻辑只留通信骨架可以直接移植到 STM32F100ZE 的任意 USART 上。前提是你已经初始化好 USART 的 TX/RX 引脚和波特率。// 读取 ADC 24位原始码值 int32_t ads122u04_read_sample(void) { uint8_t tx_buf 0x1C; // 读数据命令特定型号请查数据手册确认 uint8_t rx_buf[3] {0, 0, 0}; HAL_UART_Transmit(huart2, tx_buf, 1, 10); HAL_UART_Receive(huart2, rx_buf, 3, 20); uint32_t raw (rx_buf[0] 16) | (rx_buf[1] 8) | rx_buf[2]; int32_t code; if (raw 0x800000U) { code (int32_t)(raw | 0xFF000000U); // 符号扩展 } else { code (int32_t)raw; } return code; } // 写配置寄存器addr 为寄存器地址0~9data 为写入值 void ads122u04_write_reg(uint8_t addr, uint8_t data) { uint8_t cmd[3]; cmd[0] 0x40 | (addr 2); // 写寄存器命令 地址 cmd[1] 0x00; cmd[2] data; HAL_UART_Transmit(huart2, cmd, 3, 10); }使用这套骨架前最好先读出寄存器默认值存个档方便刷回原配置。4. 线性化、冷端补偿与标定让数字变成可靠温度的关键步骤4.1 PT100 从 ADC 码值到温度的两步换算PT100 的测温原理是电阻随温度近似线性变化但实际是非线性的。拿到 ADC 码值后第一步换算电阻R_RTD ADC_Code / 8388607 × R_BIAS × (1 / PGA)不对这里要仔细。由于是比例测量V_RTD / V_REF ADC_Code / 8388607同时 V_RTD I × R_RTDV_REF I × R_BIAS所以 R_RTD ADC_Code × R_BIAS / 8388607。PGA 增益的影响已经在码值里了公式里不用再乘。有了电阻值第二步用查表法或者 Callendar-Van Dusen 方程换算温度。Callendar-Van Dusen 方程是工业上最常用的换算方法核心公式分两段0°C 以上用 Rt R0 × (1 A×t B×t²)0°C 以下再加 C×(t-100)×t³。PT100 的系数 A3.9083e-3B-5.775e-7C-4.183e-12这个方程在 -200°C 到 850°C 范围内精度很高。单片机上不建议直接浮点算三次方程可以预先把 -50°C 到 150°C 的电阻-温度表烧进 Flash每 0.5°C 一个点运行时代码值先换成电阻再二分法查表加线性插值误差小于 0.05°C速度几乎为零。我用的是后者省得在线程里做浮点开销。4.2 热电偶的冷端补偿是绝对绕不开的细节热电偶测量的是热端和冷端之间的温差电势冷端如果逗留在 25°C读数就得加上 25°C 对应的电势才能得到真实温度。那张 NIST ITS-90 多项式查表表本质是热端 0°C 参考的标准表所以冷端补偿是必需步骤。我的做法如下在 ADS122U04 附近的接线端子排位置贴一片板载温度传感器我用的是一片精度 0.5°C 的本地 NTC接在 ADC 的一个单端通道上。每次获取热电偶的热电势后先查表得到冷端温度 Tc再把 Tc 换算成对应的热电势 E_cj加到 ADC 测得的 E_measured 上得到补偿后的 E_total再查表反算出真实温度。这个流程很多人都会但容易忽略一个细节冷端传感器和被测温点之间有没有热阻如果热电偶端子是金属外壳接在机柜里冷端传感器的读数会被机柜温度带偏导致同样环境下不同时段误差能差 1 到 2°C。我后来把 NTC 用导热硅脂贴到接线端子金属块上再做了隔热罩一致性明显改善。K 型热电偶的温电系数常温下约 41µV/°C这意味着 0.1°C 的分辨率需要能分辨 4µV。ADS122U04 增益 64 的 LSB 是 2.048V / 64 / 8388607 ≈ 3.8µV刚好够。如果还想更稳可以在软件里做多次采集中值滤波把噪声平均掉再查表。4.3 两点标定和误差拆解的实操思路再好的元器件也有离散性批量出货前必须做标定。我每个通道都做零点加满量程两点标定。零点用精密电阻箱模拟 PT100 的 100Ω也就是 0°C记录 ADC 码值满量程用 138.5Ω 对应 100°C再记录码值。两点连一条线算出增益系数和偏移量写进出厂参数区。热电偶通道没法直接用电阻箱模拟就接校准源输送到若干毫伏电压反推增益误差补偿系数小通常 PGA 本身精度已经够好主要还是补偿偏移。标定完再拿到恒温槽里做盲测数据大概是这样的设定温度(°C)PT100 通道实测(°C)热电偶通道实测(°C)0.00.030.0825.025.0225.1550.050.0150.2280.080.0480.31PT100 通道基本能控制在 ±0.1°C 以内热电偶要看冷端补偿的精度±0.5°C 以内完全可接受。如果热电偶通道误差出现固定偏大多半不是 ADC 的问题去检查冷端传感器贴得紧不紧、有没有被其他热源烤到。5. 实测精度与现场抗干扰表现5.1 全天候运行下的温度稳定性和读数行为整机装进控制柜在车间里跑了一个星期车间里有变频器、伺服电机、电焊机轮番工作。我监控三个点电机轴承温度PT100散热器表面温度K 型热电偶以及柜内环境温度NTC。结果是 PT100 通道在整个测试期间最大波动 ±0.15°C热电偶通道最大波动 ±0.6°C环境温度通道 ±0.3°C。这个表现在工业环境里称得上稳定关键是读了原始码值后发现短时跳动的幅度其实不小是软件滤波扛住了最终输出值。5.2 软件滤波组合滑动平均加中值滤除脉冲干扰工业现场最恶心的是偶发脉冲干扰比如电磁阀一动作信号线上忽然蹦出个 500mV 的尖峰如果平均滤波会把尖峰平摊到好几个点曲线看起来就是一个小鼓包但不会造成误报警中值滤波对这种脉冲最有效。所以我的策略是两级叠加先取 5 个原始采样做中值滤波扔掉异常大或异常小的点再对这串结果做 8 点滑动平均。最终输出带宽比我直接 20SPS 采样低一截但温度显示曲线极其平滑在 0.1°C 分辨率下不会出现跳字。中值滤波在 STM32F100ZE 上实现要注意排序函数别写太笨5 个数用冒泡也行我直接手写了 5 个元素的交换排序Flash 占用极低。采样线程每 100ms 取一次中值滑动窗口每秒更新一次这样既保证实时性又不让缓变温度曲线失真。HVAC 温控对实时性要求不像电机控制那么苛刻1 秒的显示延迟完全没人能察觉反而觉得温度更稳了。5.3 长跑期间的漂移观察和参考电阻的影响一周数据看下来PT100 通道没有出现明显的单调漂移昼夜温差对 ADC 码值的影响约等于零因为比例测量把基准误差抵消了。反倒是环境温度通道的 NTC 分压电路用的是 AVDD 直接做基准没有比例测量早上和半夜读数能差 0.5°C这就是没用比例测量的代价。第二个项目我直接把 NTC 那一路也改了用同一个 IDAC 电流源激励 NTC 和参考电阻一致性立刻上来。所以说能比例测量的通道尽量别偷懒用绝对电压测量这是工业测温的第一原则。6. 调试中的坑与排查思路6.1 UART 通信偶发失败问题出在上电时序第一批样机调通信时大约每十次上电有一两次 ADC 完全无响应发送配置命令石沉大海。排查过程比较典型我先用示波器抓 ADC 的 TXD 脚发现完全无输出说明 ADC 可能没正常启动。再查电源时序STM32F100ZE 的复位时间比 ADC 的 DVDD 上电快MCU 已经在发同步命令时ADC 的模拟部分可能还在复位状态。把 ADC 的 RESET 引脚接到一个 GPIO软件流程改成MCU 先拉低 RESET等待 10ms释放再等 10ms然后才发同步命令。就这个改动几十次上电再没失败过。6.2 读数左右蹦跳排查 PGA 增益和参考电容有一路热探偶通道读数在常温附近无规律跳动从 23°C 跳到 29°C 又跳回来幅度远超正常噪声。先怀疑传感器损坏换新热电偶无果再怀疑 PGA 增益配置被回写错误读寄存器发现配置正确。最后用示波器看 AIN 引脚波形看到高频噪声和周期性毛刺于是我用一个 RC 低通把带宽压到 30Hz毛刺明显消失。后来分析原因是热电偶引线在这个通道旁边走过一段变频器输出线的辐射区域感性耦合进来高频共模噪声。PGA 增益越高带内噪声越敏感所以高增益通道一定要在输入脚就近放滤波电容电容不能只放在原理图上而不放板子靠近端子处。6.3 热电偶开路误判干扰还是真断线热电偶在工业现场氧化或者振断是家常便饭必须检测出来。ADS122U04 内置了传感器开路检测功能通过内部电流源上拉下拉把开路的通道强制拉到满量程或零刻度MCU 通过判断码值是否超出合理范围就能报故障。我用 ADC 的码值范围做边界判断热电偶正常时增益 64 码值不可能接近正负满量程一旦码值跌到 ±800 万级就判开路同时配合 3 秒内连续 N 次超界才报警避免瞬间干扰误报。这个逻辑在试机第 3 天正确报出了一次热电偶端子松动挺给力。6.4 STM32 引脚默认状态对 UART 的影响还有一个隐蔽的坑STM32F100ZE 的 USART 引脚如果被启动代码里的 GPIO_Init 覆盖成推挽输出或者开漏输出电阻上拉状态不对UART 电平会出现边沿变缓尤其在 3.3V 系统里信号完整性问题会导致 ADC 偶尔识别到错位字符。我排查过至少两小时才发现是 GPIO 配置时把 TXD 口配成了开漏输出导致驱动能力不够。后来统一改成复用推挽输出波特率再拉回 115200问题彻底消失。这套方案的适用边界和后续扩展空间如果你也打算在工业设备或者 HVAC 控制箱里做温度巡检我必须诚实说一句这套 ADS122U04 STM32F100ZE 的组合适合到 32 路以下的模拟输入更多通道时就该考虑 ADS122U04 的多片级联或者上专用 RTD 采集卡了。单片方案在小批量、混合传感器类型、成本敏感的场合非常有竞争力。后续想扩展的话我建议走这几条路一是把 ADC 的 UART 拆到隔离侧配合 RS485 总线做分布式温度采集二是加一路 SD 卡或者上位机协议把标定补偿曲线做成可配置三是把 F100ZE 换成带 CAN 外设的型号直接挂到工业控制网络里这套 ADC 端的逻辑不用动只换主控就能上线。做混合信号项目我最大的体会是把精力的 70% 花在电源、布局和接地这三件基础事上算法反而是相对老实的一部分。等这三件事做好了你读到的 ADS122U04 数据就会像教科书一样干净。