接手这类测温项目时,我第一反应往往不是“这颗 ADC 精度如何”,而是“现场线缆多长、干扰多大、校准怎么做、上位机怎么通讯”。工业炉控和 HVAC 机组看着是两个方向,但底层的温度采集逻辑其实是通的。这套基于ADS122U04IPWR和STM32F756ZG的方案,可以说把“高精度采集”和“强处理能力”两件事分开干了,文章就是想把设计过程中的关键决策、电路细节、固件链路和现场校准经验一次性讲透,给准备上手做工业级或 HVAC 温度测控的工程师一个可以直接参考的路线。
1. 项目背景:从现场测温痛点看,为什么这个组合成立
1.1 工业装备和 HVAC 机组里“测温”到底难在哪
先说我在现场常遇到的情况:一台注塑机有 6 个加热区,热电偶信号线从加热圈拉到控制柜,距离通常三五米,中间还贴着变频器或接触器的线槽;HVAC 项目里冷冻水供回水温度、风管温湿度、压缩机排气温度,测点分散在十几米甚至几十米的区域,柜内控制器和传感器之间隔着各种强电骚扰源。
如果只是拿普通单片机直接读热电偶或 RTD,问题非常明确:信号太微弱,K 型热电偶只有大约 40μV/℃,PT100 在 1mA 激励下也只有约 0.385Ω/℃,温漂和噪声很容易把有效信号淹没。传统方案会外接仪表放大器加独立 ADC,但这样电路复杂、校准点多、成本也上去。
这时用一片集成了可编程增益放大器(PGA)、24 位 Δ-Σ ADC、激励电流源和内部基准的芯片就顺理成章了。ADS122U04IPWR正是这类器件,而且它选了 UART 接口而非 SPI/I2C,对于分布式测温场景反而更好布线、更好隔离,这点后面单独说。
1.2 为什么锁定 ADS122U04IPWR:UART 接口不是随便选的
ADS122U04 属于 TI 的 ADS122 家族,24 位分辨率,自带 4 通道输入多路复用器、PGA、两组可编程激励电流源,以及用于热电偶冷端补偿的内部温度传感器。从功能上看,它几乎把前端模拟链路的所有关键模块都收进来了,外部只需要少量电阻电容。
真正让我确定选它的理由是 UART 接口。常见的 ADS1220 是 SPI 接口,SPI 在板级通讯没问题,但拉到工业现场就有几个麻烦:时钟线和数据线要严格同步,线一长就容易受干扰;电气隔离时至少要隔离 3~4 根信号线,成本高。而ADS122U04IPWR是异步串口,只靠 DIN 和 DOUT 两根线就能传命令和数据,配合 DRDY 数据就绪引脚做中断触发,隔离时只需要隔两根线,成本明显降低。
它还支持多设备挂在同一条 UART 总线上,配合地址帧实现多点测温,这对 HVAC 项目里“一台控制器带十几个测点”的架构非常友好。加上数据帧自带 CRC 校验,长线传输时的误码问题也能兜底。
1.3 STM32F756ZG 的分工:不只是读数据
ADS122U04 负责把温度信号数字化,但 24 位原始码只是第二步,真正需要算力的是线性化、数字滤波、报警判断和闭环控制。STM32F756ZG 在这里承担的不只是“读传感器”的角色。
STM32F756ZG 是 Cortex-M7 内核,主频能到 216MHz,带硬件 FPU 和 DSP 指令。温度换算里最典型的场景是 PT100 的阻值-温度关系,如果做高精度,需要处理二次多项式甚至 Callendar-Van Dusen 方程,纯用整数运算虽然也能做,但代码可读性和精度调整都很痛苦。有 FPU 之后直接用浮点算,逻辑清晰,实时性也够。
这一颗芯片在外设配置上也比较宽裕,有多个 UART、SPI、CAN 和 USB 接口。我在方案里做了这样的分工:用一个 UART 接 ADS122U04,另一个 UART 走 RS-485 或 Modbus 和上位机通讯,剩余接口留给本地显示、按键和报警输出。F756ZG 的 1MB Flash 和 320KB RAM 也让我不用费心去抠存储空间,哪怕是多个传感器数据一块缓存、加一段历史记录都够用。
2. 硬件接线与外围电路:把 ADC 的压箱底功能真正用起来
2.1 RTD 三线制接法:消线阻的关键是电流源
RTD 测温最常见的坑是线阻。PT100 本身在 0℃ 时只有 100Ω,如果现场走线有 2Ω 接触电阻,测出来直接偏差 5℃ 以上。二线制基本没法用,四线制最准但电缆成本高,所以工业现场最常用的是三线制。
ADS122U04 内部有两路匹配的激励电流源 IDAC1 和 IDAC2,这正好用来做三线制 RTD 的比例测量。接法原理是:让 IDAC1 的电流流过 RTD 和其中一条引线,IDAC2 的电流流过另一条引线,两支电流源大小相等,引线上的压降在 AINP 和 AINN 端相互抵消,ADC 测到的就只剩 RTD 本身的压降。
实际接线时我推荐用外部基准电阻做比例式测量,而不是直接用内部 2.048V 基准。原理是让同一个激励电流也流过一颗精密参考电阻 Rref,再把这个电阻上的电压作为 ADC 的参考电压。这样电源电压波动和电流源温漂会被同时“抵消”,系统精度大幅提升。
以 PT100 为例,激励电流取 1mA,Rref 取 1800Ω,参考电压就是 1.8V。RTD 在 0℃ 时压降 100mV,100℃ 时约 138.5mV,如果 PGA 增益取 16,信号回到 ADC 内部时约 1.6V~2.2V,动态范围刚好。这个参数组合我在两个项目里都用过,实测效果最稳。
2.2 热电偶采样与冷端补偿:内部温度传感器不是摆设
热电偶本身只能测温差,要得到绝对温度必须知道冷端温度。ADS122U04 内部集成了温度传感器,可以直接用在对冷端补偿上,省掉外置 NTC 或 DS18B20。
我通常这么接:热电偶的正负极分别接到 AIN0 和 AIN1,并就近并一个几十 nF 的电容做差模滤波。由于热电偶信号本来就很小,K 型 40μV/℃,PGA 增益建议取 64 或 128。这个电平下,PCB 上任何一点地弹或电源噪声都会被“放大”出来,所以输入走线要短、避开功率线路,这个习惯很重要。
冷端补偿的工程细节是:用 ADS 内部温度传感器测出的温度会被量化成一个代表“板级温度”的值,它和热电偶接头处的实际温度存在误差,通常来源是传感器到接头的热阻。我在设计时特意把热电偶的冷端接头直接压在 PCB 铜箔上,并在铜箔下方铺了一个矩形地岛,目的就是让接头和内部温度传感器处于尽量相同的热环境下。留作原理设计容易,实际装配恰恰要把它当重点来抠。
2.3 UART 电平、DRDY 中断和 STM32F756ZG 的连接
ADS122U04 支持 2.3V~5.5V 供电,我直接采用 3.3V 供电,和 STM32F756ZG 的电平完全一致,不需要电平转换。连接关系很简单:ADS 的 DIN 接 F7 的 TX,DOUT 接 F7 的 RX,DRDY 接一个普通 GPIO,并配置成外部中断输入。
唯一要留意的接线常识是 DRDY 信号。当 ADS 完成一次转换且数据未读时,DRDY 会拉低,这个信号在工业环境中容易串入毛刺,GPIO 上必须加一个 100kΩ 左右的上拉到 VDD,必要时并一个 1nF 滤波电容。单片机侧可以把 DRDY 配置为下降沿中断,一旦进来就启动 UART 读取,这样不会漏数据,也不用反复轮询状态位。
为了长线传输,我还在 DIN 和 DOUT 上各串了一个 22Ω 电阻,靠近接收端再接一个小电容,相当于简单的抗振铃处理。柜内走线 1 米以内完全够用,如果距离更长,就直接加数字隔离器,推荐用 Si8620 或 ISO7720,把 TX、RX、DRDY 一起隔离过去。
2.4 模数电源和 PCB 布局:别让 24 位白白浪费
24 位 ADC 的噪声底非常低,系统里任何一点开关电源纹波都可能把有效位数拉低。ADS122U04 的模拟电源和数字电源我用一颗单独的 LDO 供电,AVDD 和 DVDD 引脚之间用一个 10Ω 电阻做 PI 型滤波,并在每个电源引脚旁边放 100nF 加上 10μF 电容。
PCB 布局上,我坚持几个原则:ADC 下方是实心的模拟地平面,数字信号和模拟信号分区走线;Rref 基准电阻放在离 REFP/REFN 尽量近的位置,用开尔文连接避免走线压降影响基准电压;所有输入信号线走等长、短直路径。这套做法在 PCB 上多花不了多少面积,却能让最终精度有质的差别,值得养成习惯。
3. 通信帧与寄存器配置:把 ADS122U04 调成可以一直吐数据的样子
3.1 UART 帧格式和命令时序
ADS122U04 的 UART 帧核心组成是命令字节加数据字段,如果开启了 CRC,还要在帧尾追加一个 CRC 字节。像读取转换结果这种读操作,单片机先发命令帧,从机准备好后返回数据,整体时序特别好理解。
我建议的通讯参数是:波特率 115200、8 位数据、无校验、1 位停止位。高了没必要,低了影响连续读取速率,115200 对 ADS122U04 的数据速率上限 2000SPS 绰绰有余。需要注意的细节是,从 DRDY 拉低到真正启动读取,中间要给一个 1~2μs 的建立时间,不要 DRDY 一来就立刻发命令,否则偶发读回错误数据。
一个我用得很顺的技巧是:单片机上电后,先把 ADS 的复位引脚拉低再拉高,然后等待至少 10ms,等内部上电复位和自校准结束,再开始寄存器配置,否则第一次读取会莫名其妙失败。
3.2 关键寄存器配置速查
ADS122U04 的寄存器主要是 CONFIG0 到 CONFIG4,下面表格里是我的标准配置思路,具体位段以数据手册为准:
| 寄存器 | 主要配置内容 | 项目中实际设置 |
|---|---|---|
| CONFIG0 | 输入多路复用器、PGA 旁路 | 根据 RTD / 热电偶选通道,PGA 不旁路 |
| CONFIG1 | PGA 增益 | RTD 取 16,热电偶取 64 或 128 |
| CONFIG2 | 数据速率、转换模式 | 20~90SPS 优先,连续转换模式 |
| CONFIG3 | IDAC 开关、内部温度传感器、基准开关 | 激流开、内部温度传感器按需开 |
| CONFIG4 | IDAC 电流、基准选择、CRC | IDAC 取 1mA,基准选外部,CRC 开 |
你可能注意到我把数据速率压到 20~90SPS,而不是直接追求 1000SPS 以上。原因是温度信号本身是慢变量,过高的数据速率只会把更多噪声放进系统,真正合适的是让 Δ-Σ 调制器的数字滤波器把工频干扰也一并抑制掉。90SPS 附近对 50Hz 的偶次谐波抑制已经很理想,工业现场实测噪声明显低于高速档。
3.3 连续转换 vs 单次转换:实际项目中我选哪一种
ADS122U04 有两种转换模式。单次转换模式下,每完成一次转换 ADC 自动进入休眠,功耗低,适合电池或供电紧张的设备;连续转换模式下,ADC 一直工作,DRDY 以固定速率持续拉低,适合需要实时刷新温度的主从结构。
工业炉控和 HVAC 项目几乎都不会缺电,而且控制闭环需要连续温度流,所以我全用连续转换模式。只是在连续转换模式下,寄存器配置或校准相关命令要避开转换进行中的关键时序,最好是先暂停转换、改完寄存器、再重新启动,逻辑上多几步,但比边转边改来得稳。
3.4 CRC 和错误处理:别用“重启大法”糊弄现场
ADS122U04 的 CRC 功能我在长线或隔离方案下必定启用。开启后每个帧都会追加 CRC 字节,单片机接收端需要自行算一遍并比对,不匹配就丢弃该帧并计数。项目里我会记录连续 CRC 失败次数,如果超过阈值,就主动做一次重新初始化,而不是傻等。
做过现场调试的朋友都懂,通讯偶发故障最怕“看起来正常但偶发跳变”,CRC 能把这部分问题抓出来。也提醒一句:CRC 使能在寄存器里打开后,所有读写命令都会变化,代码逻辑里要统一处理,别出现“有的命令带 CRC、有的不带”这种半吊子状态,否则对不上协议,问题极难排查。
4. 固件数据处理:从原始码到温度值的完整链路
4.1 原始数据读取和符号处理
ADS122U04 的转换结果以 24 位二进制补码形式输出。读取时会拿到 3 个字节,比如 b2、b1、b0,首先要判断符号位:如果最高字节的最高位为 1,就把整个数据转成负数。
STM32 端我习惯先把 3 个字节拼成一个 int32_t:
int32_t raw = ((int32_t)b2 << 16) | ((int32_t)b1 << 8) | b0; if (raw & 0x800000) { raw |= 0xFF000000; // 符号扩展 }这个逻辑写起来很简单,但很容易被忽略。如果不做符号扩展,低温场景下会出现“温度越测越低、数值却跳成正数”的怪现象,第一次踩到会非常困惑,多半想不到是符号扩展的问题。
4.2 RTD 线性化:查表法与解析法的取舍
RTD 的阻值和温度不是线性关系,PT100 在 0~100℃ 范围的非线性就有约 0.4℃ 偏差,工业控温要守住 ±0.2℃ 就得做线性化修正。
我的做法分两种设备需求。HVAC 场景比较标准,常用温度范围窄,用查表加线性插值就够了。表格可以按 10℃ 间隔存阻值,两点之间插值误差大概 0.05℃ 以内,而且代码执行极快。工业炉控对精度要求高,我在部分项目里直接用 Callendar-Van Dusen 方程做反算,虽然计算量上去了,但 STM32F756ZG 有 FPU,一次迭代求解也就是十几微秒的事,完全破译得住。
查表法要注意表长和温度范围的匹配,表太粗插值误差大,表太细浪费 Flash。我一般按实际量程取舍,拿 PT100 举例,-50~300℃ 用 10℃ 间隔存 36 个点,整体内存开销很可观,精度也足。
4.3 数字滤波:平均值和限幅滤波的组合
ADC 的 24 位数据再干净,经过工业现场的长线传输后也可能有脉冲干扰。我在固件里做了两级滤波:第一级是限幅滤波,比较当前值和上一次值的差值,如果超过物理上“不可能的变化率”,就把当前值丢弃,改用上一次值;第二级是滑动平均,取最近 N 个有效样本平均。
N 的取值很关键。温度闭环里 N 太大会带来滞后,N 太小滤波效果不好。我用的 N=8,数据速率 90SPS 时等效时间常数约 89ms,对温度环来说既不显得迟钝,又能压住大部分噪声。如果设备有显示需求,我还会再加一轮更低通的中值滤波或更长的滑动平均,但只用于显示、不用于控制,这样控制和显示两套数据各得其所。
4.4 从温度到执行:F756ZG 上的闭环控制与输出
测温之后最终要用到控制上。STM32F756ZG 的算力足够直接跑 PID,不需要外挂控制芯片。PID 的输入是滤波后的温度,输出无非两项:加热设备用 PWM,阀控或变频器用 0~10V 或 4~20mA。F7 的定时器可以很干净地产生 PWM,模拟输出加一颗外部 DAC 或者用 PWM 加 RC 滤波也能满足仪表级需求。
实际调参时我习惯先把积分和微分归零,纯比例往下拉,找到系统开始振荡的阈值,再适当加入积分消除静差。对于 HVAC 水系统这种大惯性对象,微分一般不用太多,否则给一点扰动就开始抖。F7 调试起来很方便,可以把 PID 参数做成运行时变量,通过 RS-485 在线改写,我在现场就是这样一点点调收敛的。
5. 双场景联调:工业现场和 HVAC 项目的实际校验记录
5.1 工业环境:隔离、干扰与长线衰减
第一次把样机装进工业炉控柜时,热电偶读数的波动肉眼可见。原因很简单,柜子里有接触器,动作瞬间产生的尖峰干扰直接耦合进了信号线,24 位 ADC 把这种干扰当作真实信号采了进来。
后续几版我做了三个改动:一是输入线上加了 TVS 管和共模电感,防止外部浪涌直接打进 ADC;二是 UART 侧用数字隔离器完全断开现场和 MCU 的地,避免地环路噪声;三是把 ADS 的输入滤波电容从 10nF 加到 100nF,并在软件里把数据速率降到 20SPS,让片上数字滤波器对高频干扰有更强的抑制。完成这三步后,同样一只热电偶的读数波动从 ±1.5℃ 压到 ±0.1℃,基本达到仪表级表现。
5.2 HVAC 场景:多测点、RS-485 上传与总线布线
HVAC 项目和工业炉控不同,测点分散,且往往要跟楼宇自控系统对接。以前的做法是每个测点单独走线到控制器,测点多时线缆像蜘蛛网一样;而用 ADS122U04 的 UART 总线特性,可以把多个 ADC 节点串在同一根两线总线上,每个节点设一个地址,F756ZG 轮询读取即可。
在实施中,我把每个节点做成一个小模块,模块上带一颗插座式热电偶或 RTD 端子,模块间用 UART 总线串联,末端通过 RS-485 转换成远距离上楼宇平台。F756ZG 的内核和内存跑这种轮询任务很从容,还能顺便做节点报警判断。整个系统比原来的“一测点一接线”方案少了一多半线缆,施工和排查成本明显降低。
5.3 校准与验收:标准温度计对照
再好的硬件不做校准都是白搭。我的做法是准备一个标准电阻箱和一个经过检定的冰点槽,分两步校准:
- 零点校准:把 PT100 接到标准电阻箱,设置成 100Ω,对应 0℃,然后记录 ADC 原始码,差值和理论值的偏移作为零点修正项写入 Flash。
- 满量程校准:把电阻箱设成 138.5Ω,对应 100℃,记录增益偏差,生成增益修正系数。
热电偶方面则借助冰点槽或标准干体炉做冷端和测温两点验证。校准完成后的系统,在常温区段我测得误差能控制在 ±0.15℃ 以内,HVAC 应用绰绰有余,炉控的重要区段也能满足工艺要求。
5.4 给后来者的一组经验与坑位清单
做完整套软硬件后,我把最容易出问题的几个点整理成清单,供你排查时对照:
- 上电后没等 ADC 自校准完成就去读写寄存器,会导致首次转换数据乱飞;初始化前留足延时。
- 开启 CRC 后,发送和接收的计算多项式要和数据手册完全一致,不少项目问题出在“协议两边理解不一致”。
- 热电偶冷端补偿要保证探头接头和 ADC 内部温度传感器的热一致,否则理论精度再高,实际也会出现整片温度偏移。
- RTD 采用外部基准电阻做比例测量时,Rref 用普通电阻会带来温漂偏差,建议直接用 0.1% 精度、低温度系数的精密电阻。
- DRDY 用查询方式在高速数据率场景容易造成 CPU 忙等,浪费 F7 的性能,中断加 DMA 的方式更稳。
我个人实际使用下来,这套 ADS122U04IPWR 加 STM32F756ZG 的方案在可靠性和开发效率上都很平衡,唯一的调整空间在于 ADC 前端的抗干扰电路,现场环境不同,滤波和隔离的力度也要因地制宜,这个没有通用答案,只能靠实测数据来定参数。