ADS122U04+STM32F765ZI工业温度采集模块:PT100/热电偶精确测量方案

发布时间:2026/11/5 7:38:04
ADS122U04+STM32F765ZI工业温度采集模块:PT100/热电偶精确测量方案

搞工业现场和 HVAC 温度采集,最容易被低估的其实是“毫伏级信号怎么变成稳定数字量”这一步。过去一年我用ADS122U04IPWR和STM32F765ZI做了一块四路温度采集模块,测风管温度、水管温度、机房环境温度,同时兼容 PT100 三线制和 K 型热电偶。今天把这块板子的选型思路、硬件细节、固件实现和现场踩过的坑一次性整理出来,给正在搭类似采集方案的朋友做个参考。

先说结论:这套方案最大的价值不是单个芯片有多强,而是“24 位 Δ-Σ ADC 自带激励电流源 + 高性能 MCU 做线性化处理”的组合,把模拟前端误差和数字计算压力同时降了下来。你不需要再搞一级仪表放大器,也不需要自己拼基准源和恒流源,一颗 ADC 全包了。下面按设计链路逐步拆。

1. 项目整体设计与选型思考

1.1 为什么相中 ADS122U04IPWR 而不是其他 ADC

第一次选型时我其实犹豫了很久,摆在面前的主要有三类方案。

第一类是用“运放 + 16 位逐次逼近 ADC”的老方案。看起来成本低,但要把 PT100 在 0°C 附近的 0.385Ω/°C 变化率转换成足够的分辨率,前端就得加固定增益放大器,而运放的失调、温漂、电源抑制比每一项都要额外花钱和精力去压,量产一致性很难控。

第二类是 SPI 接口的 24 位 Δ-Σ ADC,比如常见的 ADS1220 或 ADS124 系列。性能没问题,但 SPI 是高速同步接口,SCLK、MISO、MOSI、CS 四根线在模块和主控之间走线,隔离、布局都比串口麻烦。如果打算把采集板做成独立的小模块,挂在主控板上,或者现场布线比较长,SPI 的时序裕量会让你很难受。

第三类就是 ADS122U04IPWR。它的核心卖点是UART 接口,物理上只要两根线,交叉连接就能和 MCU 通信。距离稍微拉长之后还可以直接挂 RS485 收发器变成远距离半双工总线,这在工业采集模块里非常实用。再加上 ADS122U04 本身集成了可编程增益放大器 PGA、两个可编程激励电流源 IDAC、内部 2.048V 基准、内部温度传感器,一颗芯片就覆盖了 RTD 前端需要的全部模拟电路。

另外注意 IPWR 尾缀,这对应的是 TSSOP-16 小封装,回流焊和手工焊接都容易处理,样板阶段调试很方便。

1.2 STM32F765ZI 是不是“杀鸡用牛刀”

如果只是把 ADC 数据读出来然后算个温度,用 STM32F103 也绰绰有余。但我在设计这块板子的时候考虑的是整套产品而不是单纯一个例程。

STM32F765ZI 是 Cortex-M7 内核,主频 216MHz,带单精度 FPU 和 DSP 指令,跑 PT100 的 Callendar-Van Dusen 逆解、热电偶查表插值这些浮点运算基本是“零成本”。它的 LQFP144 封装下挂了 8 个串口,我一路接 ADC、一路接调试、一路接 RS485,剩余的还能给未来扩展 LCD 屏和对外升级用。2MB Flash 放 Bootloader 加双镜像远程升级没有压力,512KB SRAM 做采集环形缓冲和多通道均值滤波也非常宽裕。

选型时的逻辑很简单:与其在 103 上抠 RAM 和省浮点时间,不如一步到位,把产品后续的功能扩展空间留出来。温度采集模块往往不是单独存在,后面大概率要内嵌 Modbus、数据日志、入网协议,这些都会吃资源和开发时间。

1.3 整机链路与资源分配

这块板子的整体链路是这样的:

24VAC/DC 输入 → 前端保护 → 隔离 DC/DC → 5V → LDO 3.3V 模拟/数字分区供电 → 传感器信号进 ADS122U04 → UART 送 STM32F765ZI → 线性化与滤波 → RS485 Modbus 输出 / 本地显示。

STM32 侧的串口资源分配我列一个表,方便你对照自己的项目:

外设用途备注
USART3接 ADS122U04 的 UART9600 波特率 8N1,半双工命令应答
USART1调试串口仅开发阶段使用,量产可去掉
UART4RS485 Modbus 从站SP3485 + 隔离,接到触摸屏/DDC
剩余串口预留后续接蓝牙、4G、LCD 等

整个系统里 STM32 只负责“算”和“传”,模拟采集全部甩给 ADC,这样固件层和硬件层的职责边界非常清楚,调试时排查问题也快。

2. 硬件设计:真正决定精度的细节

2.1 RTD 前端接线方式怎么选

硬件上最容易出错、也是最影响精度的环节就是 RTD 前端。PT100 是电阻随温度变化的传感器,引线本身也有电阻,所以接线方式决定了引线电阻会不会被“算进”温度里。

我同时兼容了四线制和三线制。接法原则如下:

  • 四线制:两根线与激励电流源 IDAC 串联,另外两根线专门做电压检测。检测线几乎没有电流流过,所以引线电阻完全不影响读数,精度最高,适合做计量和校准基准。
  • 三线制:用于现场大多数场合。标准做法是把一路激励电流从高端引线灌进去,电流流经铂电阻后从低端引线出来,再经过精密参考电阻 RREF 回到地。这样激励电流、传感电阻和参考电阻是串联的,实现比例测量。第三根引线接到电压检测端,用来抵消引线电阻带来的误差。
  • 两线制:最省线,但引线电阻全部串入被测电阻中,精度最差。我只在非关键监控点做兼容,校准也没法完全补掉。

从项目实践看,楼宇自控、水系统温度监控绝大多数场合用三线制就够。现场传感器到模块的线缆经常会拉到十几米甚至几十米,三线制的误差会被控制在可接受范围,四线制留给实验室参考端。

2.2 激励电流、参考电阻和增益怎么搭配

这块是整个硬件设计里“为什么这么选”的核心。ADS122U04 的两个 IDAC 可以输出可编程电流,我把 IDAC1 配成 1mA 作为激励,让它同时流过 PT100 和参考电阻 RREF。因为同一股电流同时产生传感电压和参考电压,最终 ADC 结果是一个比值:

R_RTD = RREF × (code / FS)

这里IDAC 的绝对精度被完全抵消,它漂多少都没关系,因为分子分母是同一个电流。真正重要的反而是 RREF 这颗电阻的精度和温漂,我选的是 0.02% 精度、15ppm/°C 的精密电阻,而不是把精力浪费在选一个昂贵的高精度恒流源上。这一点很多第一次做比例测量的人容易搞反。

增益和基准电压要按测量量程来配。我按“-40°C 到 +200°C”这个 HVAC 常用区间算了一笔账:

PT100 在 -40°C 时约 84.27Ω,在 +200°C 时约 175.84Ω,1mA 激励下对应的信号电压是 84mV 到 176mV。我选 RREF=1.5kΩ,基准电压就是 1.5V,PGA 增益选 8,则送入 ADC 的满幅信号是 0.67V 到 1.41V,始终低于基准电压,不会削顶。这样配置之后,理论 LSB 约为 11nV,虽然实际噪声远到不了这个数,但分辨率余量已经非常充足。

别忘了自热问题。1mA 电流在 100Ω 上产生的功率是 0.1mW,对普通铠装 PT100 探头来说约等于 0.05°C 左右的温升,基本可忽略。但如果你用的是薄膜电阻或很细的探头,建议把电流降到 500µA,代价是信号幅度减半,这时可以把增益调到 16 来补回来。

2.3 输入保护与抗电磁干扰处理

工业现场最怕的不是精度不够,而是浪涌、静电和电磁干扰直接打坏 ADC。我在每个模拟输入通道前都加了串联电阻和双向 TVS 管,再并联一个到地的滤波电容。串联电阻取值不能太大,因为 Δ-Σ ADC 的 PGA 输入端会有动态输入电流,电阻太大会造成增益误差。实测下来 560Ω 串联加 1nF 对地是比较稳妥的折中,既能挡住高频干扰,又不会明显吃掉 24 位精度。

另外 RTD 和热电偶从几十米外的现场探头上过来,线缆本身就像一根天线。我用的是双绞屏蔽线,屏蔽层在采集模块这一端单点接地,另一端悬空,避免屏蔽层形成地环路。板子上模拟前端区域也做了包地处理,靠近 ADC 的走线尽量短而粗,IDAC 的激励线和 RTD 的检测线不能并行走太长,否则耦合噪声会直接进差分输入。

2.4 电源、隔离与布局关键点

楼宇设备现场大量采用 24VAC 供电,这也是 HVAC 项目的一个特殊性。我的方案里电源入口先做整流桥,兼容 24VAC 和 24VDC,然后经过 TVS 和共模电感,再进隔离 DC/DC 转成 5V,最后用低噪声 LDO 分出 3.3V 模拟电源。隔离的作用不是为了标新立异,而是当现场还有变频器、水泵、电磁阀时,地电位差和共模干扰非常夸张,不隔离的话采集漂移会让你怀疑人生。

PCB 布局上我遵循一个原则:模拟电源和数字电源在芯片附近用磁珠或 0Ω 电阻单点汇合,模拟地和数字地在 ADC 下方以星形方式单点连接。千万别把 AGND 和 DGND 大面积铺成一个整铜皮,那相当于是给噪声开了一条最短路径。

3. 固件实现:从 UART 通信到温度值输出

3.1 ADS122U04 的 UART 命令与寄存器配置

ADS122U04 的 UART 协议不复杂,本质就是“主机发命令,器件应答”。读寄存器、写寄存器、读转换结果、连续读、停止连续读,都是单字节命令字,具体命令字以你手里那版数据手册的 Command Definitions 表为准。我工程里的宏定义大概是这样的思路:

/* 命令字宏定义请以 datasheet 的 Command Definitions 表为准 */ #define CMD_NOP (0x00u) /* 空操作 */ #define CMD_RDATA (0x10u) /* 读一次转换结果 */ #define CMD_RDATAC (0x12u) /* 连续读模式 */ #define CMD_SDATAC (0x14u) /* 停止连续读 */ #define CMD_RREG (0x20u) /* 读寄存器,可带上寄存器地址 */ #define CMD_WREG (0x40u) /* 写寄存器 */

接口上只要把 STM32 的 USART_TX 接到 ADC 的 RX,USART_RX 接到 ADC 的 TX,8N1 格式,波特率 9600。对采集模块这种 100ms 级别的采样周期来说,9600 波特率完全够用,换来的是远距离传输的稳定性。

寄存器配置是固件里最关键的一步。我在初始化代码里按顺序设置:

  1. 把输入多路开关选到目标差分通道。
  2. 设置 PGA 增益为 8。
  3. 选择外部基准(RREF 上的电压)。
  4. 配置 IDAC1 电流为 1mA,并把它路由到高端激励引脚。
  5. 使能内部温度传感器,这个后面做热电偶冷端补偿要用。
  6. 把转换速率设为 20SPS,用于工频环境下的噪声抑制。

写寄存器时要注意:UART 方式是命令应答型,写完寄存器之后不要立刻发下一条命令,最好等器件返回应答字节再继续,否则容易出现命令丢失的情况。

3.2 采集流程与数据解析

我的采集周期是固定的 100ms 轮询一次,不跑中断,流程图在代码里体现在状态机上:

  1. 上电后先做一次软复位。
  2. 写配置寄存器并等待应答。
  3. 延时等待第一次转换完成。
  4. 发送 RDATA 读数据命令。
  5. 接收 4 个字节,其中前 3 个字节是 24 位转换结果,另外 1 个字节带状态位。
  6. 把 24 位原始码根据测量模式换算成比例值。
  7. 代入 RTD 阻值计算,再做线性化和滤波。

这里有个很实用的细节:上电后的第一组转换结果最好直接丢弃。ADS122U04 和其他 Δ-Σ ADC 一样,上电后模拟前端和数字滤波器需要建立时间,第一拍读数经常会出现明显偏差。我在初始化之后先做一次空读,再把后续数据作为有效数据。

ADS122U04 输出的编码格式要对照手册确认。一般单极性测量时输出类似“零到满量程二进制码”,双极性测量时才是二进制补码。换算公式就是“实际输入电压 = 编码 / 满量程编码 × 基准电压 / 增益”。如果这一步搞反了符号,你会在温度曲线里看到非常奇怪的负偏差。

3.3 温度换算:不用查表也能做到准

拿到 RTD 阻值之后,下一步就是线性化。很多人第一反应是存一张 0.1°C 间隔的查询表,但表会占 Flash,而且插值代码还得小心翼翼。我直接用 Callendar-Van Dusen 方程做逆解,在 STM32F765 的 FPU 上只跑几次牛顿迭代就收敛,实测速度和精度都比查表方案好:

static float pt100_r_to_t(float r) { /* PT100 Callendar-Van Dusen 逆解,牛顿迭代 */ const float r0 = 100.0f; const float a = 3.9083e-3f; const float b = -5.775e-7f; const float c = -4.183e-12f; /* 仅在 0°C 以下生效 */ float t = 0.0f; for (int i = 0; i < 8; i++) { float rc, drdt; if (t < 0.0f) { rc = r0 * (1.0f + a*t + b*t*t + c*(t - 100.0f)*t*t*t); drdt = r0 * (a + 2.0f*b*t + c*(4.0f*t*t*t - 300.0f*t*t)); } else { rc = r0 * (1.0f + a*t + b*t*t); drdt = r0 * (a + 2.0f*b*t); } t -= (rc - r) / drdt; } return t; }

这段代码里 0°C 以下多了带 C 系数的三次项修正,0°C 以上用二次方程就足够。迭代初始值直接设成 0°C 也没问题,因为 RTD 阻值到温度的映射是单调的,实测几轮之内就能收敛到小数点后 4 位。

温度算出来后我还会过一个滑动平均滤波器。工业 HVAC 对象本身热惯性很大,水管温度一分钟才变化一点,没必要追求每 100ms 的瞬时值,我用的窗口是 8 到 16 点滑动平均,既消除随机噪声,又不会带来明显的滞后。

3.4 热电偶通道的冷端补偿怎么处理

ADS122U04 自带的内部温度传感器可以直接用来做 K 型热电偶的冷端补偿。原理很简单,热电偶测到的是热端和冷端的温差电压,所以要得到热端真实温度,得把冷端温度对应的热电动势加回来。

具体步骤是:

  1. 用 ADC 内部温度传感器读出芯片温度,当作冷端温度。
  2. 查 K 型热电偶的 NIST 分度表(或多项式),算出冷端温度对应的毫伏值 V_cold。
  3. 用 ADC 测到热电偶的实际毫伏输出 V_meas。
  4. 计算 V_hot = V_meas + V_cold,再反查分度表得到热端温度。

热电偶灵敏度很低,K 型大约 41µV/°C,所以我把该通道的 PGA 增益设到 128,才能把微弱信号抬到 ADC 的高分辨率区间。这里有一个必须提醒的坑:用芯片内部温度计做冷端补偿的前提是冷端就在 ADC 芯片附近。如果你的热电偶端子排离 ADC 比较远,或者 PCB 上有发热元件,内部温度读数会失真,这时候老老实实在端子排旁边放一颗外置 NTC,用另一个通道去测,比省一颗电阻造成的误差小得多。

3.5 对外集成:Modbus RTU 与校准参数

对外输出我用 UART4 接了 RS485,跑 Modbus RTU 从站协议,上位机是触摸屏和 DDC 控制器。四路温度分别映射到保持寄存器,功能码 03/04 都能读。协议栈我用的是移植性比较好的 FreeModbus,在 STM32F765 上跑非常轻松。

校准参数我放在内部 Flash 的一个独立扇区,每路温度有独立的零点偏移和增益系数。出厂前用标准电阻箱做两点校准,把校准系数写进 Flash。这样做的好处是现场更换探头后不需要改代码,通过 Modbus 写寄存器就能更新校准参数,运维人员自己就能搞定。

4. 现场常见问题与排查记录

4.1 读数漂移、噪声偏大

这一条是现场反馈最多的问题。排查顺序我总结成了一个固定套路:先看 RREF 有没有被热风吹到,再看激励电流配置,最后看数据速率。

精密电阻虽然温漂低,但它如果紧挨着隔离 DC/DC 这类热源,温度上来一样会漂。我在布局时把 RREF 放在远离发热器件的位置,并且选的是 0603 封装大功率规格,减少自身发热。其次,把数据速率从 1000SPS 降到 20SPS 之后,噪声通常能下降一个数量级以上。商用 HVAC 场合根本不需要 1kSPS 的带宽,20SPS 带来的是更干净的读数。

4.2 UART 偶发死锁、数据对不上

ADS122U04 走命令应答式通信,最容易出的问题就是主机和器件不同步。曾经我在上电初始化之后立即发 WREG,结果偶尔会有一次命令没被正确接收,导致后面所有读数都错。解决方法是:

  1. 初始化后先发 NOP 命令,收到应答后再继续。
  2. 每次 WREG 之后都检查应答字节,收到异常就重新复位 ADC。
  3. 在 USART 接收端做超时保护,防止器件没应答时主机一直阻塞等待。

还有一个常见的低级错误是 TX/RX 接反。UART 交叉连接是原则,但样板焊接时总有粗心的时候。遇到完全收不到响应,先用万用表量一下两个引脚的静态电平,再查一下焊接方向,往往比反复改固件快得多。

4.3 50/60Hz 工频干扰

在配电房附近和风机盘管旁边,工频干扰几乎是躲不开的。我的做法是把数据速率配成 20SPS,Δ-Σ ADC 的 sinc 数字滤波器陷波点能覆盖 50Hz 和 60Hz 及其整数倍谐波,实测效果非常明显,峰峰值噪声能降好几倍。如果你所在区域是 60Hz 供电,就选与之匹配的速率档位,原则是让陷波点压在工频和主要谐波上。

线缆层面的处理同样重要。双绞屏蔽线、屏蔽层单点接地、远离变频器动力线,这三条同时做到,否则全靠 ADC 滤波算法也扛不住强烈的空间辐射耦合。

4.4 多通道切换后读数跳变

四路输入共用一个 ADC,多路开关切换后模拟输入电压突变,PGA 和数字滤波器都需要建立时间。最初我在通道切换后立即读数,发现数值要好几拍才能稳定。后来改成切换到新通道后先丢弃前两拍数据,从第三拍开始采集,问题立刻消失。如果你的前端还加了较大的 RC 滤波,这个稳定时间会更长,需要实测后调整丢弃的样本数。

4.5 上电首采异常与“看起来永远不对”的符号问题

上电首采异常就是上面说的空读一次。符号问题则出在编码格式上,切换增益或输入模式时,务必重新确认输出编码是偏移二进制还是二进制补码。我吃过一次亏:所有数值都正常,就是 0°C 附近出现一个小台阶,排查半天发现是编码格式理解错了,导致低字节的符号位处理错误。

把常见问题整理成表格,方便现场快速对照:

症状最常见原因处理办法
读数缓慢漂移RREF 受热或激励电流配置变动检查布局、重新配置 IDAC
噪声大数据速率过高 / 屏蔽接地不良降到 20SPS、屏蔽层单点接地
无响应TX/RX 接反或波特率错误量电平、核对交叉接线
偶发乱码主机与器件失步NOP 同步、应答校验、异常复位
通道切换跳变建立时间不足切通道后丢弃前两拍
温度符号不对编码格式理解错误重新核对手册编码规则

5. 实测数据与工程落地建议

5.1 量产板实测精度与噪声表现

在实验室用标准电阻箱标定以后,四路 PT100 通道在 0°C 到 100°C 区间的实测偏差稳定在 ±0.05°C 以内。20SPS 数据速率下,原始读数折算成温度的峰峰值噪声大约是 0.02°C 到 0.03°C,完全能满足楼宇自控和工业过程监控的精度要求。

对比同样环境下的两线制接法,三线制明显把引线电阻的影响压了下去。我拿 10 米线缆做实验,三线制读数和近距离四线制读数相差不到 0.1°C,两线制同样的线缆直接差出 0.5°C 以上。所以只要你现场传感器不是四线制,至少也得保证三线制。

5.2 HVAC 现场安装布线的具体建议

这块板子在空调箱、水泵房、机房用了大半年,总结几条现场经验:

  • 风管温度探头要插到气流中心,而不是贴在管壁外面,否则测的是外壳温度。
  • 水管温度探头要配不锈钢套管,并且探头要紧贴套管底部,套管和管壁之间要用导热硅脂填充,不然响应非常慢。
  • 信号线不能和 220V 动力线走同一个线槽,实在躲不开就改用屏蔽线,并且两边线槽保持至少 30cm 间距。
  • 现场供电常见 24VAC,整流后会有纹波,隔离 DC/DC 之后的 LDO 要留足够压差,否则 3.3V 模拟电源纹波会直接影响 ADC 的基准电压和测量稳定性。

5.3 个人踩坑总结,按后悔指数排序

最后按“如果重新设计我会怎么做”的顺序盘点一下。

第一后悔的是没有在第一版就把校准流程做成产线自动化,而是靠人工记录数据。虽然板卡性能没问题,但量产阶段每块板子人工标定非常浪费时间,后期我用串口脚本自动读取、自动计算校准系数写入 Flash,效率提升了十倍。

第二后悔的是热电偶通道的冷端补偿一开始依赖芯片内部温度传感器,结果端子排在板边、芯片在板中央,温差明显。后来加了一颗外置 NTC 贴在端子排背面,补偿精度立刻改善。

第三个值得提醒的是,不要盲目追求高数据速率。HVAC 对象响应慢,20SPS 足够,而且数字滤波器的噪声抑制能力只有在低速率下才能发挥出来。我一开始图省事往高了配,后来噪声问题逼着我改回 20SPS,白白浪费了两天调试时间。

ADS122U04IPWR 和 STM32F765ZI 这套组合,最舒服的地方在于模拟链路的坑被芯片集成掉了大部分,你只需要把参考电阻选好、把布局做规整、把数据速率配对,就能拿到非常干净的测量结果。之后不管你是想加 Modbus、加显示、加远程上报,F765 的资源都绰绰有余。这套方案我后续还准备扩成 8 通道,主控侧基本不改,ADC 侧再挂一片就行。