ADS122U04与STM32的工业高精度温度采集方案

发布时间:2026/11/5 6:29:00
ADS122U04与STM32的工业高精度温度采集方案

做工业仪表和楼宇自控的同行,应该都体会过“选测温方案”这种事:量程要够宽、精度要够高、现场干扰还得顶得住,最后成本还得压下来。我最近在做一个暖通空调(HVAC)风管温度采集节点,同时要兼顾一台小型锅炉的热电偶监测,最终定的方案是用 TI 的 ADS122U04IPWR 配合 STM32F091RC。这个组合不算什么新潮架构,但用下来非常顺手,尤其是在需要把模拟前端和数字核心彻底隔离的场景里,省掉了很多麻烦。

ADS122U04 是一颗24位 ΔΣ ADC,片内带 PGA、基准源、激励电流源和温度传感器,最关键的是它通过 UART 接口输出数据,而不是常规的 SPI/I2C。这一点在工业现场挺有讲究:UART 只需两根线就能完成双向通信,还方便做成隔离或者远传,配合 STM32F091RC 的多个串口资源,固件侧几乎零成本接入。很多工程师一听到“24位 ADC 还要加一颗 MCU”就觉得夸张,实际上在 HVAC 这种温度变化缓慢、需要长期稳定的场景里,高分辨率加数字滤波带来的红利,远远超过增加的那点 BOM 成本。

这篇文章就把这套方案聊透:从芯片选型、传感器接入、寄存器配置,到 STM32 固件怎么把 ADC 码值换算成真实温度,最后再附上我实测踩过的坑。无论你是做工业仪表的老手,还是刚接触高精度测温的嵌入式新人,照着这个思路走,都能少绕几圈弯路。

1. 方案选型:为什么是 ADS122U04IPWR + STM32F091RC

1.1 ADS122U04 到底特殊在哪

先聊这颗 ADC。ADS122U04 的“U”后缀是 UART 接口版本,同系列还有 ADS122C04(I2C版),以及不带后缀的 SPI 版本 ADS1220 之类。四通道、24位、内置 PGA,这都不稀奇,稀奇的是 TI 把 ΔΣ ADC 的读数据接口做成了 UART,还支持多个器件挂在同一条总线上通过地址寻址。这个特性在工业场景里是实打实的优势:SPI 线多、距离短、还容易被地电位差搞出噪声;I2C 虽然线少,但是速率和抗干扰又不尽如人意;UART 天生就是点对点长距离传输的料,稍微加个隔离芯片,模拟端和数字端就能干净利落地分开。

再说片内资源。ADS122U04 的 PGA 增益范围从 1 到 128 共 8 档,既可以直接接热电偶的毫伏级小信号,也能接 PT100 经过激励电流产生的几百毫伏信号;内部基准电压典型值 2.048V,温漂约 10 ppm/°C,对于常规工业温度测量来说足够稳。它还带了两个可配置的低噪声激励电流源,做 RTD 三线制比例测量非常方便,省掉了外部分立恒流源电路。片内还有一个温度传感器和供电电压检测,前者可以用来做热电偶冷端补偿的辅助参考,后者能在现场电压跌落时提前预警。

这颗芯片的工作电压范围是 2.3V 到 5.5V,我用 3.3V 和 5V 两种电源都跑过。个人建议如果测量对象是热电偶,模拟电源尽量用 5V,因为内部基准和 PGA 的余量更充足;如果单纯做 PT100/NTC,3.3V 也够用。功耗方面,正常工作电流约 500μA 多,关断模式更是低到微安级,做电池供电的无线温湿度传感器也不是不行。

1.2 STM32F091RC 在这个项目里担任什么角色

STM32F091RC 是意法半导体 Cortex-M0+ 内核的 MCU,主频 48MHz,内置 256KB Flash 和 32KB SRAM。放在温度采集项目里,这个性能绰绰有余:它不需要跑复杂的算法,只需要管好 ADC 的数据读出、滤波、换算、以及对外通信。

选择 F091 而非 F103 或者 G0 系列,有几个具体原因。第一是串口资源,F091 有多达 8 个 USART/LPUART,我把其中一个接 ADS122U04,另一个接上位机 Modbus,还有一个留着做调试,完全不用共用引脚,省去切换方向的心智负担。第二是 M0+ 内核在 48MHz 下跑温度换算这种纯整数/浮点混合运算,实测一个 ADC 采样周期(比如 20SPS 时一个周期 50ms)内能轻松完成所有处理,算力冗余很足。第三是这颗料价格便宜、供货稳定,在工控产品里属于“不心疼”的选择。

有人可能会问:那为啥不用 STM32 内部自带的 12 位 ADC,非要外挂 24 位?这是因为热电偶信号满量程也就几十毫伏,12 位 ADC 在 3.3V 参考下分辨率大约 0.8mV,对应 K 型热电偶的温度分辨率已经到 20°C 量级,完全不可用。即便用内部 PGA 放大,噪声地板还是远远比不上 ΔΣ 架构。所以在低带宽高精度的测温领域,配备高分辨率外部 ΔΣ ADC 依然是可靠的选择。

1.3 与 SPI/I2C 方案的对比

我早期试过用 SPI 接口的 ADS1220 接 F091,当时碰到的问题是:SPI 线必须短,模拟前端和数字主控稍微拉远一点,通信就容易受干扰;而且 SPI 的四根线在 PCB 上占地方,做隔离也更麻烦。后来换到 ADS122U04,通信线减少到一行串口接线,配合隔离芯片,整个模拟前端就可以和主控板分开布置,这对 HVAC 风管内的探头模块设计非常友好。

I2C 方案我也评估过,速度偏低不说,外加上拉电阻在长线上容易引入噪声,多设备挂在总线上还涉及地址冲突。ADS122U04 的 UART 虽然也是半双工模式(发送命令和读取数据共用同一组线或分时),但在 19.2kbps 到 44.4kbps 的常用波特率下,读取 24 位结果加配置命令的耗时在毫秒级,对于最高 1000SPS 的采样率绰绰有余。如果后端还需要走 RS-485,串口信号更是可以直接对接,连电平逻辑转换都省了一道。

对比项ADS122U04(UART)ADS122C04(I2C)ADS1220(SPI)STM32内部ADC
通信线数量2(+地)2(+地)4-5无外部通信
通信距离远,易隔离短极短局限板内
分辨率24位24位24位12位
热电偶直连支持(PGA)支持(PGA)支持(PGA)勉强(噪声大)
多设备组网支持地址寻址支持地址寻址需片选扩展不支持
典型场景工业远传板级高精度仪表内部常规电压采集

结论很直接:如果你的温度探头和主控板必须分开放,或者你担心 SPI 线缆的干扰,UART 版本是最舒服的选择。如果一切都挤在同一块 PCB 上,SPI 版也能用,只是布线要小心。

2. 传感器接入与模拟前端设计:热电偶、RTD、NTC 的接法

2.1 热电偶:毫伏信号如何正确调理

HVAC 系统里热电偶最典型的应用是锅炉排烟温度、燃烧器表面温度这类超过 300°C 的场合。K 型热电偶的灵敏度大约 41μV/°C,在 0°C 到 600°C 范围内输出也就 0 到 24mV 左右。这么小的信号,直接用 ADC 的 24 位分辨率去量化是没问题的,但前提是 PGA 要开起来。

我的接法是把热电偶正极接到 AIN 通道的正输入,负极接到 AIN 负输入,然后把 PGA 增益设为 32 或 64。以增益 64 为例,K 型热电偶 600°C 时的 24mV 被放大到约 1.54V,正好落在内部基准 2.048V 的量程中段,此时 LSB 等效电压约为 2.048V / 2^24 ≈ 0.122μV,对应温度分辨率优于 0.003°C,完全够用。当然,实际噪声不可能达到理论值,但有效分辨率做到 0.01°C 量级是没问题的。

热电偶有两个容易踩的坑:一个是共模电压,一个是冷端补偿。如果热电偶探头和加热设备之间形成接地环路,共模电压可能超出 ADC 允许范围。解决方法是先确认现场电源和传感器之间没有非预期回路,必要时用隔离供电,让模拟地浮空。另一个是冷端补偿,热电偶输出的电压是相对于冷端(接线端子处)的温差电压,所以你必须知道冷端温度。我这里用板载一个 NTC 紧贴热电偶接线端子,再配合 ADC 内部温度传感器做双重校正,实测冷端精度大约能控制在 ±0.3°C,换算到总温度误差约 ±0.3°C。

ADS122U04 还支持热电偶烧毁检测。寄存器里配置好之后,它会在测量通道上周期性叠加一个检测电流,如果测量值跳到满量程,通常说明探头断线。这个功能我强烈建议打开,因为 HVAC 现场的电工师傅可不会拿着万用表挨个测探头好坏,断线报警能省大量售后时间。

2.2 RTD 三线制和比例测量

风管温度、回水温度这类 -50°C 到 200°C 的场合,我的首选是 PT100 或者 PT1000 铂电阻。PT100 的问题是 0°C 时阻值仅 100Ω,到 100°C 时约 138.5Ω,变化量只有 38.5Ω。如果激励电流 1mA,满量程信号只有 38.5mV,同样需要 PGA 放大。

RTD 测量有个原则:必须用比例测量,而不是拿激励电流产生电压后再和一个固定基准比较。因为激励电流会有温漂,基准电压也会温漂,如果电流和基准是同源的,漂移就会相互抵消。ADS122U04 的内部激励电流源正好提供了这个条件:用 IDAC 电流流过 RTD,产生的电压输入到 ADC,ADC 的参考电压则取自同一个电流流过精密参考电阻产生的电压。这样算下来,RTD 阻值只取决于两个电阻的比值,跟电流绝对值和基准绝对值都无关。

三线制接线是为了消减引线电阻。两根引线分别走 RTD 的两端,第三根线用来补偿远端地端的引线电阻。实际操作中我用 1mA 激励电流,这样自热功率只有 100μW 量级,PT100 的温升可以忽略。通道配置方面,我将 RTD 的高端接到 AIN1+,低端接到 AIN1-,参考电阻接在 REFP/REFN 上,IDAC1 输出接到 RTD 上端,IDAC2 用来补偿引线电阻。这个模式需要好好读寄存器说明,TI 的 datasheet 里有一张典型应用表格,照着抄就行,第一次用容易把 REF 极性搞反。

2.3 NTC、半导体温度计与备用通道

HVAC 里还有一个常用传感器是 NTC 热敏电阻,比如 10kΩ 的 B=3950。NTC 的优点是便宜、响应快、非线性大,适合做风管内的辅助温度,或者冷凝水管表面温度。接法上,我把 NTC 做成分压结构:激励电流源不参与,直接用 ADC 内部 2.048V 基准作为分压电压源,NTC 和一个精密电阻串联,中间点接 ADC 输入。这样做虽然不如比例测量严格,但对 NTC 的应用精度已经足够。

NTC 的非线性用查表法解决最直接。我把 -40°C 到 150°C 的温度表和对应的 ADC 码值存入 Flash,运行时二分查找再线性插值,实测误差能控制在 ±0.2°C 以内,而且速度很快,几十个周期就能找完。也可以用 Steinhart-Hart 公式计算,但查表方式在 Cortex-M0+ 上更省事。

这四路通道我平时只开两路热电偶、一路 PT100 和一路 NTC,正好对应锅炉、风管、回水和环境温度四个测点。ADS122U04 的四通道是单端/差分复用,我全部按差分模式配置,因为 HVAC 现场电机变频器多,差分输入能抵消大部分共模干扰,比单端可靠得多。

3. 关键参数解析:寄存器、数据速率、数字滤波怎么配

3.1 八个寄存器一次讲清

ADS122U04 内部有 8 个 8 位寄存器,基本上所有功能都在这里配置。我贴一下我在项目里实际用的配置表,并解释每一字节的关键位:

寄存器值含义
寄存器00x2EPGA 增益 64,通道选择差分 AIN0/AIN1
寄存器10x24数据速率 20SPS,开启 50Hz/60Hz 抑制滤波
寄存器20x0F基准为内部 2.048V,使能热电偶偏置电流,烧毁检测开
寄存器30x10IDAC1 输出到 AIN0,IDAC2 电流 1000μA 档位
寄存器4-7按需系统状态、多通道扫描序列、GPIO 配置等

寄存器0 主要配置增益和输入通道。PGA 增益的选择依据是:期望输入满量程除以参考电压后,留出 20% 余量,防止瞬间过压把输出限制在满量程。比如热电偶最大 24mV,参考 2.048V,增益 64 时最大放大后 1.536V,此时余量仍有 25% 左右,这个比例很舒服。

寄存器1 里的数据速率和滤波器设置是精度关键。ΔΣ ADC 有个特点:数据速率越低,数字滤波器抑制工频干扰的能力越强。20SPS 时,滤波器对 50Hz/60Hz 及其整数倍都有很强的陷波效果,这在 HVAC 现场简直是救命功能。如果你需要更快的响应,可以提到 200SPS,但这时候 50Hz 附近的抑制会明显变弱,建议外部模拟滤波跟上,把截止频率压到几十赫兹。

寄存器2 里我同时开了偏置电压和烧毁检测,这里有个细节:偏置电压会把输入信号拉到一个已知电位,防止热电偶开路时 ADC 输入端悬空,导致随机电平把读数打成漂移值。烧毁检测检测的是开路状态,两者配合起来,能明确区分“传感器断线”和“温度超限”。

寄存器3 是激励电流源配置,RTD 和热电偶的用法完全不同。RTD 用 IDAC1 提供 1mA 电流,热电偶不用激励电流,IDAC2 可以完全关掉,避免电流流过热电偶产生自热。这个细节很多人容易忽略,自热虽然只有几十微瓦,但对精密测温来说一样会引入误差。

3.2 数据速率与响应时间的平衡

ADS122U04 的数据速率从 1.8SPS 到 1000SPS 可调。我在项目中做了两个版本的固件:室内空调箱的温度采集用 20SPS,因为风管温度变化非常缓慢,20SPS 配合内部 FIR 滤波能得到极低的噪声;锅炉烟温用 50SPS,因为燃烧状态起伏相对快一些,同时还要避开变频器的谐波干扰。

选择数据速率时,你要先算清楚系统的时间常数。比如 20SPS 下,单个转换周期是 50ms,加上数字滤波器的群延迟,从温度突变到 ADC 输出达到稳定值,大约需要 3 到 5 个周期,也就是 150 到 250ms。HVAC 的控制环通常是秒级,这个延迟毫无压力。但如果用户拿这个系统去做实验室里的小型环境箱,要求 1 秒内看到温度阶跃,那就得把速率提到 100SPS 以上,噪声会稍微高一点,但控制响应优先。

另一个容易被忽略的是串口读取时序。ADS122U04 的转换结果准备好在数据寄存器后,如果长期不读取,新数据并不会覆盖,而是会挂起或根据配置选择。我固件里做了一个“读最新值”的循环:每次进定时器中断,先发读取命令拿到上一次转换结果,再做均值滤波,确保不丢数据。这个做法的好处是数据曲线连续,不会出现采样间隔不均匀造成的台阶。

3.3 基准电压和电压噪声

ADS122U04 的内部基准优缺点是分明的:优点是简单、温漂低;缺点是切换通道后需要一个稳定时间,尤其在基准缓冲刚打开时,前几个转换结果会略微偏大。我实测过,通道切换后前 4 个读数直接丢弃,从第 5 个开始才算有效,这个经验在写固件时非常有用。

外部基准我建议如果有条件,可以接一个高精度 2.5V 或 2.048V 的基准芯片(比如 REF5025),把 ADS 的 REF 引脚接过去。比例测量的 RTD 不依赖绝对基准,但热电偶测量用内部基准已经够好,外置基准提升的空间不大。如果就是为了追求极致的长期稳定性,外置基准加上定期自校准,可以做到一年下来总漂移小于 0.05%。

还有一个玄学但真实的问题是电源噪声。ADS122U04 的数字电源和模拟电源最好是分开走线,或者至少用磁珠做单点连接。我用 LDO 输出 3.3V 给 F091,再单独用一个低噪声 LDO 输出 3.3V 给 ADS 模拟电源,实测噪声比共用一个 LDO 低差不多 1/3。ΔΣ ADC 确实有一定电源抑制能力,但开关电源的高频纹波还是能渗透进来,尽量别省这几十毫安的成本。

4. STM32F091RC 固件实现:从寄存器到真实温度值

4.1 UART 对接:接线、时钟与中断

ADS122U04 的 UART 模式并不复杂,本质上就是把 ADC 当成了一个带地址的串口从机。正常工作时,主控发送两三个字节的命令帧,ADC 返回对应的数据帧。它的地址是由引脚 ADDR[2:0] 决定的,一个 UART 总线上最多挂 8 颗 ADS122U04,每一颗配置不同地址,命令帧里带上地址字节,从机按地址响应。

我用 F091 的 USART1 接 ADC,波特率 19.2kbps,8 位数据,偶校验。F091 的 UART 支持硬件校验,这能省掉软件奇偶校验的 CPU 开销。接线方式:MCU_TX 接 ADS 的 DIN/RX 端,MCU_RX 接 ADS 的 DOUT/TX 端,因为是半双工方式,实际硬件上也可以共用一根线,然后用 GPIO 控制方向。我因为走线方便,采用了全双工交叉接线,一收一发两根线,这样软件上不用频繁切换方向,更省心。

中断设计上,我启用了 F091 的 USART1 RXNE 中断,每收到一字节就丢进一个环形缓冲区。ADC 的响应数据长度是固定的,上层状态机按字节数判断一帧是否收满,收满后置事件标志,主循环里取出来处理。整个中断只有 20 行左右的代码,非常轻量。

4.2 单次转换与连续扫描两种模式

ADS122U04 支持单次转换和连续转换。之前在 HVAC 节点里,我两种都用过,最终选的是单次转换:每次需要读数时,发 START 命令,等待 52ms 再读结果。这样平均电流更低,而且多个 ADS 挂在同一总线上时不会互相争抢总线。

连续模式的好处是数据更新均匀,不需要每次发启动命令,适合用 DMA 批量接收。坏处是,如果主控被打断,数据可能在缓冲区里堆积,时间一长你就不确定读到的哪组对应哪个时刻。对于 HVAC 这种慢系统,单次转换完全没有问题,代码也更直观。

让我贴一段核心读数据代码,这是我在项目里实际使用并验证过的逻辑:

/* 从ADS122U04读取一次转换结果,返回原始24位码值 */ int32_t ads122u04_read_single(uint8_t ch) { uint8_t cmd[3]; uint8_t buf[3] = {0, 0, 0}; uint16_t timeout = 100; /* 寄存器0: 0x2E 为 PGA=64, AIN0/AIN1 差分;ch=1 时切换到通道2 */ if (ch == 0) { cmd[0] = 0x2E; } else { cmd[0] = 0x36; /* AIN2/AIN3差分,PGA=64 */ } cmd[1] = 0x24; /* 20SPS, 50/60Hz抑制 */ cmd[2] = 0x0F; /* 内部基准, 偏置和烧毁检测使能 */ uart_send_buf(cmd, 3); delay_ms(1); uart_send_byte(0x10); /* START 采集命令 */ while (--timeout) { /* 20SPS单次转换需要50ms,这里至少等50ms */ if (ads_has_data_flag) { break; } os_delay(5); } uart_send_byte(0x20); /* RDATA 读数据命令 */ recv_bytes_with_timeout(buf, 3, 100); return (buf[0] << 16) | (buf[1] << 8) | buf[2]; }

这段代码干净利落,核心就是三条命令:写配置、启动转换、读数据。凡是超过 100ms 没有返回,上层就直接报通信超时,不会让系统死等。在实际项目中,ads_has_data_flag可以由收到串口数据的回调置位,也可以用周期定时器查询,我更推荐后者,因为读取节奏完全由主控决定,不会因为 ADC 响应快慢而漂移。

4.3 码值到温度的换算:热电偶和 RTD 分别怎么算

拿到 24 位码值后,接下来是纯数学活。先要把 ADC 码值换算成电压:

[ V_{in} = \frac{Code}{2^{24}-1} \times \frac{V_{ref}}{PGA_gain} ]

内部基准 2.048V、增益 64、正负差分输入,所以实际量程是 ±2.048V/64 = ±32mV。24 位码值中最高的位是符号位,处理时要符号扩展。换算出来的电压是热电偶的温差电压 (V_{tc}),再用冷端温度 (T_c) 查标准 NIST 多项式,得到热端温度 (T_h)。K 型热电偶可以用 ITS-90 多项式拟合,也可以用分段线性表。我建议在嵌入式里用查表后线性插值,因为多项式阶数高了在 M0+ 上算起来太慢。

RTD 的换算更方便,因为比例测量的结果已经和激励电流无关:

[ R_{rtd} = \frac{Code_{rtd}}{Code_{ref}} \times R_{ref} ]

然后查 PT100 的分度表,同样是查表加插值。Callendar-Van Dusen 公式是另一种方法,但查表的方式代码简单、边界条件好控制,我在项目里就是用查表,100 个点的表存 400 字节,Flash 空间完全不在乎。

冷端补偿我再说细一点。我采用的方法是:每次读取热电偶通道电压的同时,也读 ADC 内部温度传感器或者外部 NTC 的数值。读内部温度传感器时,要注意它是二极管类型,输出电压线性度一般,需要根据数据手册做校准。实际上我在板上放了一颗 NTC 紧贴接线端子,低温漂电阻分压,再用 ADC 另一个通道去读它。这样做的原因是:ADC 芯片温度和接线端子温度之间还有 PCB 传导延迟,外部 NTC 更接近真实冷端温度。

4.4 数字滤波:一阶低通与中值滤波

ADS122U04 自带的数字滤波器主要做工频抑制,但它对随机的尖峰干扰没辙。我给温度值加了一层软件滤波,方法很朴素:先做 5 次采样中值滤波,把异常毛刺踢掉,再做一阶低通平滑。

中值滤波的窗口大小要小心,窗口太大,真实温度变化被误判为毛刺,滞后会明显。我用的是 5 点中值,对 HVAC 应用来说,稳妥又不迟钝。一阶低通的系数取 0.2 到 0.3 比较合适,过高会让温度曲线平滑,但反应变慢;过低则噪声依然明显。我调试时实际输出过原始数据和滤波后数据,两者相差明显:原始数据在 25°C 表显下有 ±0.05°C 的跳动,滤波后降到 ±0.01°C 以内。

滤波的副作用是:如果现场真发生温度跳变(比如突然通入 100°C 蒸汽),滤波后到达 90°C 需要几秒钟。这对 HVAC 的 PID 控制反而有益,因为控制回路不需要那么快的传感器响应;但如果你同时也做超温报警,建议报警逻辑从滤波前的原始值取,这样报警更及时,不至于因为滤波滞后而错过危险温度。

5. 常见问题与排查技巧实录

5.1 排查速查表:症状、原因、对策

我把三个月现场调试和加班排障整理成了一份问题速查表,直接分享给各位参考:

症状可能原因排查步骤对策
读数恒定满量程热电偶断线或接线松用万用表测传感器两端电阻启用烧毁检测,实现断线报警
读数乱跳无规律线缆受变频器干扰示波器看ADC输入波形差分接入+屏蔽双绞线;降低数据速率
读数缓慢漂移冷端温度未补偿对比热电偶和标准温度计正确放置冷端传感器,做双点校准
通道切换后前几个值异常基准或滤波器建立时间不足打印原始通道切换后的数据丢弃前4个转换结果
RTD 读数偏低或偏高引线电阻补偿未配置短接RTD测回算阻值改用三线制并正确配置 IDAC2
通信超时波特率不一致或接线不对用示波器抓 UART 波形确认 8 位数据偶校验,核对TX/RX
转换结果恒为0ADC未收到START命令检查命令帧中地址位核对地址字节,确保从机ACK

这些现象我基本都遇到过。其中“读数乱跳”是最折腾的一次,最后发现是市电 50Hz 通过探头屏蔽层耦合进来,普通滤波器压不住,换 20SPS 数据率加软件中值滤波后立刻安静下来。串口超时则是开机时序问题,ADC 电压还没稳定就发命令,结果是弃了前五条命令后一切正常。

5.2 热电偶冷端补偿不准的坑

冷端补偿不准是个隐蔽问题。我一开始把 NTC 放在 PCB 的角落,结果环境温度变化时,NTC 温度总是比接线端子温度滞后 5-10 分钟,导致开机后一小时内的温度读数长期偏差 0.5°C 以上。后来我把 NTC 改用导热胶直接贴在端子排的金属部分,并在固件里让 ADC 每次采完热电偶后立即采集 NTC,时间差控制在 20ms 内,问题就消失了。

经验是:冷端传感器不是“放在同一块板上就行”,而要和热电偶端子有良好的热接触。在风管空调箱这种温度波动温和的环境还好,如果是露天机柜,昼夜温差十几度,这块必须较真。

另外,K 型热电偶本身还容易因为材质不均匀产生附加误差,通常 ±1-2°C。这不是 ADC 或软件能救的,所以在对精度有严格要求的点位,我会选更高等级的探头,或者干脆换 PT100。你可以跟客户说清楚,热电偶量程宽但精度有限,PT100 精度高但量程窄,没有万能的选择。

5.3 接地环路与隔离对策

工业现场最让人头疼的是地环路。我在一个锅炉房调试时,热电偶探头和被加热管道接触良好,但管道本身金属外壳连着电网地,控制系统电源又是另一路地,两边电位差硬生生加到了 ADC 输入端,读数直接飘了十几度。

解决手段是隔离。我把 F091 侧供电用隔离 DC-DC,UART 之间加数字隔离器,模拟地单独浮空。隔离后,电位差不再有环路电流,信号干净了,读数稳定了。如果只是探头端简单浮空,通常也能解决,但耐压和可靠性不如整体隔离。ADS122U04 的低功耗特性配合隔离供电,整个模拟前端加传感器,总电流不到 2mA,非常适合做长线分布采集。

5.4 关于“24位”的正确认识

说到 24 位,很多新手以为分辨率无穷大,其实远不是这样。24 位 ADC 的有效位数受噪声限制,在 20SPS 数据率下,ADS122U04 能达到 21 到 22 位有效分辨率已经算不错。但这并不影响它做精密测温:22 位有效分辨率,在 ±32mV 量程下对应约 15nV,就算折半也有 30nV,折合 K 型热电偶温度分辨率仍然优于 0.001°C。真正限制精度的是传感器本身、基准温漂、以及系统的校准水平,而不是 ADC 位数。

千万不要迷信“24位就必须高性能”,关键看系统整体。把这个 ADC 配上高精度基准、细心布局的模拟前端、标准温度计校准,最后整体误差能做到 0.1°C 以内,这才是它真正的价值。

6. 固件架构的一点心得:用状态机管理复杂时序

6.1 任务调度比你想的重要

ADS122U04 的串口交互虽然简单,但当你同时要读取 4 个通道、处理 Modbus 请求、定时刷新冷端补偿时,裸奔代码容易变成一锅粥。我建议从一开始就用简单的状态机调度,而不是写长循环阻塞等待。

我设计了一个状态机,状态依次是:空闲 → 发送配置命令 → 等待转换完成 → 读取数据 → 执行滤波算法 → 更新温度表 → 回到空闲。每次状态切换都由定时器中断触发,主循环只处理 Modbus 帧和报警判断。这样一个状态机跑了三个月,没出现过一次多路通道数据错乱的情况,代码结构也清晰,后面同事接手也不费劲。

6.2 参数校准与存储策略

设备校准是工业仪表绕不开的环节。我在系统里留了 4 组校准系数,分别对应零点偏移和增益误差。出厂校准时,用标准铂电阻温度计配合干体炉,分别在 0°C、50°C、100°C 三个点做修正。修正系数存到 F091 的 Flash 末页,上电时读出来,如果校验和失败就用默认值。

这里要提醒一个细节:F091 的 Flash 擦写次数有限,不能每次校准都直接擦写。我的做法是:平时校准值只缓存到 RAM,只有收到上位机的“保存”命令才写入 Flash。这样可以避免现场频繁校准导致 Flash 寿命迅速耗尽。

6.3 通信协议设计

和上位机通信我用的是简化版 Modbus-RTU,一个温度节点就几十个寄存器,非常轻松。对 ADS 的原始码值、滤波后温度值、断线状态、版本号这些信息,分别映射到不同的保持寄存器。这样调试时可以直接用 Modbus Poll 工具看数据,省得每次开串口助手输十六进制。

如果你不想上 Modbus,也可以用简单的 ASCII 帧协议,比如“@01TEMP ”这种。但工业现场大家默认都认 Modbus,建议不要省这个功能,它往往是客户验收的第一道门槛。

7. 最后的经验:这套方案如何扩展到更多点位

这套 ADC+MCU 的架构,最大的价值在于可扩展。ADS122U04 支持最多 8 颗共挂在一条 UART 总线上,每一颗负责 4 路模拟输入。也就是说,一颗 F091 最多可以通过一个串口扩展出 32 路高精度测温通道。对 HVAC 这种点位分散、数量随楼层增长的系统,这是很实用的能力。

我实际做的一版采集器,用了三颗 ADS122U04,共 12 路输入,其中 8 路 PT100 供风管温度,4 路 K 型热电偶供锅炉测点,全部走一条 UART 总线。固件里通过地址字节区分设备,每个设备内的通道再通过寄存器配置切换,数据上传到 F091 后统一编号。整个采集面板比 A4 纸还小,而测温精度和成本都压到了很理想的区间。

如果后续还想扩展,可以考虑增加无线模块,把 F091 算好的温度值直接上传给 LoRa 网关或 Wi-Fi 模块。因为前端的 ADC 采集和处理已经完成了,后端只需要把数据打包,整个系统就能从有线采集平滑升级为无线传感网络,这也是我当初把处理逻辑放在 F091 而不是上位机的原因之一。

最后分享一个个人习惯:不要急着贴 ADC,先把传感器、基准、电源的“坑”填完。绝大多数温度测量项目,最后的误差大头往往不是 ADC 芯片,而是冷端、参考电阻、PCB 漏电流或者不合理的接地。把这些基础问题解决掉,ADS122U04 配合 STM32F091RC 就是一套能让你安稳睡觉的测温方案。