news 2026/11/4 11:02:18

ADS122U04 + STM32F437ZG 温度采集方案详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ADS122U04 + STM32F437ZG 温度采集方案详解

做工业现场和 HVAC 温度采集的人,多半都体会过一种别扭:你想要的精度其实不高,0.1℃ 就够,但现场环境就是跟你过不去——配电柜里几十安的变频器在边上,传感器线一拉十几米,测温点偶尔还和动力线共地。这时候,ADS122U04IPWR 这颗 24 位 Δ-Σ ADC 搭配 STM32F437ZG 主控的组合,就特别对路。文章从我实际做过的项目出发,把从选型、电路、固件到调参踩坑的完整链路捋一遍,给正在做温度采集板、HVAC 控制器或工业仪表的工程师一套能直接复用的参考方案。测温对象主要是 PT100/PT1000 热电阻和 K/T 型热电偶,覆盖 -40℃ 到 150℃ 的 HVAC 段,也能延伸到更宽的工业段。

1. 方案选型复盘:为什么组合是 ADS122U04IPWR 与 STM32F437ZG

1.1 ADC 侧:ADS122U04 最打动我的三个点

ADS122U04 这颗芯片,型号里的 “U” 就是 UART 接口,IPWR 是 TSSOP-16 封装的订货后缀。它本质上是 TO 的 24 位 Δ-Σ ADC,内部集成了四通道输入多路复用、可编程增益放大器 PGA(增益 1~128)、两个用于 RTD 激励的恒流源 IDAC、2.048V 基准电压源、内部温度传感器以及传感器开路检测。这一堆模拟前端组件全塞在一颗芯片里,直接省掉了外部仪表放大器、精密恒流源和基准源。

先说最打动我的三个点。第一是比例式 RTD 测量极其友好。两个 IDAC 恒流源可以给热电阻提供激励电流,同时把同一股电流送到外部基准电阻上,ADC 的参考电压和输入信号共用电流源,这样恒流源的温漂和电压波动会被自动抵消,精度完全取决于基准电阻本身,而不是电流稳定性。第二是UART 接口在工业现场比 SPI 好使。SPI 需要时钟线、数据线、片选线,要隔离就得隔离四条线;UART 只有 TX/RX 两条线,加一对数字隔离器或者光耦就搞定,长线传输时也不存在时钟偏移导致的数据错位,对 Modbus 这类轮询式协议特别顺手。第三是四通道输入和故障检测。一路 ADC 可以通过模拟开关切四路传感器,板子做紧凑一点,成本摊薄;断线检测可以在现场探头损坏时直接报警,而不是报一个吓人的中间值。

关键参数选型上,我常用的工作条件是数据率 20SPS 或 45SPS,PGA 根据传感器类型在 1~128 之间切。24 位输出在低速档下有效分辨率很高,配合硬件滤波和软件平均,HVAC 场景下做到 0.05℃ 级别的稳定显示并不难。工作电压范围宽,3.3V 和 5V 系统都能带,和 STM32F437ZG 的 3.3V 电平匹配时几乎不用额外转换。

1.2 主控侧:STM32F437ZG 的资源匹配

STM32F437ZG 是 M4 内核、带 FPU,主频 180MHz,Flash 1MB,SRAM 192KB,LQFP144 封装。选它不是因为温度采集本身需要多大的算力——ADC 读出来打个滤波、查个表,这点活 F103 也够——而是因为整个系统的“其他需求”太多。HVAC 控制器通常要做 PID 或开关控制,跑 Modbus RTU 从站,驱动 LCD 显示屏,处理按键,存储参数,还要挂看门狗;如果后续要接入楼宇自控,往往还要扩一路 RS485 或者以太网。F437ZG 的串口资源多,USART/UART 总数足够把调试口、ADC 口、Modbus 口、触摸屏口全部分开独立,不会被外设端口卡脖子。

另一个实际原因是开发效率。HAL 库加上 CubeMX 生成工程,UART 配置和 DMA 中断都能快速搭起来,对做产品原型和中小批量设备都很省时间。相比 F407,F437 的加密模块可以做固件保护;相比 F103,180MHz 主频让浮点滤波和 Modbus 响应耗时都很充裕。ZG 后缀的 LQFP144 引脚够多,四路 ADC 输入、RS485 收发控制、继电器输出、数码管/LCD 接口一次性铺开,不用为了省引脚去做一堆复用切换。

选型时我也对比过 ADS124S08 这类八通道 ADC,通道数多但价格高。对于 HVAC 场景,四路够用;如果将来要扩到八路测量,合理的做法是多挂一片 ADS122U04,UART 接口做菊花链或者片选,而不是一上来就用大通道 ADC 牺牲成本和灵活性。

2. 硬件电路设计:从传感器到 UART 的关键链路

2.1 RTD 测量电路:比例式测量怎么搭

先说清楚 RTD 比例式测量的接线核心。以 PT100 四线制为例,IDAC1 恒流源从芯片输出,经过传感器热电阻,再经过外部基准电阻 RREF 回到 GND。把 ADC 的正输入 AINP 接到热电阻的高端,负输入 AINN 接到热电阻的低端,这样输入电压就是恒流源在热电阻上产生的压降。同时,把 REFP1 接到 RREF 的高端,REFN1 接到 GND,这样参考电压就是同一股电流在 RREF 上产生的压降。

为什么这么接?因为 ADC 输出的比例是 VIN × Gain / VREF,代入后就是 (I × R_RTD) × Gain / (I × RREF),电流 I 被约掉了。只要 RREF 温漂足够低,测量结果就与恒流源的绝对精度无关,这就是“比例式”的精髓。如果不这么接,而是用内部基准做参考,那么 IDAC 的温漂会直接变成零点漂移,读数会随着芯片温度变化慢慢跑偏,现场排查时非常难发现。

RREF 的选型我建议直接上低温漂精密电阻,温度系数 5ppm/°C 以内,阻值 2kΩ 比较合适。IDAC 电流设 500μA,VREF 就是 1V,PT100 在 0℃ 时压降约 50mV,PGA 取 8 倍后是 0.4V 的输入幅度,既不会削顶,又能把信号充分放大。需要说明的是,RREF 要紧贴 ADS122U04 的 REFP1/REFN1 引脚放置,走线要短,否则 PCB 铜箔电阻和热电动势会影响比例精度。我见过不少新手的板子,模拟前端布线很随意,结果温度清零时读数漂了几十个码,拿烙铁靠近一下又漂更多,基本都是热电动势和地线噪声叠加出来的。

三线制 RTD 的接法略微复杂,用两个 IDAC 分别从热电阻两端供流,让导线电阻上的压降被对称抵消。四线制精度最高,但现场很多旧设备只有三线,所以驱动代码里要把两种模式都支持。拨到三线制时,PGA 和滤波参数基本不用改,只是电路上要多走一根补偿线。

2.2 热电偶与冷端补偿

热电偶的工程量比 RTD 大,主要难在信号微弱和冷端补偿。K 型热电偶灵敏度约 40μV/°C,测 0~100°C 只有 4mV 左右的电压,必须靠 PGA 放大。实际配置我会把 PGA 拉到 64 或 128,输入直接差分接入 AIN 通道。放大倍数高了以后,PCB 上的热电动势、电源耦合噪声都会被放大,所以热电偶输入前必须加 RC 低通滤波,我常用的参数是 R 100Ω、C 0.1μF,放在靠近 ADC 引脚的位置,先折掉高频干扰再进 PGA。

冷端补偿在 HVAC 场景里特别容易做错。ADS122U04 内部有温度传感器,可以读芯片附近的温度,算法上拿这个值当冷端温度。问题是:芯片表面温度不等于接线端子处热电偶冷端的温度,中间隔着 PCB 铜箔、端子材料和空气热阻,尤其在设备外壳内温升明显的场合,用内部温度做补偿会产生不小的误差。我的做法是如果精度要求高,就在端子排旁边放一颗外置 NTC 或数字温度传感器,和热电偶接线点尽量靠近,把冷端温度测准。补偿公式是 V_actual = V_measured + V_cold_junction(T_cj),T_cj 是冷端温度,V_cold_junction 从分度表或多项式查出来,再用热端电压对照分度表反算出被测温度。这一套写下来不难,难的是让冷端传感器和热电偶端子之间没有温度梯度。

2.3 UART 隔离与长线传输设计

ADS122U04 的 UART 接口是 TTL 电平,直接和 STM32 连接的话,板内走线没问题,但一旦传感器板和控制板分开、距离超过几十厘米,或者现场有变频器、接触器干扰,就得上隔离和线缆保护。隔离方案我推荐数字隔离器,比如 ISO7721 或 ADuM1201 这类双通道器件,一路 TX、一路 RX;隔离电源用 B0505S 这类小功率 DC-DC,注意隔离电源的输出纹波要给 ADC 模拟部分做好滤波,否则 ADC 噪声会被电源带起来。

如果板间距离到几十米,最简单的做法是在隔离之后加 RS485 收发器,把 UART 信号转成差分信号走屏蔽双绞线。RS485 电路要接 120Ω 终端电阻,视线缆长度和节点数决定是否启用;屏蔽层单端接地,避免地环路。如果只是几米距离,用 MAX3223 之类的 RS232 方案也能跑,但对工业现场来说,RS485 抗共模干扰能力更强,后续要并联多个设备也更方便。

值得提醒的是,UART 隔离的波特率不是随手定的。低速光耦在 115200 波特率下边沿延迟明显,容易错帧。如果隔离器是普通光耦,建议把波特率压到 9600 或 19200;如果用的高速数字隔离器,115200 基本没问题。现场调试时最好用示波器看 TX/RX 波形,确认边沿干净再定档。

3. 固件实现:STM32F437ZG 与 ADS122U04 的 UART 通信

3.1 通信帧结构分析

ADS122U04 的 UART 协议是典型的寄存器读写模型,MCU 作为主机发送命令帧,ADC 回传数据帧。帧里除了命令字节和数据字节,还有 CRC 校验,这是工业环境里必须的,否则长线上一个脉冲就能让读数跳几度。写寄存器时,主机发命令和要写入的数据,器件收到后回确认;读寄存器或读转换结果时,主机发命令,器件把数据连 CRC 一起返回。

这里我不打算把数据手册里的命令码表格整段抄过来,而是把协议思路和驱动结构讲清楚,因为芯片的命令字节定义必须以 TI 官方手册为准,不同批次文档里 CRC 字节顺序可能也有差异。实际移植时,把命令码做成宏,一行一行对着手册表格填进去,确保 CRC 多项式、初值、字节序和示例波形逐项对上,再继续下一步。

帧解析时注意一个细节:UART 接收不能只按固定字节数等。如果 ADC 忙或者命令错误,返回的帧长可能不同,轻则错位,重则把下一次帧头吞掉。我的做法是状态机收帧:先收命令域,再按不同命令期望的返回长度收数据域,CRC 校验通过才更新变量,校验失败直接丢弃整帧并计数,连续失败超过阈值就重新初始化 ADC 串口。

// 示意宏,具体命令码务必对照数据手册填写 #define ADS_CMD_WRITE_REG 0x4A #define ADS_CMD_READ_REG 0x2A #define ADS_CMD_READ_DATA 0x12 #define ADS_CRC_POLY 0x1021 static uint16_t ads_crc16_update(uint16_t crc, uint8_t byte) { int i; crc ^= (uint16_t)byte << 8; for (i = 0; i < 8; i++) { crc = (crc & 0x8000) ? (crc << 1) ^ ADS_CRC_POLY : (crc << 1); } return crc; }

3.2 STM32 侧驱动状态机与 DMA 接收

STM32F437ZG 的串口资源多,我给 ADS122U04 分配一个 UART,用 DMA 接收加空闲中断,接收不定长帧很顺手。初始化时,使能 GPIO 复用、配置 UART 波特率、打开 DMA 接收通道,然后启动一次 DMA 接收;每帧结束后触发空闲中断,在中断里读取 DMA 剩余计数,算出一帧实际长度,交给解析函数。这样做的好处是 CPU 不用逐字节轮询接收,ADC 连续输出时也不会因为主循环忙乱丢数据。

static uint8_t ads_rx_buf[64]; static volatile uint16_t ads_rx_len; void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart->Instance == USART1) { ads_rx_len = Size; ads_parse_frame(ads_rx_buf, ads_rx_len); HAL_UARTEx_ReceiveToIdle_DMA(&huart1, ads_rx_buf, sizeof(ads_rx_buf)); } }

读转换结果时,主机发读数据命令,ADC 返回 3 字节的 24 位有符号数再加 CRC。解析代码要做符号扩展:如果最高位是 1,表示负输入,按负数处理。HVAC 里多数温度是正的,但热电偶接反或者传感器断线时可能出现负满码,这时候扩展不正确会把 -1 码变成 1677 万多的巨大正数,滤波和显示都会乱套。

static int32_t ads_raw_to_signed(const uint8_t *p) { int32_t val = ((int32_t)p[0] << 16) | ((int32_t)p[1] << 8) | p[2]; if (val & 0x800000) { val |= 0xFF000000; } return val; }

驱动里我用单次转换模式,不搞连续输出。原因是 HVAC 场景刷新率不需要很高,1 秒更新一次足够,单次模式每次命令发完后等数据返回,中间主控还能处理 Modbus 和显示任务,功耗也低。如果想做更平稳的显示,就连续读几个点做滑动平均。连续模式适合那种需要毫秒级更新的工业控制场合,代价是 MCU 要一直处理串口中断,主循环紧张一些。

4. 温度换算、滤波与现场标定

4.1 从原始码到电阻、再算到温度

ADS122U04 的输出码和输入电压的关系是:Code = (VIN × Gain / VREF) × (2^23 - 1)。因为做了比例式参考,VIN/VREF 就是 R_RTD/RREF,代入后得到 R_RTD = (Code / (2^23 - 1)) × RREF / Gain。实际项目里我不会直接在中断里做浮点除法,而是先用定点算出电阻值再转浮点,但为了方便理解,工程代码可以直接写成浮点,F437ZG 带 FPU,20SPS 下算几百次都不吃力。

拿 PT100 举例算一遍:RREF=2kΩ,IDAC=500μA,Gain=8,0℃ 时 R_RTD=100Ω。VIN=50mV,VREF=1V,放大后输入幅值 0.4V,Code = 0.4 × 8388607 ≈ 3355443。反算电阻:(3355443 / 8388607) × 2000 / 8 = 100.0Ω,正确。就是这条链路,用任何语言写都一样。

电阻转温度,我用 Callendar-Van Dusen 方程。0℃ 以上,R(t) = R0 × (1 + A×t + B×t²),其中 A=3.9083e-3,B=-5.775e-7;0℃ 以下还需要加 C×t³×(t-100) 项。反过来求温度时,直接用求根公式算 0℃ 以上的解,0℃ 以下或要求高精度时改用查表加线性插值,表从 -50℃ 到 300℃ 每 10℃ 一档就够,插值后误差完全可控。

float pt100_temperature(float resistance) { const float R0 = 100.0f; const float A = 3.9083e-3f; const float B = -5.775e-7f; float r = resistance / R0 - 1.0f; float det = A * A - 4.0f * B * r; return (-A + sqrtf(det)) / (2.0f * B); }

4.2 滤波与数据率取舍

数据率档位影响最大的是噪声。ADS122U04 这类芯片,低速档下数字滤波器平均次数多,RMS 噪声能压到非常低;数据率一高,等效噪声带宽变大,码值跳动肉眼可见。实测下来,330SPS 时 RTD 读数跳动的码值可能是 20SPS 时的几倍,这不是芯片坏了,而是噪声本来就是宽频的。HVAC 温度变化又慢,完全没必要追高数据率,我固定在 20SPS 或 45SPS,配合软件一阶低通滤波,最终显示更新 1Hz,稳定度肉眼可见地好。

软件滤波我用一阶 IIR:y_n = y_(n-1) + α × (x_n - y_(n-1))。α 取 0.1 到 0.3,平滑效果明显,响应也跟得上空调水系统的温度变化。要注意的是,传感器断线时输出会瞬间跳到满码或负满码,这时候必须跳过滤波并把报警标志拉起来,否则 IIR 会把一个异常值慢慢“消化”成假温度,现场会误判为温度突变。

4.3 多点标定与自校准流程

再好的 ADC 也敌不过传感器和电路的系统性误差。HVAC 仪表一般要求 ±0.5℃ 或更高,出厂标定这步省不掉。我的流程是:设备上电稳定 30 分钟,然后做两点校准。第一点用冰点槽(0℃ 冰水混合物)或干井,第二点用 40℃ 或 100℃ 恒温槽。每一点浸泡探头至少 10 分钟,等读数变化小于 0.01℃ 再记录。

把两个校准点记录下来,算一条直线:实际的电阻修正值 = 测量电阻 × K + B。K 修正增益误差,B 修正零点偏移。系数写进 STM32 内部 Flash 或外接 EEPROM,上电加载。这里注意一个细节:标定时必须等热电阻自热稳定。IDAC 激励电流 500μA 在 100Ω 上只有 0.025mW 发热,影响很小,但如果是 1mA 激励加小型探头,自热可能让示值偏高 0.1℃ 以上。标定完成后保留校准日期和批次号,方便追溯。

5. 工业与 HVAC 现场调试:常见问题和避坑记录

5.1 现象一:测量跳动大,噪声超标

先别急着怀疑 ADC 不行。断电,用万用表量传感器输入两端是不是真的有几百欧的电阻;再把传感器短接,看 ADC 输出码的离散程度。短接后码值依然乱跳,问题在板子侧:电源纹波、RREF 松动、PGA 过大、数据率太高,逐一排查。短接后码值非常稳定,说明噪声源在传感器线缆或干扰回路里:换屏蔽线、屏蔽层单端接地、加输入 RC、降低数据率,四件套下来基本能解决。我踩过最狠的一次是 RTD 引线绑在变频器输出电缆上,读数像心电图,后来把线缆分开并穿屏蔽管才压下去。

5.2 现象二:UART 偶发错帧,CRC 老校验不过

错帧先看波特率误差。STM32 的 HSE 和 USB 晶振不校准会有偏差,和 ADS 内部 UART 分频叠加后,字符多了误差累计就会错位。用示波器抓一下 TX 脚波形,量单个字符长度,确认实际波特率和目标相差不到 1%。其次看隔离器,光耦在高速率下传播延迟不对称,会让采样点吃到下降沿上,表现就是偶发错帧。我的习惯是工业板 UART 一律用高速数字隔离器,波特率 19200 打底,再不行降到 9600,稳字当头。协议层做好 CRC 校验和重发机制,错一帧重读一次,比在中断里跟噪声死磕靠谱。

5.3 现象三:上电和半小时后读数漂移

这类漂移十有八九是热源造成的。RREF 靠近功率器件发热区,温度慢慢升高,阻值变化,比例式测量的基准就飘了。解决手段是热设计:RREF 远离发热源,必要时加隔热屏蔽。另一个来源是 PCB 上的热电动势,RTD 输入端两根走线不对称,焊点和过孔产生微小温差电压,直接叠加到几十毫伏的信号上。对称布线、同一层、等间距,能压掉大部分。还有芯片自热,上电初期 IDAC 和内部模拟电路让 AD 芯片温度缓慢爬升,冷端补偿和基准都会跟着变,所以标定和比对测试都放在上电半小时之后。

5.4 HVAC 工程落地要注意的细节

HVAC 现场和实验室是两个世界。水管温度测点要装热电阻套管,探头伸进套管里并填充导热硅脂,不能直接挂在管道外壁;风管测点要放在气流稳定段,避开盘管和加热器,否则测的是局部温度。接线端子盒要做防水,PCB 刷三防漆,尤其是靠窗户或新风口的设备,冬天结露是常事。楼宇自控对接时,主控跑 Modbus RTU 从站,把温度值放大 10 倍存成整数给上位机,单位 0.1℃;同时把传感器断线、通信超时这些状态位放到独立寄存器,上位机才能区分“温度是 0”和“温度没测到”。

最后说点个人体会。做这类测温板最忌讳的是把“ADC 位数”当成精度,24 位在低速档下确实厉害,但 HVAC 现场真正决定系统性能的往往是 RREF 的温漂、探头安装位置和 UART 帧的重发策略。我在实际项目里吃过亏:刚上电读数很漂亮,半小时后整体偏了 0.3℃,最后查到是 IDAC 电流和 RREF 在板子上靠得太近,被芯片自热烤着了。后来把 RREF 挪到板边、加了一圈地孔隔热,问题才解决。对于准备自己打造温度采集模块的朋友,建议先从 2 路 RTD 加 1 路热电偶的小板做起,把 0℃ 附近和 100℃ 附近两点标定做扎实,比一味堆通道数有用得多。这一步想清楚了,后面扩展 8 路、加 Modbus 都只是顺水推舟的事。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 11:01:53

ESP32 BLE鼠标开发实战:从零打造指环鼠标的HID链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/4 11:00:19

车载显示开发实战:从多屏映射到启动优化的关键技术解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/4 10:57:04

C++哈希表之闭散列方法的模拟实现详解

前言 哈希表&#xff08;hash table&#xff09;解决的是「按 key 快速查找」的问题。当不同 key 被映射到同一个桶时&#xff0c;就需要冲突处理。常见做法有两类&#xff1a;开链法&#xff08;separate chaining&#xff09;在每个桶上挂一条链表&#xff1b;闭散列&#xf…

作者头像 李华
网站建设 2026/11/4 10:56:42

LabVIEW调用SQLite实战:CLFN封装与嵌入式数据持久化

简介&#xff1a;本资源是一套面向LabVIEW工程师与自动化开发者的SQLite数据库集成解决方案&#xff0c;专为解决LabVIEW原生数据库操作能力薄弱、建库繁琐、缓存积压及编程复杂等痛点而设计。资源包共148个文件&#xff0c;含117个可直接调用的VI程序&#xff08;覆盖建库、表…

作者头像 李华
网站建设 2026/11/4 10:56:42

Agent驱动CLI工具全解析:从Codex CLI安装到多Agent编排实战

1. 从"CLI-Anything"说起&#xff1a;命令行工具正在经历一场静默革命 第一次看到"CLI-Anything"这个说法&#xff0c;我脑子里蹦出来的不是某个具体工具&#xff0c;而是一种趋势判断&#xff1a;命令行界面正在从"人敲命令"进化成"人描述…

作者头像 李华
网站建设 2026/11/4 10:56:42

Fuchsia操作系统:微内核架构与跨设备协同技术解析

1. 操作系统生态变革的前夜 最近科技圈被一则重磅消息刷屏&#xff1a;谷歌正在秘密研发一款名为"Fuchsia"的全新操作系统&#xff0c;该系统设计理念与现有安卓截然不同&#xff0c;采用微内核架构并支持跨设备无缝协同。这让我想起三年前第一次拆解鸿蒙系统代码时的…

作者头像 李华