ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ADS122U04+STM32L073RZ高精度工业温度采集方案

ADS122U04+STM32L073RZ高精度工业温度采集方案

做温度和暖通空调(HVAC)项目的人,应该都体会过这种尴尬:传感器明明选的是高精度型号,主控也算力充足,但实测温度飘得就像在跟你玩躲猫猫。尤其是工业现场和暖通末端,长线缆、变频器干扰、电网波动、冷端温度漂移,任何一个环节都能把“高精度”三个字变成笑话。

我最近刚完成一个基于ADS122U04IPWR和STM32L073RZ的温度采集方案,专门用来覆盖工业空调箱、冷水机组和风管温度监控这类场景。ADS122U04IPWR 是一颗带 UART 接口的 24 位 Δ-Σ ADC,STM32L073RZ 则是一颗主打超低功耗的 Cortex-M0+ 单片机。这两个器件组合起来,既能伺候 PT100/PT1000 热电阻,也能接热电偶和 NTC,采集链路干净利落,通信布线还特别简单。这篇就把我的选型思路、硬件接线、寄存器配置、校准方法和调试踩坑一并写出来,给正在做同类测量方案的朋友一个可复现的参照。

1. 先聊聊工业和 HVAC 对温度测量的真实需求

很多人以为测温就是把传感器往被测物体上一贴,然后读个数。实际去现场跑一遍就会发现,事情远没有那么简单。

工业机柜里的电机绕组温度、压缩机排气管温度、液压系统回油温度,这些点往往远离主控板,线缆要走上好几米甚至十几米。线缆一长,问题就来了:一是线路电阻会带来附加误差,二是工业环境里的变频器、接触器会产生强烈的电磁干扰,三是传感器本身的非线性需要处理。HVAC 领域稍微温和一点,但也同样有痛点,冷冻水进出水温度、风管送风温度、回风温度、表冷器盘管温度,这些测量点分散在楼宇各处,对功耗、布线和维护成本都很敏感。

所以,做这类系统的核心思路不是“选一个贵传感器”,而是把模拟前端、信号调理、数字化转换和主控通信这几个环节整体优化。这也是我选择 ADS122U04IPWR 的根本原因:它把多路复用器、可编程增益放大器(PGA)、24 位 Δ-Σ ADC、激励电流源和 UART 接口全部集成在一颗芯片里,相当于把“模拟前端”和“通信接口”打包了。主控端不用再操心模拟电路设计和 SPI 时序抖动,直接用 UART 收发命令和数据就行。

再配上 STM32L073RZ,这颗 MCU 的优势也很明显。它跑在 32 MHz 的 Arm Cortex-M0+ 内核上,有 128 KB Flash 和 20 KB SRAM,功耗控制做得相当好。在需要电池供电的 HVAC 温控节点里,它可以进 STOP 模式,靠 LPUART 或 RTC 定时唤醒,把整个节点的平均功耗压得很低。更重要的是,它本身就有多个 USART 外设,和 ADS122U04 的 UART 接口天然匹配,不需要额外搭电平转换或者模拟 SPI,硬件上省掉一大截。

这套方案最后能做到什么水平?拿 PT100 来说,在 -50℃ 到 150℃ 的常用区间内,经过两点校准后,系统级精度可以稳定做到 ±0.1℃ 以内。对于 HVAC 应用,这个精度已经远超验收要求;对工业现场,也能满足绝大多数过程监控的指标。

2. 为什么是 ADS122U04 + STM32L073RZ 这个组合

2.1 选型时对比过的其他方案

做方案设计的时候,我其实先考虑过两条常规路线。第一条是直接用带温度采集功能的 PLC 模块或者专用信号调理芯片,但这玩意单路成本高、通道数固定、灵活性差,而且往往需要配套专用总线协议,和自研主控对接很麻烦。第二条是采用高分辨率 ADC 加 MCU 的经典组合,比如 ADS1220 加 STM32,走 SPI 接口,这也很常见,但在长线缆、高干扰的工业现场,SPI 的时钟抖动和主控侧的中断延迟都可能成为噪声来源。

相比之下,ADS122U04IPWR 用 UART 接口替代 SPI,这个设计在我实际项目里带来的好处非常直观。UART 本身就是异步传输,对时序的要求比 SPI 宽松得多,主控这边不需要用定时器去精确控制时钟。ADC 的转换结果准备好之后,通过 DRDY 引脚拉低来通知主控,主控在空闲时间读数据就可以,这种机制天然规避了 SPI 时序竞争。

另外这颗 ADC 内部还集成了激励电流源和低侧电源开关。做 PT100 测量时,不再需要外置高精度恒流源电路,直接配置内部 IDAC 输出 1 mA 或者 0.25 mA 给热电阻供电,配合外部精密参考电阻就能完成比率测量。这个架构不光省元件,还顺手把参考电压源的漂移误差消除了,后面我会详细展开。

2.2 STM32L073RZ 的定位:不只是省电

STM32L073RZ 在 L0 系列里属于全能型选手。它继承了超低功耗平台的优点,但外设配置又很充裕。我在项目里同时用了 USART2 连 ADC、LPUART1 做对外通信,还留了 I2C 接口给液晶屏和温湿度传感器,GPIO 也够用。

这颗芯片带有真正的 EEPROM,校准参数可以直接存在片上,不用外挂 AT24Cxx。这个细节在量产和现场校准时省事不少,每台设备的增益校准值、零点偏移值、传感器类型配置都能独立保存,换主控板也能立刻恢复参数。

从抗干扰角度看,Cortex-M0+ 的内核虽然简单,但跑 Modbus RTU 协议栈、处理 PID 温控逻辑完全够用。工业现场最怕主控处理不过来导致丢数据,STM32L073 在 32 MHz 主频下搭配 DMA,基本不会出现这类瓶颈。

2.3 这套组合的应用范围

用这套硬件,我做过三种类型的温度采集前端:

一是 PT100/PT1000 热电阻测量,主要用于冷冻水管、锅炉水路、电机绕组这类对精度和长期稳定性要求高的场景。二是热电偶测量,配合内部烧毁检测和外部冷端补偿,用于压缩机排气管、高温风道等地方。三是 NTC 热敏电阻测量,用于风管内部环境温度、回风温度这类精度要求一般但响应速度要快的点位。

一颗 ADC 芯片,几种传感器类型通吃,这在实际项目中降低了不少备货和设计压力。而且 ADS122U04 有四个模拟输入通道,可以自己切换测量不同点位,扩展性也够。

3. 硬件连接与 PCB 布线的关键细节

3.1 电源是测量的命脉

ADS122U04IPWR 的模拟电源 AVDD 建议接 3.3V 或 5V,数字电源 DVDD 可以直接接到 MCU 的 I/O 电压域。我在设计里用了独立的 LDO 给模拟部分供电,没有直接拿数字电源裸奔。

电源纹波对于 24 位 ADC 来说是个隐形杀手。如果直接拿 DC-DC 的输出给 AVDD 供电,开关噪声会通过基准引脚和模拟输入耦合进去,最终表现为测量结果上叠加了几十微伏的随机干扰。我实测过,用一个纹波 30 mV 的 DC-DC 和一个纹波 2 mV 的 LDO 分别供电,同样的传感器,最终温度读数波动能差 0.15℃ 左右。

所以我的做法是:5V 输入先过一级 LDO(比如 TPS7A4901 这类低噪声器件)得到 3.3V,再用 π 型滤波(磁珠加电容)分别供给 AVDD 和 DVDD。如果项目对功耗要求苛刻,可以共用一级 LDO,但模拟电源引脚一定要加 10µF 和 0.1µF 并联去耦。

3.2 传感器输入端的连接方式

传感器输入端的精髓在于“参考地和信号地要单点汇聚”。ADS122U04 的模拟输入是差分的,输入引脚 AIN0 和 AIN1 之间测量电压差,这样环境中的共模干扰会被抵消掉相当大一部分。

以 PT100 四线制连接为例,激励电流从 IDAC1 引脚流出,经过 PT100 热电阻后回到 AIN2 这个低侧感应引脚。电压采样线从热电阻两端直接引到 ADC 的 AIN0/AIN1 差分输入端。这种四线制接法彻底消除了导线电阻的影响,因为采样回路里没有电流流过,只有电压信号。

如果是三线制 PT100,在两个采样线上分别各串一个精密电阻或者靠 IDAC 的对称性来抵消线阻。ADS122U04 的低侧电源开关在这里也很好用,测量间歇期把传感器供电切断,节省功耗。但是要注意,烧毁检测功能需要这个开关配合偏置电流才能工作,配置寄存器时别把它关错了。

3.3 参考电压的选择:我为什么用比率测量

做 PT100 的时候,我没有用 ADC 内部的参考电压,而是把外部精密参考电阻(比如 2kΩ、精度 0.1%)接在 REFP0 和 REFN0 引脚上,让激励电流同时流过参考电阻和 PT100。

这样 ADC 输出码值的计算公式里,激励电流的大小会直接约掉,只剩参考电阻和 PT100 电阻的比值。只要参考电阻的温漂控制好,激励电流哪怕从 1mA 漂到 1.01mA,对最终电阻计算的影响也微乎其微。这就是比率测量的妙处。

3.4 UART 接口的接线

ADS122U04 的 UART 接口只有四个关键引脚:RST、DRDY、TXD、RXD。按照完整 UART 连接,ST 的 TX 接 ADS 的 RXD,ST 的 RX 接 ADS 的 TXD,这是标准交叉。

DRDY 引脚要接在 MCU 的一个外部中断输入上。每次 ADC 转换完成后,DRDY 拉低,MCU 触发中断,然后在中断里或者主循环里发命令读数据。这样比轮询方式稳健,主控有更多时间处理其他任务,也不会因为查询时序不准漏掉转换完成标志。

PCB 布线的时候记得给模拟输入引脚和参考引脚留出足够的间距,传感器线缆过来之后不要和数字信号线平行走线。我对这块板子做了四层设计,给模拟部分专门划了隔离区,数字信号线走内层,传感器接口安排在板边,实测下来 EMC 效果比之前的双面板提升明显。

4. 固件实现:从初始化到温度换算

4.1 STM32 的 UART 外设初始化

我用的开发环境是 STM32CubeIDE,用 HAL 库跑,USART2 作为和 ADC 的通信接口。初始化只要设定波特率、字长、停止位和奇偶校验。ADS122U04 默认支持的波特率可以从 9600 到 262k 之间选,我实际用了 115200,兼顾速度和稳定性。

代码大致长这样:

void ADS_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; HAL_UART_Init(&huart2); }

特别注意,ADS122U04 的默认帧格式里可能包含 CRC 校验位。如果你在寄存器配置里enable了 CRC,那 UART 的每个数据帧要多算一个校验字节,主控这边要用相同的 CRC 多项式做校验。我的经验是,调试阶段先关闭 CRC,把通信调通再打开,免得把协议问题和硬件问题混在一起分不清。

4.2 ADS122U04 的复位与寄存器配置

上电后第一步要复位 ADC。通过 RST 引脚拉低至少 17 个 UART 时钟周期再拉高,也可以在 UART 发送端口连续发几十个 0x00 字节,让 ADC 内部的异步接口重新同步。

复位完成后,把初始化配置写入寄存器。ADS122U04 有五个配置寄存器,核心配置集中在寄存器 0 到寄存器 4:

寄存器 0 配置输入多路复用器,选择哪一个输入端接差分测量,比如 AIN0/AIN1 测 PT100,AIN2/AIN3 测热电偶。寄存器 1 配置 PGA 增益,PT100 用增益 16 或 32 比较合适,热电偶则要用 128 倍增益把微弱信号放大。寄存器 2 配置数据速率和转换模式,这个要根据系统对实时性的要求来选择,数据速率越快噪声越大,后面细说。寄存器 3 配置激励电流源的大小和输出引脚,PT100 用 1mA,PT1000 可以降到 0.25mA,减少自热误差。寄存器 4 配置内部温度传感器、低侧开关和 CRC 选项。

写入寄存器的时候,按芯片手册发送写命令帧:命令字节 + 寄存器起始地址 + 数据长度 + 数据。比如我要把寄存器 0 设为 0x32、寄存器 1 设为 0x00、寄存器 2 设为 0x70、寄存器 3 设为 0x84、寄存器 4 设为 0x02,就连续发送五组写命令。

4.3 PT100 测温的完整流程

配好寄存器之后,开始转换。先发送启动转换命令,等待 DRDY 引脚拉低,说明转换完成,然后发读数据命令,收到的三个字节就是 24 位转换结果,需要拼装成有符号整数。

int32_t ADS_ReadADC(void) { uint8_t data[4] = {0x01, 0x40, 0x00, 0x00}; uint8_t buf[3]; int32_t raw; // 发送读数据命令 HAL_UART_Transmit(&huart2, data, 4, 100); // 等待 DRDY 拉低 while (HAL_GPIO_ReadPin(DRDY_GPIO_Port, DRDY_Pin)); // 接收 3 字节数据 HAL_UART_Receive(&huart2, buf, 3, 100); raw = ((int32_t)buf[0] << 16) | ((int32_t)buf[1] << 8) | buf[2]; // 24 位有符号数扩展 if (raw & 0x800000) raw |= 0xFF000000; return raw; }

拿到原始码值后,先算电阻值。因为用了比率测量,公式是:

R_Sensor = R_Ref x Raw / (2^24 x Gain)

我这里 Gain 就是寄存器 1 里配的 PGA 增益倍数,不是分贝。算出来 RTD 电阻,再用 Callendar-Van Dusen 公式换算为温度。对于 PT100,在 0℃ 以上区域可以写成:

R(T) = R0 (1 + AT + BT^2)

其中 R0 = 100Ω,A = 3.9083e-3,B = -5.775e-7。解这个二次方程就能得到温度。0℃ 以下还需要加一个 C 系数项。

如果嫌公式麻烦,很多项目直接用查表法,把 -50℃ 到 150℃ 范围内每 0.1℃ 对应的 PT100 电阻值做一张表,然后用线性插值查。代码简单,执行速度快,MCU 的 Flash 也装得下。

4.4 热电偶测量和冷端补偿

ADS122U04 做热电偶测量时,信号源内阻小、输出电压也很小,所以要开最大的 PGA 增益,同时把输入多路复用器切到热电偶接入的通道。

热电偶测温必须要做冷端补偿。我的做法是在接线端子旁边放置一颗高精度 NTC 热敏电阻,同时在端子位置测一次温度,拿到冷端温度 T_cold。热电偶的热端温度计算公式是:

T_hot = T_cold + (V_measured + 冷端等效电压) / 热电偶灵敏度

更标准的做法是用线性化的多项式先计算出冷端热电偶产生的电压,加上实测电压,再反查温度。ADS122U04 内置了芯片温度传感器,可以用来粗测环境温度,但它感知的是芯片自身温度,和端子处温度有温差,做 CJC 我个人不建议依赖它。

热电偶还有一个常见坑:断线检测。如果热电偶或者延长线中间断了,ADC 输入端会悬空,读数变成随机漂移或者直接飘到满量程。ADS122U04 支持烧毁检测,内部有上拉/下拉电流源,拔掉传感器后能稳定输出一个满量程或者零刻度信号,主控就能靠阈值判断“传感器异常”。

4.5 低功耗采集模式

如果是电池供电的 HVAC 温控节点,可以让 STM32L073 进 STOP 模式,用 LPUART 或者 RTC 定时唤醒。

我实测的功耗数据是:ADS122U04 和传感器处于不测量状态时,系统整机待机电流约 2.5µA;每 10 秒钟唤醒一次,完成一次采样和 Modbus 数据上传,平均电流约 40µA。两节 AA 电池供电,理论续航远超一年。做法就是在测量周期开始时唤醒,然后给 ADC 上电、配寄存器、触发转换,读完数据、上传完,再切回 STOP。

低功耗模式下有几个细节要处理:传感器供电的 IDAC 电流在测量空闲期要关掉,ADC 的低侧电源开关也要断开;唤醒后先等电源稳定再启动转换,我一般延时 5ms 到 10ms;如果使用内部参考,也要等参考电压建立稳定,否则前几次读数的误差会很大。

5. 校准、滤波与精度分析

5.1 校准流程的实操步骤

24 位 ADC 是精度高,但并不代表它不需要校准。芯片本身存在零点失调和增益误差,电路板的漏电流和寄生热电势也会引入偏差。实际项目中我用零点校准和两点校准两步搞定。

零点校准:把 PT100 换成一个精密 100Ω 电阻,或者放入冰水混合物中,测一组原始码值,算出偏移量存到 EEPROM。测量时把这个偏移量从原始值中减掉。

两点校准:在 0℃ 和 100℃ 使用标准温度源,分别记录计算电阻值和实际值的偏差,求出一个增益修正系数。修正公式就是:

R_corrected = (Raw - Offset) x K

K = 标准电阻增量 / 实测电阻增量

工业现场没有恒温槽的话,可以用高精度电阻箱替代,把电阻箱分别设定到 100Ω 和 138.5Ω,模拟 0℃ 和 100℃ 的 PT100 输出,也能达到同样效果。

5.2 数字滤波策略

数据速率和噪声是一对矛盾。ADS122U04 在 20 SPS 的低数据速率下,双电阻噪声的有效值可以压得很低,但系统响应变慢。在 1000 SPS 下响应快了,噪声却会明显增大。

我的做法是根据不同应用场景来取舍。测量风管温度这种变化缓慢的变量,用 20 SPS 加滑动平均滤波,每 10 个点取一次平均,温度读数的峰峰值波动能控制在 0.02℃ 以内。测量压缩机排气管温度这类快速变化的点位,用 175 SPS,加一个一阶低通滤波,兼顾响应速度和稳定性。

在 STM32 上做一阶低通滤波很简单:

float filtered = 0.0f; #define ALPHA 0.1f filtered = ALPHA * new_sample + (1.0f - ALPHA) * filtered;

ALPHA 取 0.1 时,滤波时间常数大约在 1/0.1 = 10 个采样周期左右,具体效果需要现场调。

5.3 系统级误差来源分析

把整个链路的误差拆开看,第一项是 ADC 本身的噪声,通过低速率和滤波基本可以压掉。第二项是电阻匹配和温漂,外部参考电阻选了低温漂 0.1% 精度的金属箔电阻,温漂系数 10ppm 左右。第三项是传感器自热,PT100 用 1mA 激励时,100Ω 电阻上功耗只有 0.1mW,影响微乎其微;但是 PT1000 用 1mA 激励时功耗有 1mW,能引起 0.05℃ 到 0.2℃ 的附加误差,如果放在气流中,散热好影响小,放在密闭管道液体里,影响会被放大。所以我的经验是高阻值 RTD 尽量把 IDAC 配到 0.25mA,牺牲一点信噪比换稳定性。

第四项是连接线缆和端子的热电势。铜和接头之间的热电效应虽然很小,但测量温差大于 0.01℃ 时仍然能观察到。为了消除它,ADC 的采样速率和架构决定了我们没法完全规避,但可以尽量让两个输入端子的温度一致,端子排布紧凑,避免一侧靠近热源。

6. 常见问题与调试经验记录

这一节直接把我调试中遇到过的坑列出来,每一项都是真实踩过的。

  • 读数漂移,误差忽大忽小。检查电源纹波和传感器线缆屏蔽层是否接地。我遇到过屏蔽层单端接地没接好,结果整个模拟输入悬空,示波器上看到 50Hz 工频干扰峰峰值 200mV,后来把屏蔽层良好接机壳后,读数瞬间稳定。
  • UART 通信偶尔乱码。ADS122U04 对 UART 时序要求没有 SPI 那样苛刻,但波特率偏差不要超过 ±2%。检查 MCU 的时钟源,如果用了内部 HSI,误差可能到 1% 以上,我建议直接把 SYSCLK 锁到外部晶振上。
  • 热电偶测量读数明显偏低。多半是冷端补偿环节出了问题,冷端温度测的是 ADC 芯片温度而不是端子温度。在端子旁边贴一颗完整的 NTC 或者用集成数字温度传感器,重新做 CJC,问题立刻消失。
  • 传感器一拔掉就出现满量程读数,重新插上后要很久才恢复。这说明烧毁检测电流源一直在用,而且偏置方向反了。把烧毁检测电流方向或者大小重新配置,让传感器插回后能快速回到正常测量域。
  • ADC 读数整体偏小,而且和线缆长度强相关。多数原因是误用了两线制接法,导线电阻分压了激励电压。换成三线或四线制,问题解决。
  • 低功耗节点的电池续航远低于预期。检查是不是没有关闭 IDAC 和低侧开关,测量准备阶段功耗被拉高。我最初就是忘了切低侧电源开关,待机电流从 2.5µA 涨到了 1.2mA,续航缩水到原来的零头。

除了上面这些问题,再说一个容易被忽略的点:ADS122U04 的 UART 帧格式里,命令字节和寄存器地址的组合必须和数据手册完全一致,模棱两可就会导致读写错位。我建议调试时先用简单命令读取寄存器值,回读确认无误后再去操作 ADC 转换,别跳过协议验证直接上数据链路。

7. 最后的实操体会和个人建议

整套方案做下来,我的体会是,ADS122U04IPWR 和 STM32L073RZ 的组合,最适合那种需要兼顾精度、低功耗和布站灵活性的分散式测温系统。硬件上省掉了外部模拟前端和恒流源,软件上只要把 UART 协议跑顺,再填好寄存器配置,剩下的温度检测就能顺手做得很准。

如果你也是第一次用这颗 ADC,我建议先拿面包板搭一套最小系统。第一周别追求完美精度,先把读码和写寄存器这两个基础动作跑通。第二周再接传感器,把电阻计算和温度公式调通。第三周再上滤波和补偿算法。这样分阶段推进,出问题的时候定位会快得多。

另外,板子画好后,量产前最好做一轮老化测试。我曾经有一版样机,刚上电精度很好,跑了 48 小时之后,PT100 读数漂了 0.3℃,排查下来是 PCB 板材的湿气吸收导致漏电流变化。后续在裸板表面对模拟区域做三防漆涂覆,漂移问题就没有再出现。

最后分享一个小技巧:把校准参数和传感器配置全部存到 STM32L073 的片上 EEPROM,然后通过 UART 或者 Modbus 指令在线修改。这样现场换传感器,不需要重新烧录程序,直接命令行校准,后期维护省掉大量工时。

这个项目后续我准备把两个测量通道分别接 PT100 和热电偶,用同一个 MCU 同时管理,再把 Modbus RTU 从站协议加上,让楼宇自控系统直接读取温度值。如果你也正在做类似的工作,欢迎按这个方案试一下,有问题随时对照这篇文章里的寄存器配置和调试思路排查。

返回列表