
说实话一开始拿到这个标题的时候我第一反应是ADS122U04IPWR 这颗 ADC 在中文社区里存在感不算高但它在工业温度采集和 HVAC 控制这类场景里其实是一颗相当“省心”的料。再加上 STM32F437ZG 这颗腾挪空间很大的 M4 主控做出来的温度测量系统完全可以应付生产线、风管温度、水系统进出水温度、机房环境监测这些真实工况。这篇文章我就围绕这套组合把一个完整的温度测量方案从选型思路、硬件设计、寄存器配置、软件驱动到校准和排障全部摊开来讲清楚。先说个总体的感受在工业/HVAC 场景里做温度测量难点从来不是“ADC 分辨率够不够”而是“你怎么把传感器 mV 甚至 µV 级别的信号在强干扰的环境里稳定地变成温度数值”。24 位的 ADS122U04IPWR 解决的是“采得准”的问题而 STM32F437ZG 解决的是“算得过来、存得下、还能把数据送出去”的问题。这套组合天然适合需要长时间稳定运行、多路输入、还要和上位机或 HMI 打交道的设备。1. 方案整体设计与思路拆解1.1 为什么是 ADS122U04IPWR而不是常见的 SPI 接口 ADC很多工程师一提到工业级高精度 ADC脑子里的第一选择往往是 AD7793、ADS1247 这类 SPI 接口的器件。SPI 接口普遍、驱动资料多但有个现实痛点当传感器信号远离主控板时SPI 的时钟线和数据线在长距离传输上容易受干扰而且多从机挂接时的片选逻辑会越铺越复杂。ADS122U04 最大的特点是内置 UART 接口。这颗芯片把结果寄存器、配置寄存器全部映射到一个基于地址的串行协议上你用两根线TX/RX就能把它挂到 MCU 的任意一个 USART 上传输距离比 SPI 远得多线序也简单。对于 HVAC 这类要把温度板子分散布置在风管、机房、楼层板卡里的应用场景UART 这种“点对点但距离不怂”的物理层非常实用。再说性能。ADS122U04 是 24 位 Δ-Σ ADC带内部 PGA增益 1 到 128 可编程4 个差分输入通道内部还集成两个精密的 IDAC 恒流源专门用来驱动电阻类传感器。你别小看这个“恒流源集成”的设定这意味着你做 PT100/PT1000 的时候不需要在外面再单独搭一个精密电流源——软件里配置寄存器的 IDAC 使能位电流就出来了。外部电路的 BOM 一下就能砍掉一小块布板面积也省不少。至于为什么选 STM32F437ZG这颗主频 168MHz带 FPU1MB Flash192KB RAM在工业温控器或者 HVAC 控制器的角色里它既能干“定时采集滤波线性化”这种脏活累活也能跑 PID 控制算法、图形化的人机界面、网络协议栈。温度测量只是其中的一个功能模块但它的 USART、DMA、定时器资源足够从容。1.2 工业场景与 HVAC 场景对温度测量的不同要求这里得把两个场景拆开看因为设计重心差很多。工业场景里我们常用 Pt100 或者 K 型热电偶。Pt100 是非线性的需要线性化查表或者多项式拟合热电偶信号小但响应快需要高增益 PGA 放大同时要做冷端补偿。工业环境的干扰源还多变频器、继电器、电机启停这些都会在传感器线上感应出共模噪声。所以你在设计时ADC 的输入滤波、供电隔离、屏蔽层接地就都得考虑进去。HVAC 场景则更偏向 Pt1000、NTC 热敏电阻和温度变送器。温度范围基本集中在 -20℃ 到 150℃ 这个区间对量程的绝对精度要求不像工业计量那么夸张但是要求长时间稳定、一致性好、成本可控。通风管道、风冷盘管、换热站水温、室内温控面板这些位置往往要求传感器数据能直接进控制器参与风机盘管的 PID 调节不允许 ADC 输出有明显的跳变或者漂移。ADS122U04 在两个场景之间有一个很舒服的中间地带24 位分辨率给了你充足的“余粮”。比如用 PT100 时即便 PGA 增益只需要 8 倍也能轻松分辨 0.01℃ 级别的变化。真正的精度瓶颈往往在传感器的标定、基准电压源的温漂和 PCB 布局上——所以后面我会把参考电压、滤波电容、校准流程这些容易被忽视的细节单独讲。2. 硬件电路设计与关键参数分析2.1 传感器接法与 IDAC 恒流源配置ADS122U04 的四个差分输入通道 AIN1/AIN2、AIN3/AIN4 可以灵活接法你可以做两组三线制 RTD也可以做成两路单端热电偶加一路 RTD 的混搭。但不管怎么接传感器信号的连接方式决定测量的总误差。以最常见的三线制 PT100 测量为例。三个引脚里两根线分别接到 AIN 的正负输入端另一根线连的是屏蔽层或地。为什么要搞三线制因为实际工业现场传感器导线动不动就是几米甚至几十米导线电阻本身会带来误差。如果只接两根线导线电阻会直接串联进电桥或分压网络里线一长、温度一变读数就飘了。三线制的核心思路是让恒流源的电流路径尽量对称把导线电阻的影响在差分测量里抵消掉。ADS122U04 的 IDAC 有两个通道可配置为 250µA 到 1500µA 的恒流输出。对于 PT100我一般选 500µA 或 1mA。注意电流越大传感器自热效应越明显PT100 在 1mA 下大约有 0.05℃ 的自热温升在要求更高精度的时候需要降下来。电流越小信号幅度越小对 PGA 的噪声要求就更严所以这里存在一个经典的权衡。如果是 PT1000阻值大、信号本身就够大我通常直接用 250µA 的激励电流这样即使传感器到了 300℃对应阻值约 2120Ω满量程信号也就 0.5V 出头配合 PGA 倍数不需要太高就能精确测量同时自热几乎可以忽略。HVAC 场景里用 Pt1000 居多也是这个原因——阻值高、信号好、自热小、导线电阻影响相对低。2.2 外部基准电阻与比例式测量的优势这是我在实际项目里比较看重的一点RTD 测量一定要做“比例式测量”不要用绝对电压基准。做法是选一颗高精度低温漂电阻 RREF连接到 IDAC 的电流路径中同时把 RREF 的电压接到 ADC 的外部参考输入端 REFP0/REFN0。这时 ADC 的转换结果等于code (V_RTD / V_REF) * 2^23而 V_RTD I_IDAC * R_RTDV_REF I_IDAC * R_REF。两个电压相除时同一个恒流源的电流项会被抵消掉。也就是说IDAC 的绝对电流精度、电流随温度的漂移都不会影响最终测量结果。测量值只取决于 RTD 与 RREF 的比值而 RREF 是一颗你能买到的 0.1% 甚至 0.05%、温漂 5ppm 的精密电阻——这个精度指标容易做到而且成本可控。RREF 的阻值选择要匹配电流源和 PGA 量程。我用 1mA 电流配 2kΩ 的 RREF基准电压就是 2VPGA 增益选 8 倍时满量程输入 ±250mV对应 PT100 在 1mA 激励下约 250Ω 的量程覆盖 -200℃ 到 600℃ 都够。如果你的应用温度范围窄比如 HVAC 只测 0℃ 到 100℃那可以把 RREF 换成 1.5kΩ、把 PGA 调到 16 倍分辨率会进一步上升量程依然安全。2.3 电源与滤波设计的一些实操细节ADS122U04 的模拟电源 AVDD 我用 3.3V数字电源 DVDD 也接 3.3V但要通过磁珠或 10Ω 电阻隔离避免 MCU 的数字噪声串进模拟部分。这个细节很多人不注意直接把 ADC 的 DVDD 接到板上的 3.3V 电源轨上结果测量数据在 10bit 位权上蹦迪找了半天原因其实是电源没隔离。还要注意 REFN0 和 AIN 输入的回流路径。我习惯在 ADC 的电源引脚、基准引脚和输入端各放一个 0.1µF 的 X7R 电容同时在靠近电源输入的地方放一个 10µF 的钽电容做低频储能。传感器线进来之后我会先过一个简单的 RC 低通滤波电阻按传感器激励电流算好压降电容选择 0.1µF 到 1µF 之间。这个滤波主要不是为了滤高频而是抑制 50Hz 工频干扰和高频共模噪声给 ADC 一个更干净的差分输入。RC 的截止频率不要设太低否则温度响应会变慢一般取几十 kHz 到几百 kHz 之间比较合理。STM32F437ZG 部分USART 引脚用普通的 GPIO 复用即可但建议在 TX、RX 线上串联 33Ω 到 47Ω 的电阻用于阻抗匹配和限流。UART 波特率这里不用跑太快9600bps 或者 19200bps 足够。ADS122U04 的输出速率最高也就 2000SPS你波特率再高传感器信号带宽也用不上反而增加误码风险。实测下来 9600bps 在 1 米到 3 米的板上走线距离下非常稳。3. 软件驱动与数据采集实现3.1 ADS122U04 的串行通信协议要点ADS122U04 的 UART 命令帧遵循一个特定的格式前导字节 地址字节 命令字节 数据字节 校验字节。我这套系统只用一颗 ADC所以把地址设为默认地址即可。但要注意地址字节和命令字节的顺序不能搞错ADC 会把收到的帧和本地地址做比对如果地址不匹配后续命令直接被丢弃。典型的数据读取流程是发送写寄存器命令配置 MUX、PGA、IDAC、采样速率 发送启动转换命令 等待 DRDY 引脚拉低或用轮询状态寄存器 发送读取数据命令接收 3 字节的 24 位转换码DRDY 引脚要不要接我的建议是接。STM32F437ZG 的中断资源很充裕把 DRDY 接到一个下降沿触发的外部中断引脚上数据准备好之后 MCU 立刻去读理论上可以做到“零延迟采样”。如果不方便接中断也可以在主循环里定时查询状态位但开机到第一次转换完成的那段时序要小心处理我后文会在常见问题里展开。3.2 寄存器初始化与常用配置参数这里给一套实测过的配置针对 PT100 三线制 1mA 激励 8 倍 PGA参数配置值说明MUX 通道AIN1/AIN2 差分接 PT100 传感器PGA 增益8满量程约 ±250mV对应约 250ΩIDAC1 电流1000µA激励电流经 RREF 后到 RTDIDAC2 电流关闭三线制时不需要第二个激励源RREF 电压基准外部 RREF用精密电阻做比例基准采样速率20SPS同时开启 50Hz/60Hz 抑制滤波模式连续转换配合数字滤波读取采样速率这里重点说下。ADS122U04 内部有一个数字滤波器在 20SPS 这个档位它能把 50Hz 和 60Hz 的工频干扰同时压掉很深的量。工业现场那些变频器、工频磁场干扰恰恰都落在 50Hz 附近。我做过对比测试同一套硬件20SPS 比 1000SPS 的读数稳定程度高一个数量级。温度是慢变信号20SPS 完全够用所以为了抗干扰牺牲一点输出速率绝对是划算的。温度值转换公式为t (code_RTD / code_REF) * R_REF得到 R_RTD 之后再用查表法或 Callendar-Van Dusen 公式转换为温度。STM32F437ZG 的 FPU 跑浮点计算非常快我通常在 MCU 里存一张 PT100 分度表按 1℃ 间隔查表后做线性插值误差可以被压到 0.02℃ 以内。如果你嫌查表占 FlashMCU 的 1MB Flash 完全足以存一张 1℃ 分度表根本不用犹豫。3.3 STM32 侧 USART 数据搬运与解析STM32F437ZG 和 ADC 之间是 UART 单线半双工式的交互MCU 发送命令、ADC 回复数据帧。这里有一个关键点——USART 的 RX 引脚收到的并不只是干净的转换结果它收到的是一整帧包含地址、数据、校验的报文所以必须做状态机解析。我的做法是把 USART 配成 DMA 接收收到一个完整的 OK 字节长度之后触发 IDLE 中断然后在 DMA 缓冲区里解析帧。这样做的好处是MCU 在 20SPS 的采样率下每一帧数据之间的间隔有 50msDMA 接收不会占用 CPU 太多时间CPU 可以去跑 PID 或者 HMI 刷新。解析帧时先用校验字节验证数据完整性再做数据类型转换// 伪代码示意数据帧解析 uint8_t buf[8]; uint32_t code (buf[2] 16) | (buf[3] 8) | buf[4];注意 ADS122U04 的转换码是二进制补码形式。如果读出来是负电压比如热电偶接反或者冷端补偿计算需要你需要对 code 做符号扩展否则直接带入公式算出来的温度会完全错乱。这个坑我在测试的时候撞过一次调试半天最后发现是没做符号扩展。4. 温度换算、线性化与标定校准4.1 从 ADC 原始码到温度的完整链路很多人拿到 ADC 的 24 位码之后直接查公式就完事了但完整链路至少有三步第一步把原始码转换成电压比例。用比例式测量时这步可以简化成“原始码与 RREF 的比值换算”不需要关心具体的绝对电压值。第二步把阻值换算成温度。对 PT100 这种铂电阻我用 IEC 60751 标准里的 Callendar-Van Dusen 公式或者 1℃ 间隔的分度表插值。对 NTC 热敏电阻我一般建议直接用 B 值公式但 NTC 的一致性差批量生产最好做两点校准。第三步考虑传感器自身的误差。PT100 的 A 级精度是 ±0.15℃B 级是 ±0.3℃HVAC 里很多用的是 B 级。B 级传感器配一个 24 位 ADC系统精度瓶颈绝不是 ADC而是传感器本身。所以如果你想提高整机精度在传感器选型上花钱比换更高端的 ADC 更有效。// 查表 线性插值的温度换算 float pt100_res_to_temp(float res) { // 通过二分查找找到相邻的两个分度点 // 使用线性插值计算温度 return temp; }4.2 零点校准与两点增益校准的方法温度测量的标定是整个系统误差控制的最后一段。出厂标定时我一般做以下几项零点校准把输入端短路记录 ADC 的输出偏移码将这个偏移码作为固定偏差在软件里减去。这个操作补偿的是 ADC 自身的输入偏置电压和 PGA 失调误差。增益校准用一个高精度标准电阻箱接到传感器端分别设置两个阻值点比如 100Ω 和 200Ω读取 ADC 码然后计算实际增益斜率更新软件里的校正系数。做完这一步PGA 的增益误差可以压到很小。室温校准对冷端补偿用。ADS122U04 内部有温度传感器但内部温度传感器测量的是芯片附近的温度不是热电偶冷端处的温度。如果你用热电偶冷端探头应该放在端子排旁用独立的精确温度传感器读取专门做冷端补偿。HVAC 的大批量产品标定不可能每一台都做零点增益所以很多做法是只在产线做一次室温单点补偿把系统误差在这个点附近修平。精度要求不高的应用±0.5℃ 足够这种简易标定方案是划算的。真正要求高就老老实实上标准温度槽做两点或三点校准。4.3 滤波与抗工频干扰的软件手段硬件 RC 滤波只是第一层软件上还要补一刀。我常用的是滑动平均滤波和一阶惯性滤波组合滑动平均窗口取 16 个点或 32 个点用于消除随机噪声然后过一个一阶惯性滤波时间常数按 1~2 秒设置平滑掉最后的残余波动。这个组合对 HVAC 这种场景很友好。温度变化本身是慢变过程你没必要对每一步的瞬时值都做响应。PID 控制器在 1Hz 采样下跑一个时间常数为 30~60 秒的温度环多出来的滤波延迟大概率不会引起振荡。相反如果不对测量值做滤波PID 会把传感器噪声当作真实温度变化来响应风阀、水阀就会频繁动作控制器寿命和舒适度双双受损。一个技巧用滑动平均滤波之后保留原始码和滤波值的差异。当这个差异持续大于某个阈值比如等效 1℃时说明传感器可能损坏或者线路断线了可以在上位机或者人机界面上直接报“传感器异常”。这个功能在工业现场非常实用比定期人工巡检靠谱得多。5. 常见问题与排查技巧实录5.1 读数漂移、归零异常和突变我实际调试中遇到的最搞笑问题是刚上板的 ADC 读数在每 50ms 内跳动达 ±0.5℃。排查下来居然是 STM32 的 USART 和 ADC 共享了同一个接地回路数字噪声全部灌进模拟地。解决方法是把 AGND 和 DGND 单点连接通过 0Ω 电阻跨接同时把 ADC 的 AGND 单独拉到电源星型接地点。这类问题在工业设备里非常容易出现尤其是当你用同一个 DC-DC 模块同时给 MCU 和 ADC 供电时。另一种常见情况是读数差一个固定偏移。比如用 PT100 测 0℃ 冰水混合物标准值是 100.00Ω读出来却是 100.45Ω。这大概率不是 ADC 的问题而是 RREF 电阻本身的偏差。你选的 0.1% 电阻在 25℃ 下误差也是 ±2Ω2kΩ*0.1%对 PT100 来说2Ω 差不多相当于 5℃ 的误差。所以 RREF 一定要选高精度低温漂电阻而且最好在软件里把 RREF 的实际标定值写进去而不是用标称值。5.2 通信帧偶尔丢失或解析失败STM32 的 USART 在 9600bps 下接 ADS122U04偶尔会出现在连续运行几小时后丢帧。后来查出来是 DMA 循环模式下缓冲区分界处出了竞态问题。解决方案有两个要么把 RX DMA 设成正常模式一次一帧每帧接收完成后手动切换缓冲区要么把 DMA 缓冲区设成两段交替模式在 IDLE 中断里判断收尾位置再复制数据。MCU 资源这么充裕直接用两段缓冲区交替是最省心的。另外一个通信坑是ADC 上电后如果 MCU 提前发命令会没有响应。ADS122U04 上电后需要大约几毫秒的稳定时间。我建议在代码里做一个上电延时等一个 10ms 之后再发配置帧并且在首次发送失败后做三次重试。每次重试之间间隔 5ms。这样程序就能扛住上下电时序不固定的电源设计。5.3 常见问题速查表现象可能原因处理建议读数剧烈跳动模拟地/数字地混合供电噪声大单点接地AVDD 加 RC 滤波电源轨分离读数整体偏高RREF 实际阻值偏大万用表实测 RREF软件参数改为实际值读数偏低且线性差传感器接线错误或导线长改用三线制用 IDAC2 补偿线电阻0℃ 附近读数跳变PGA 增益设置过高输入饱和调低 PGA 倍率或增大 RREF 参考电压上电后无响应时序未满足或地址不匹配加延时重试核对 UART 帧格式温度响应慢RC 滤波截止频率太低调整 RC软件滤波窗口减小这些表格里的问题每一个我都真实撞过。经验就是高分辨率 ADC 的调试难点通常不是“位数不够”而是你周围的“物理世界”会从各个方向给你增加噪声和误差。电源、地、接线、传感器探头位置每一项都会影响最终精度。拿着 ADS122U04 这种档位的 ADC你花在系统级抗干扰上的时间往往比重写好驱动代码的时间还长。6. 一个小项目落地后的直观感受最后做个收尾。ADS122U04IPWR 和 STM32F437ZG 这套组合在我做的一台小型换热站控制器里跑了半年多24 小时连续采集两路 PT100 和三路 Pt1000配合 20SPS 采样和软件滤波温度数值在 0℃ 到 90℃ 区间内稳定跳变不超过 0.03℃。相比以前用 SPI 接口 ADC 独立恒流源的设计这版板子 BOM 少了两个运放和一路基准源布板面积小了三分之一调试周期缩短了一半以上。要说它的不足UART 通信在超长距离10 米以上传输时终究不如 RS485 可靠但那时你本来也会考虑转成总线形式传输ADC 到 MCU 这一段近距离 UART 反而更简洁。这个方案的定位不是“跟基准源精度死磕”而是在普通工业环境下迅速获得稳定、可靠、可批量复制的温度数据ADS122U04 的集成度和 STM32F437ZG 的算力恰好把这个平衡点拿捏得刚刚好。如果你也在做类似的控制器或者设备这套“ADCMCU”的架构可以直接拿去参考省下的调试时间够你多睡好几个好觉了。