☰
基于ADS122U04与STM32L4的高精度温度采集方案解析
2026/11/5 1:10:07 网站建设 项目流程

做温度采集这么多年,我越来越觉得“测温度”这三个字没法小看。HVAC 的管道风温、冷热水回水温度,工业现场的机柜温度、管路表面温度,看似都是百八十度的范围,但精度要求、传感器种类、布线环境各不相同,稍不留神数据就会漂。最近一个项目里,我用 ADS122U04IPWR 这颗 24 位 Delta-Sigma ADC 搭配 STM32L4S5ZI 单片机,把 PT100、热电偶、NTC 的温度测量统一做进一套硬件,实测稳定性比过去用 MCU 内置 ADC 的方案高了一个量级,通信链路也简单了不少。这篇就把整个方案的器件选型逻辑、硬件接线、寄存器配置、温度换算算法,以及调试时踩过的坑完整记下来。不管你是刚开始接触高精度温度采集,还是已经在做 HVAC 控制板,这套思路都可以直接拿来参考。

1. 项目定位:HVAC 与工业现场的测温难点在哪

1.1 现场测温的三个典型痛点

精度和分辨率是第一个坎。HVAC 系统里冷冻水供水温度、回风温度常年要求 ±0.2°C 甚至更高的控制精度。PT100 在 0°C 附近每变化 1°C 只变化大约 0.385Ω,0.1°C 对应不到 0.04Ω。MCU 内置的 12 位 ADC 即便把量程压到最小,也很难稳定分辨这个级别的变化。24 位 ΔΣ ADC 在这里不是炫技,是刚需。

第二个痛点是传感器类型杂、信号电平跨度大。PT100 在测温范围内的电阻变化可能只有几十欧,电桥输出也就几十毫伏;热电偶输出更夸张,K 型也就 41µV/°C,信号放大不到位根本没法用;而 NTC 阻值又会从几千欧变到几百欧。一个系统里混着这些传感器,ADC 前面的模拟前端必须足够灵活。第三个痛点是现场噪声和长线很难绕开。RTD 引线经常要拉到十几米甚至几十米,线路上会有变频器、接触器、开关电源的干扰。信号微弱,线又长,还经常和 220V AC 动力线走同一个线槽。这种情况下,靠普通 ADC 硬采,数据会像心电图一样跳。这三条叠在一起,决定了这类项目不能靠 MCU 自带的 ADC 硬凑,必须外挂一颗像样的模拟前端。

1.2 方案选型:为什么是 ADS122U04IPWR + STM32L4S5ZI

先说 ADC。选 ADS122U04IPWR 有四个理由。第一,24 位 ΔΣ 架构,分辨率足够覆盖 PT100 的 0.01°C 级别;内置可编程增益放大器(PGA),增益 1 到 128 可调,热电偶、PT100、NTC 全都能接。第二,它内置两个可编程激励电流源 IDAC,做 RTD 比率测量时不用自己搭恒流源电路,省掉一整套模拟器件。第三,它带的是 UART 接口而不是传统 SPI。对工业现场来说,UART 最大的好处是隔离容易——中间加一颗数字隔离器就能把模拟侧和数字侧干净分开,这在需要避免地环路和浪涌干扰的场景里非常实用。第四,功耗低,典型工作电流只有几百微安,很适合 24 小时不间断运行的 HVAC 控制器。

MCU 选 STM32L4S5ZI 则更多是从系统角度考虑。L4 系列是低功耗定位,但 L4S5 这一颗做到了 120MHz 的 Cortex-M4 带 FPU,浮点计算做温度换算和控制算法很顺手。2MB Flash、640KB SRAM 也足够跑 Modbus 协议栈、数据记录和简单的本地人机界面。HVAC 控制板往往要同时管风机、阀门、传感器,这颗芯片的外设数量和扩展性刚好够用。ADC 和 MCU 的配合方式很明确:ADC 负责把所有模拟信号变成干净的 24 位数字码值,MCU 负责通信、换算、滤波和控制。两边各干各擅长的活,整个系统的可靠性和可维护性都比“全堆在 MCU 里”的方案好很多。

2. 硬件设计:信号链和接口的完整拆解

2.1 ADS122U04IPWR 关键参数盘点

先把这颗芯片的关键信息列个表,方便后面讲电路时对照。

参数数值/说明
分辨率24 bit,ΔΣ 架构
输入通道4 路,可配成 2 组差分或 4 路单端
PGA 增益1 / 2 / 4 / 8 / 16 / 32 / 64 / 128
可编程电流源2 个 IDAC,10µA ~ 2mA 多档可配
内置基准2.048V;也支持外部基准输入
数据率20 / 45 / 90 / 175 / 330 / 600 / 1000 SPS
接口UART,支持自动波特率检测
供电2.3V ~ 5.5V,典型工作电流约 415µA
温度等级-40°C ~ +125°C 工业级
封装TSSOP-16,IPWR 后缀即此封装加卷带包装

型号后缀也要解释一下:ADS122U04 里的 U 代表 UART 版本,04 代表 4 通道;I 是工业级温度范围,PWR 是 TSSOP 封装。这个命名规则在 TI 的 ADC 里基本通用,看到型号就能判断能不能用在工业现场。对这个项目来说,最重要的三件事分别是:PGA 提供信号幅度适配能力,IDAC 解决 RTD 激励问题,UART 接口让系统隔离变得简单,这三样恰好对应前面说的三个痛点。

2.2 STM32L4S5ZI 的资源分配

STM32L4S5ZI 在这个系统里的角色不只是“读 ADC”,还要承担完整的控制任务。我在项目里这样分配资源:UART4 专门接 ADS122U04IPWR,数据率 115200,8 位数据、无校验、1 位停止位。单独用一个 UART 的好处是,就算主程序里控制逻辑再复杂,也不会堵塞温度采集链路。LPUART 预留做低功耗唤醒和简单调试,平时不用时整个外设可以关时钟。UART4 的接收我配置了 DMA 加环形缓冲区,避免中断频繁打断实时控制。RTC 打时间戳,温度数据进环形 FIFO,定时刷到 Flash 或通过 Modbus 上报。

STM32L4 的功耗管理也很适合这个场景。HVAC 系统里很多控制器是常年通电的,空闲时让 MCU 进 Stop 模式、保持 UART 和 RTC 工作,整体电流能压到很低。ADS122U04 那边保持低功耗连续采样,需要时再通过 UART 唤醒,这个配合很省心。需要注意的是,UART 空闲唤醒和 DMA 环形缓冲要配合好,否则从 Stop 模式醒来后会漏掉前几帧数据,我后面在调试部分会细说。

2.3 传感器接入:三线制 PT100 的比率测量怎么搭

RTD 测量最怕引线电阻。两线制下,引线上的电压降会直接叠加到测量结果里,一根 1Ω 的引线就可能引入 2.5°C 左右的误差。三线制通过“两条电流路径加差分测量”把引线电阻变成共模信号,再靠 ADC 的差分输入和 PGA 的共模抑制把它压掉。ADS122U04 有两个 IDAC,正好可以做成经典的三线制比率测量。

拓扑结构是这样的:IDAC1 从 AIN0 这一侧注入电流,电流经过一根引线、PT100、另一根引线,最后流过基准电阻 RREF 到 GND;IDAC2 从 PT100 回线侧的采样节点注入电流,同样也流过 RREF,这样 RREF 上的总电流等于 IDAC1 加 IDAC2。ADC 差分输入端 AIN0/AIN1 接的是 PT100 两端的电压采样线,采样线几乎不取电流,所以引线电阻不在信号回路里。参考输入端 REFP0/REFN0 跨接在 RREF 两端,采样的就是总电流在 RREF 上形成的压降。最后得到的码值满足:code 等于满量程乘以(IDAC1 乘 R_PT100)除以((IDAC1+IDAC2)乘 RREF)。当两个 IDAC 电流相等时,式子简化成满量程乘 R_PT100 再除以 2 倍 RREF。

这个式子和 IDAC 电流的绝对值无关,只和电阻比值相关,这就是比率测量:电流源的温漂、电源波动都会被抵消掉,是 RTD 测量稳定性的核心。如果精度要求更高,比如实验室或计量级,可以改四线制,用两线激励、两线采样,引线电阻几乎完全退出测量回路,代价是多一根线。RREF 取值有个经验原则:让被测温度上限对应的信号电压落在参考电压的 60% 到 80% 之间。比如我要测 -40°C 到 150°C,PT100 在这段的阻值范围大约是 84Ω 到 157Ω。设 IDAC 为 1mA、RREF 为 150Ω,则 Vref 等于 2 乘 1mA 乘 150Ω,也就是 300mV;最高温时信号电压是 1mA 乘 157Ω,约 157mV,占比约 52%;低温时约 84mV 除以 300mV,约 28%。这个跨度在 24 位分辨率下足够把 0.01°C 稳稳分辨出来。RREF 再小,分辨率会更高,但参考电压太低会恶化噪声表现;RREF 太大则信号占比太小,浪费分辨率,所以一定要按实际量程去平衡。

配套的电源和滤波也不能省。ADS122U04 的 AVDD、DVDD 都接 3.3V,每路电源引脚紧贴一颗 1µF 加 0.1µF 去耦电容,模拟地单点接地。RTD 引线我用的是双绞屏蔽线,屏蔽层在 ADC 侧单端接地。RREF 必须用低温漂精密电阻,25ppm/°C 的电阻在工业现场就是误差来源,预算允许就直接上 0.1% 精度、10ppm/°C 以下的金属箔电阻。

3. 固件落地:UART 协议、寄存器配置与温度换算

3.1 先把 UART 链路打通

ADS122U04 的 UART 不需要外部时钟,芯片内部自己起振,上电后会自动检测波特率。我这边固定用 115200、8N1 和它通信。接线就是最简单的三根线:MCU 的 TX 接 ADC 的 RX,MCU 的 RX 接 ADC 的 TX,GND 共地,两边都是 3.3V 电平,直连即可。上电时序是个容易被忽略的坑。ADS122U04 的复位完成需要一段时间,如果 MCU 复位后立刻发命令,芯片可能还没来得及完成波特率检测,导致第一帧必然失败。我的做法是 MCU 上电后先延时 10ms,然后发一个 NOP 或者读一次寄存器,确认链路通了再往下走。

这里顺便说一下它的命令集,常用的就这几个:

命令字节码作用
NOP0x00空操作,测试链路
RDATA0x12读一次转换结果,返回 3 字节
RDATAC0x14进入连续输出模式
SDATAC0x16退出连续输出模式
RREG0x20 起读寄存器,返回 1 字节内容
WREG0x40 起写寄存器,命令后跟数据字节
RESET0x06复位 ADC

连续模式有个实际问题:ADC 按数据率不断吐 3 字节,UART 上没有任何帧头帧尾,容易错位。我的处理是:程序里维护一个 3 字节滑动窗口,每收到一个字节就尝试按样本可信范围判断是否对齐,一旦发现异常就越界,就发 SDATAC 再发 RDATAC 强制重新同步。比如 PT100 在 -40°C 到 150°C 对应的码值区间是固定的,超出这个区间的数据基本可以判定为错帧。

3.2 寄存器配置与初始化流程

ADS122U04 的寄存器不算多,初始化流程就是把几个关键寄存器按测量对象写一遍。以三线制 PT100 为例,配置思路如下:SETUP 寄存器使能 PGA,增益选 1,PT100 信号几十毫伏,增益 1 就够了,增益大了反而把噪声一起放大;INPMUX 寄存器把模拟输入配成 AIN0-AIN1 差分对,同时把 IDAC1 路由到 AIN0;OPMODE 寄存器选 20 SPS 数据率,这个档位下 ΔΣ 调制器的数字滤波对 50Hz/60Hz 工频干扰有不错的抑制,HVAC 现场有大量工频设备,这是很实际的考量;IDAC 寄存器把 IDAC1 和 IDAC2 都设成 1mA,按三线制要求分别路由到对应引脚;REF 寄存器选择外部参考模式,参考输入接 REFP0/REFN0,也就是 RREF 两端。

写寄存器用 WREG 命令,格式是“0x40 加寄存器地址”再加一个数据字节。给一个最小可用的代码片段:

uint8_t adc_cmd_buf[2]; void adc_write_reg(uint8_t reg, uint8_t val) { adc_cmd_buf[0] = 0x40 | (reg & 0x0F); adc_cmd_buf[1] = val; uart4_write(adc_cmd_buf, 2); delay_us(200); // 留出 ADC 处理时间 } void adc_init_pt100_3wire(void) { adc_write_reg(0x00, 0x00); // SETUP:PGA 使能,增益 = 1 adc_write_reg(0x01, 0x20); // INPMUX:AIN0-AIN1 差分,IDAC1 路由到 AIN0 adc_write_reg(0x02, 0x00); // OPMODE:20 SPS,连续转换 adc_write_reg(0x03, 0x66); // IDAC:两路 1mA,按三线制拓扑路由 adc_write_reg(0x06, 0x10); // REF:外部参考(REFP0/REFN0) }

注意,这组数值对应的是我板上三线制 PT100 的接法,INPMUX 和 IDAC 的路由编码、电流档位编码请以数据手册的 Register Map 为准,直接照搬大概率不对。嵌入式项目最怕的就是“别人的初始化代码直接抄”,寄存器配置真正重要的不是那串数字,而是你清楚每一位在干什么。初始化完成后,发 RDATAC 进入连续输出模式,之后 ADC 每个转换周期自动吐 3 字节出来;也可以在需要时才用 RDATA 手动读,这种模式适合多传感器时分复用。

3.3 从码值到温度:PT100 换算式与代码

读回来的 3 字节是 24 位二进制补码,最高位是符号位。先转成有符号整数,再换算电阻,最后算温度。

int32_t adc_read_raw(void) { uint8_t b[3]; uart4_read_bytes(b, 3); int32_t raw = ((int32_t)b[0] << 16) | ((int32_t)b[1] << 8) | b[2]; if (raw & 0x800000) // 24 位有符号扩展 raw |= ~0xFFFFFF; return raw; }

电阻换算按前面说的比率关系来。三线制情况下,比例等于原始码值除以满量程,实际电阻等于比例乘 2 再乘 RREF:

double ratio = (double)raw / 8388607.0; double rtd_ohm = ratio * 2.0 * RREF_OHM;

然后做线性化。PT100 的 R-T 特性用 Callendar-Van Dusen 方程描述,0°C 以上是 R(t) = R0 × (1 + A×t + B×t²),其中 R0 = 100Ω,A = 3.9083e-3,B = -5.775e-7。反过来求温度,解这个一元二次方程就行:

double pt100_to_temp(double r) { double r0 = 100.0; double a = 3.9083e-3; double b = -5.775e-7; double delta = r0 * r0 * a * a - 4.0 * r0 * b * (r0 - r); if (delta < 0) return NAN; return (-r0 * a + sqrt(delta)) / (2.0 * r0 * b); }

这个公式在 0°C 到 850°C 范围内精度足够。如果要在 0°C 以下用,需要再加 C×(t-100)×t³ 项,那一项会让方程变成四次,没法直接解。工程上普遍的做法是:先按 0°C 以上公式算一个初值,再用 Newton 迭代两三步收敛到真值。HVAC 项目里 0°C 以下的场景不多,但工业冷库或北方冬季的室外温度测量会用到。NTC 和热电偶的换算是另一套逻辑:NTC 用 Steinhart-Hart 方程,热电偶要查分度表并做冷端补偿。ADS122U04 自带内部温度传感器,做冷端补偿很方便:先把 ADC 切到内部温度传感器通道,读芯片自身温度作为冷端温度,再从热电偶输出电压里减去冷端对应的电动势,剩下的才是被测端和冷端的温差电动势。温度换算做完,还要在 MCU 里做一步单位组织。我习惯把每个通道的原始码值、电阻值、温度值都存进一个结构体,调试时通过 UART 打印出来,这个习惯帮我省了无数次怀疑人生的时间。

4. 系统校准与现场抗干扰

4.1 两点校准怎么做才靠谱

再好的 ADC、再精密的电阻,装在板子上都会引入系统误差。我见过很多项目,硬件设计没问题,就是不做校准,结果温度始终差那么零点几度,控制逻辑怎么调都别扭。校准这件事在温度采集里是必须的。最简单的方案是两点校准:准备两只精度足够的电阻,一只阻值接近量程低温端,一只接近量程高温端。比如量程 -40°C 到 150°C,可以用 0.01% 精度的 100Ω 和 150Ω 精密电阻,分别代替 PT100 接到输入端,记录对应的电阻测量值 R_meas1、R_meas2。实际传感器电阻 R_true1 = 100Ω,R_true2 = 150Ω,得到校准公式:

R_corr = (R_meas - offset) × gain

其中 gain = (R_true2 - R_true1) / (R_meas2 - R_meas1),offset = R_true1 - R_meas1 × gain。把 gain 和 offset 存进 MCU 的 Flash,每次上电加载,之后所有测量值都先过一遍这个校正。有没有必要做三点校准?我的看法是,对于 HVAC 这种温区不太宽的场景,两点足够;热电偶或者宽温区工业测量,可以考虑三点甚至分段线性化,但工作量也会上来。校准的精度上限取决于标准电阻本身,所以标准电阻别省,0.01% 是最低要求。

4.2 数据稳定性的处理手段

硬件做好了,固件里还要再做一层滤波。我实测下来,20 SPS 的数据率配合 32 点滑动平均,响应速度和稳定性平衡得很好。具体做法是:先做中值滤波,窗口取 5 个点,把偶发的毛刺剔掉;再做滑动平均,窗口取 16 到 32 个点,压掉随机噪声;如果需要实时响应快一点,就缩短平均窗口,或者在 PID 控制里对温度做一阶低通,时间常数 5 到 10 秒。注意别把采样率调太高。ADS122U04 最高到 1000 SPS,但数据率越高,有效分辨率越低,工频抑制也变弱。HVAC 这种被控对象本身时间常数就很大,温度几秒才变一次,20 到 45 SPS 完全够用,还能换来更好的噪声性能。

现场抗干扰有几个细节我后来才真正体会到分量。第一,UART 走线和 RTD 采样线在板子上要尽量分开,不要在 ADC 下面走数字线;第二,如果 RTD 线要出端子排,屏蔽层必须在 ADC 侧单点接地,千万别两端都接地,否则会形成地环路;第三,如果现场有浪涌或 ESD 风险,输入端要加 TVS 管和串联限流电阻。我在这块板上加了 1kΩ 的输入串联电阻,对测量精度的影响可以忽略,但对保护 ADC 帮助很大。

5. 调试实录与避坑总结

5.1 实测中遇到的三个典型问题

第一个问题:上电后 UART 完全不通。现象是发 NOP 没任何反应,用示波器看 ADC 的 TX 引脚都没波形。查下来是 RESET 引脚默认状态没处理好,芯片一直停在复位状态;另一次是代码里上电后立刻发命令,芯片波特率检测还没完成。解决方式很直接:上电延时 10ms 以上,确保 RESET 引脚释放,再发命令。时序问题在调试初期特别容易忽视,建议第一次打样时就在固件里留足延时。

第二个问题:读回来的数据全是 0xFFFFFF 或者接近满量程的稳定值。这种通常是输入悬空或者 IDAC 没工作。我踩过一次,是寄存器配置里把 IDAC 的路由位写错了,电流根本没流到 PT100 上。排查方法很简单:向 ADC 发 RREG 读回刚才写进去的寄存器内容,看和预期是否一致。这一步能在 5 分钟内把“配置写错”和“硬件没焊好”分开,省了很多冤枉路。

第三个问题:数据跳变,尤其表现为几十个码值的抖动或者周期性波动。先排除是不是 PGA 增益过高,增益高了噪声也跟着放大;再查 RREF 是不是太靠近信号线,参考电压被污染;最后查参考电阻和去耦电容。我在一块测试板上发现,把 RREF 从 100Ω 换成 150Ω 之后码值抖动明显改善,就是因为参考电压太低时,PCB 上的微小干扰在参考通道上更加敏感。这几个问题整理成速查表,方便现场排查:

现象可能原因排查/处理
UART 无响应复位未释放、上电时序太早、波特率不匹配检查 RESET、延长上电延时、发 NOP 测试
数据满量程输入悬空、IDAC 未配置、传感器断开RREG 回读寄存器,检查接线和 IDAC 路由
读数整体偏移引线电阻、RREF 偏差、未校准做两点校准,换低温漂 RREF
读数周期性波动工频干扰、参考电压受污染用 20SPS 数据率、加屏蔽、优化 RREF 布局
毛刺型跳变ESD/浪涌、继电器干扰加 TVS、输入串联电阻、软件中值滤波

5.2 这个方案还能怎么扩展

ADS122U04 有 4 个输入通道,目前我只用了两路做一组三线制 PT100。如果要把四个通道都用起来,可以这样分配:两路做 PT100 或 PT1000 差分输入,一路做 NTC 单端输入,一路接热电偶。每个通道的数据率、PGA 增益、IDAC 路由都不一样,初始化时按通道分别配置,然后按顺序读取即可。对于 HVAC 来说,温度往往不是孤立的。变风量系统里要同时测风温、水温和湿度,冷热量计量还要测流量。STM32L4S5ZI 的资源完全可以在这个基础上再接湿度传感器和流量计,把温度采集作为整个环境监测子系统的核心节点。如果想进一步降低现场施工难度,可以在这个方案外面加一层无线模块,把温度数据通过 BLE 或 LoRa 上报到网关。STM32L4S5ZI 的 Flash 和 RAM 跑这些协议栈毫无压力,这也是当初选这颗芯片而不是更小型号的原因之一。

最后说点个人体会。做温度采集,真正拉开差距的不是芯片型号有多高端,而是你对整条信号链的理解:从传感器的物理特性,到 ADC 的比率测量原理,再到 PCB 布局和固件滤波,每一环都会在最终数据上留下痕迹。ADS122U04IPWR 和 STM32L4S5ZI 这套组合,接口简单、精度够、扩展性好,是我这几轮项目做下来最顺手的一套。如果你正打算做工业或 HVAC 的温度测量,希望这篇记录能帮你少走几段弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询