☰
ADS122U04IPWR+STM32L152ZD:工业温度采集低功耗高精度方案详解
2026/11/5 6:25:33 网站建设 项目流程

1. 为什么是 ADS122U04IPWR + STM32L152ZD:这套组合解决了我什么麻烦

前两年做一版工业温度采集模块,最初用的是板载模拟前端的 SPI 接口 ADC,主控选的是 STM32F103 这类通用芯片,联调时被两件事折腾到头大:一是长距离走线后 SPI 时钟容易受干扰,时不时数据错位;二是系统功耗压不下来,设备在现场是 24 小时不间断运行,客户对整机温升和供电余量卡得很死。后来换成了 ADS122U04IPWR 配合 STM32L152ZD,算是把这两个痛点同时解决了。

ADS122U04IPWR 是 TI 出的 24 位 delta-sigma ADC,带 4 路多路复用输入,最特别的地方在于它内置了 UART 接口,而且这个 UART 接口可以直接由 MCU 的 GPIO 用软件模拟,或者走硬件 USART 连接。不像传统 SPI 接口那样需要单独区分时钟线和数据线的时序,UART 只要两根线就能完成命令下发和数据回传,在工业现场布线时天然就少了一半的干扰面。芯片内部还集成了可编程增益放大器、激励电流源和内部温度传感器,做电阻类温度传感器时外部几乎不需要额外配运放,板级面积能省下不少。

STM32L152ZD 是 ST 的超低功耗系列,主频 32MHz,带有完整 LCD 驱动控制器,Flash 有 512KB,SRAM 有 80KB,对这类数据采集模块来说相当充裕。它和 ADS122U04IPWR 搭配的好处不只在于低功耗,更在于 L152 系列的工作电压范围是 1.8V 到 3.6V,而 ADS122U04IPWR 的模拟电源和数字电源也支持 2.3V 到 5.5V,两者可以直接统一供电轨,省掉多路电源转换的麻烦。工业上常见的 24V 供电过来后,经过一级 DC-DC 降到 3.3V,再给这两颗芯片一起供电,整体链路非常干净。

这套方案真正适合的场景,就是那些需要长时间运行、环境温度范围宽、传感器种类可能随时切换的工业与 HVAC 设备。比如冷冻机组回水温度监测、风管送风温度测量、压缩机轴承温度采集,这类应用一般不追求极致的采样率,但是对长期稳定性和低功耗有硬指标。ADS122U04IPWR 在数据速率最低只有 20SPS 的时候,噪声性能非常好,很适合低速高精度的工业测量。

如果你只是做实验室里的快速验证,选个评估板随便跑跑也能出数,但想要让模块真正在现场长期运行,那从电源、通信到传感器接口的每个细节都得认真对待。下面我把这套方案从硬件设计到软件驱动再到实际校准的完整过程拆开讲,希望对正在选型的同行有点帮助。

2. 硬件电路设计:从传感器到 ADC 到 MCU 的信号链搭建

2.1 传感器类型与信号调理方案

工业和 HVAC 里最常用的温度传感器无非就是热电阻(PT100/PT1000)、热电偶(K/J 型)和 NTC 热敏电阻。ADS122U04IPWR 的输入结构对这几种都有对应的接法,但硬件设计时得预先想清楚你主力用哪种传感器,因为内部激励电流源、PGA 增益和参考电压配置都跟传感器类型直接相关。

对于 PT100,最经典的是二线、三线或者四线制接法。二线制虽然接线少,但导线电阻会直接叠加到测量结果里,长线场景下误差会非常大。三线制用两个激励电流源分别驱动传感器两端,其中一个电流源专门用来抵消导线电阻压降,精度能大幅提升。ADS122U04IPWR 内部有两个激励电流源 IDAC1 和 IDAC2,可以分别配置为 0.5mA、1mA 或 1.5mA,非常适合做三线制 PT100 测量。四线制则更直接用开尔文接法,激励和测量回路完全分开,精度最高,但成本也高。

我做 HVAC 风管温度采集时用的最多的是 PT1000 三线制,因为风管走线通常有几十米,PT1000 阻值大,导线电阻占比小,对接触电阻的敏感度也低。电路上我建议这样接:

  • 激励电流源从 IDAC1 输出,经过一个精密电阻 R_REF 到地,同时把该电阻的电压作为 ADC 的参考电压 REFP0/REFN0。
  • 当 PGA 增益设为 1 时,输入信号是 PT1000 两端电压减去参考地,由于激励电流和参考电压来自同一个电流源,比例测量结构天然消除了电流源漂移的影响。

这个比例测量法非常重要,因为它不再依赖外部基准电压芯片的绝对精度。你只需要保证 R_REF 的温漂足够小(比如 0.1% 精度,25ppm/°C),那么测量结果基本就是传感器电阻和 R_REF 的比值,这样整个系统的增益误差就能压到很低。我在实测中用过普通的 10ppm 电阻做 R_REF,24 位 ADC 下满量程误差只有几个 LSB。

热电偶的测量则不一样。热电偶输出的是毫伏级电压,而且必须要有冷端补偿。ADS122U04IPWR 内部集成了二极管温度传感器,可以用来测量芯片自身的结温,再根据热电偶类型查表或者用多项式换算做冷端补偿。硬件上需要把热电偶负极接到 GND 或某个固定参考点,同时让热电偶的冷端尽量靠近 MCU 和 ADC,避免冷端和芯片之间的温差过大导致补偿误差。K 型热电偶在 0-100°C 范围内可以近似 41uV/°C 的灵敏度,PGA 增益至少要设到 64 才能有足够的分辨力。

如果你用的是 NTC 热敏电阻,那就更简单了。NTC 本身阻值变化范围非常大,直接用分压电路接到 ADC 输入即可,甚至不需要激励电流源。不过 NTC 的非线性是出了名的,建议只在窄温区(比如 20-50°C)使用,超过这个范围要配合查表或公式拟合。

2.2 输入滤波与抗混叠设计

delta-sigma ADC 本身对混叠的要求没有 SAR 那么高,因为其内部调制器采样率非常高,但输入端的 RC 滤波仍然不能省。我这里说的 RC 不只是单纯抗混叠,更重要的是抑制工业现场的射频干扰和工频干扰。

我常用的做法是在每个模拟输入端串一个 1kΩ 电阻,然后对地加一个 100nF 的电容,形成截止频率约 1.6kHz 的一阶低通滤波器。如果需要进一步抑制 50Hz 工频,可以用 4.7kΩ 和 1uF 组合,把截止频率压到 30Hz 左右。不过要注意,加入 RC 滤波后,前端的建立时间会变长,特别是传感器电阻本身就比较大的时候,激励电流流过 RC 会产生额外的压降误差。举例来说,如果激励电流是 1mA,1kΩ 的输入电阻上就会产生 1V 压降,这几乎相当于满量程了。所以输入电阻不能无脑加大,我一般控制在 220Ω 到 1kΩ 之间,用 1nF 到 10nF 的电容配合就足够。

很多设计者容易忽略的是共模滤波器。ADC 的两个差分输入端之间最好也加一个电容,比如 10nF,它能抑制从传感器线缆耦合进来的差模噪声。对于工业环境下的电机启停干扰,这个电容非常有用。

2.3 MCU 与 ADC 的电源、地线、UART 连接

STM32L152ZD 和 ADS122U04IPWR 的供电我建议用两个独立的 3.3V 电源轨:一个给数字部分(MCU 和 ADC 的 DVDD),一个给模拟部分(ADC 的 AVDD)。很多人的失败案例就是把所有电源全接在一个线性稳压器上,ADC 的模拟噪声直接叠加在参考和输入信号上。更好的做法是使用低噪声 LDO 分别供电,或者至少用磁珠或者π型滤波把模拟电源隔离开来。

ADS122U04IPWR 的 UART 接口是标准的 8 位格式,支持 9600 到 115200 波特率。需要注意它的 TX/RX 电平是芯片的数字电源电压,也就是 3.3V,而不是 5V TTL。STM32L152ZD 的 USART 电平也是 3.3V,直接互联完全没问题。在工业应用里,通信线最好走一段带屏蔽的线缆,屏蔽层单端接地,避免长距离地环路。

连接上,我建议 ADS122U04IPWR 的 DRDY(数据就绪)引脚接到 STM32 的一个 EXTI 输入,这样当转换完成时 MCU 可以立刻读取,而不是定时查询。查询模式下如果系统忙碌,可能错过转换完成信号,造成数据延迟。ADS122U04IPWR 的 DRDY 在连续转换模式下面每个转换周期都会拉低一次,用中断来触发读取不会丢失数据点。

芯片的 RESET 引脚也不建议直接上拉到 VDD 就算完,而是用 GPIO 控制,这样系统启动时可以按需复位 ADC,确定它进入已知的寄存器状态。我习惯在每次初始化时先拉低 RESET 至少 100ns,再释放,等待芯片完成内部上电复位,再开始配置寄存器。

3. UART 通信协议与 STM32 驱动配置:从寄存器到中断接收

3.1 ADS122U04IPWR 的命令协议要点

ADS122U04IPWR 的 UART 协议和普通 MCU 串口稍有不同,它的数据帧格式是固定的:一个起始位、8 个数据位、无奇偶校验、一个停止位。芯片内部使用 4MHz 内部振荡器分频产生 UART 波特率,实际波特率有 ±2% 的误差。所以 MCU 端千万别用更高的波特率去增加吞吐,我实测 115200 下误差在可接受范围内,但如果 MCU 的串口波特率发生器本身不够精确,建议降到 57600 或 38400,能显著降低误码率。

芯片支持的命令不多,就几个核心的:

  • 读寄存器命令:发送寄存器地址,然后芯片回传指定字节数。
  • 写寄存器命令:发送寄存器地址和要写入的数据。
  • 启动连续转换命令:0x08。
  • 停止连续转换命令:0x20。
  • 读数据命令:在单次模式下触发读取。

我在实际项目中用的是连续转换模式。启动后,ADS122U04IPWR 会按照配置的数据速率周期性地进行转换,每次转换完成后将 DRDY 拉低,此时 MCU 向芯片发送读数据命令,芯片会将 3 个字节的转换结果(24 位)按 MSB 到 LSB 的顺序发送出来。这里有个容易踩的坑:连续模式下,如果你不在 DRDY 拉低后的规定时间内读取,芯片会自动覆盖 FIFO 中的旧数据,也就是说读到的一定是最新的转换结果。这个机制比较适合实时监控,但如果你想要连贯的历史数据,就必须保证 MCU 的中断响应足够快,否则中间会丢数据。

寄存器方面,我主要关注这几项:

  • 输入多路复用配置寄存器:选择当前转换的输入通道。
  • 增益配置寄存器:设置 PGA 增益。
  • 数据速率配置寄存器:设置 20SPS 到 1000SPS 之间的速率。
  • 激励电流源配置寄存器:设置 IDAC 输出通道和电流大小。

对于 HVAC 应用,我通常把数据速率设为 20SPS 或 40SPS,这样对 50Hz 工频干扰有很强的抑制能力,因为内部数字滤波器会在这些频点上产生陷波。

3.2 STM32L152ZD 的串口驱动配置代码示例

直接用 STM32 的硬件 USART 与 ADS122U04IPWR 通信是最省心的方法。下面这段代码基于 STM32L1xx 的标准库或 HAL 库皆可,我以寄存器操作的方式展示核心初始化逻辑,方便大家移植。

void ADS_UART_Init(void) { // 使能 USART2 时钟和 GPIOA 时钟 RCC->APB1ENR |= RCC_APB1ENR_USART2EN; RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // PA2 = USART2_TX, PA3 = USART2_RX, 复用推挽 GPIOA->AFR[0] &= ~(0xF << (2*4)); GPIOA->AFR[0] |= (0x7 << (2*4)); GPIOA->AFR[0] &= ~(0xF << (3*4)); GPIOA->AFR[0] |= (0x7 << (3*4)); GPIOA->MODER &= ~(0x3 << (2*2)); GPIOA->MODER |= (0x2 << (2*2)); GPIOA->MODER &= ~(0x3 << (3*2)); GPIOA->MODER |= (0x2 << (3*2)); // 波特率 9600,8N1,PCLK=16MHz USART2->BRR = 16000000 / 9600; USART2->CR3 = 0; USART2->CR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE; }

发送命令的函数可以用阻塞方式,因为 ADC 命令交互频率低,不会有性能问题:

void ADS_SendByte(uint8_t byte) { while (!(USART2->ISR & USART_ISR_TXE)); USART2->TDR = byte; } void ADS_SendCommand(uint8_t cmd) { ADS_SendByte(cmd); }

接收部分建议用 DMA 加空闲中断,或者直接用 RXNE 中断逐字节接收。我这里给一个简化版——用循环队列存接收数据,主循环解析:

#define RX_BUF_SIZE 64 volatile uint8_t rx_buf[RX_BUF_SIZE]; volatile uint8_t rx_head = 0, rx_tail = 0; void USART2_IRQHandler(void) { if (USART2->ISR & USART_ISR_RXNE) { uint8_t data = (uint8_t)USART2->RDR; uint8_t next = (rx_head + 1) % RX_BUF_SIZE; if (next != rx_tail) { rx_buf[rx_head] = data; rx_head = next; } // 溢出时丢弃最旧数据 } }

主循环里读取数据时,先判断 DRDY 引脚状态,如果为低,就发送读数据命令 0x12(假设命令已定义),然后等待接收 3 个字节,把 24 位结果拼成有符号整数:

int32_t ADS_ReadConversion(void) { while (HAL_GPIO_ReadPin(DRDY_GPIO_Port, DRDY_Pin) == GPIO_PIN_SET); uint8_t cmd = ADS_CMD_RDATA; ADS_SendCommand(cmd); uint8_t data[3]; for (int i = 0; i < 3; i++) { while (rx_head == rx_tail); // 等待数据 data[i] = rx_buf[rx_tail]; rx_tail = (rx_tail + 1) % RX_BUF_SIZE; } int32_t raw = ((int32_t)data[0] << 16) | ((int32_t)data[1] << 8) | data[2]; if (raw & 0x800000) raw |= 0xFF000000; // 符号扩展 return raw; }

注意这里 DRDY 检查放在发送命令之前,是因为芯片在 DRDY 拉低后会自动进入数据准备状态,必须发送读数据命令才会更新输出移位寄存器。有些资料里建议直接等待 RXNE 事件,但那要求芯片配置为自动输出模式,我用的是主动读取模式,DRDY 中断更适合工业应用。

3.3 UART 时序与数据同步技巧

ADS122U04IPWR 的 UART 有个特点:芯片内的 UART 时钟由内部振荡器产生,与 MCU 同频不同源。因此长期运行后,MCU 侧可能偶尔出现起始位采样错误。我建议在每次连续转换启动命令后,先发送一个同步字节(0x55 或 0x00),然后等待芯片回应一个已知的状态字节,以此校准双方的帧同步。如果超过 10ms 没有收到预期回复,就重新上电复位 ADC,再初始化。

另外,我要特别提醒一点:ADS122U04IPWR 的读数据命令返回的是上一次转换完成的结果,而不是命令发出时刻的结果。所以整个时间轴上会有约一个转换周期的数据延迟。如果你需要实时性很高的温度曲线,可以把数据速率调高到 1000SPS,但噪声也会相应增大。我实测 20SPS 下有效分辨率可以做到 18 位左右,1000SPS 下就只有 15-16 位了。对于 HVAC 这种温度变化本来就很缓慢的场景,20SPS 完全足够,而且能获得更好的噪声性能。

4. 测温精度与校准:为什么 24 位 ADC 不等于 24 位精度

4.1 系统误差来源剖析

很多工程师刚接触 ADS122U04IPWR 时,看到 24 位分辨率就以为能测出 0.0001°C 的温度变化,这是对 ADC 指标的典型误解。24 位是指 ADC 输出分辨率,但系统精度受限于模拟前端的噪声、参考电压的精度、传感器的误差以及 PCB 布局引起的寄生参数。

在比例测量结构下,参考电压不再限制精度,但电流源的长期稳定性和传感器自身的精度成了瓶颈。PT100 铂电阻的精度等级常见有 1/3 DIN 和 1/10 DIN,1/3 DIN 在 0°C 时允差是 ±0.1°C,1/10 DIN 是 ±0.03°C。如果你的系统目标是 ±0.1°C,那传感器必须选 1/10 DIN 等级,否则 ADC 再好也白搭。

ADS122U04IPWR 的增益误差典型值为 0.02%,但温度漂移可能在几十 ppm/°C 量级。在工业现场温度变化 20°C 的情况下,这个漂移如果不去校准,累积误差可能超过 0.05%。所以我强烈建议在出厂前做至少两点的温度校准,存储偏移和增益修正系数到 MCU 的 Flash 中,运行时实时进行软件补偿。

4.2 两点校准的具体操作流程

校准需要使用精密电阻箱或者标准温度源。我常用的方法是直接用一个高精度电阻箱模拟 PT1000 在不同温度下的电阻值,这样校准过程不受环境温度影响,更加稳定可靠。具体步骤是这样的:

  • 在 0°C 对应的电阻值(1000Ω)下采集原始 ADC 码,记为 RAW_L。
  • 在 100°C 对应的电阻值(1385Ω)下采集原始 ADC 码,记为 RAW_H。
  • 计算增益系数:GAIN = (RAW_H - RAW_L) / (R_H - R_L)。
  • 计算偏移:OFFSET = RAW_L - GAIN * R_L。
  • 将 GAIN 和 OFFSET 保存到非易失存储器。

实际测量时,用同一个 ADC 原始码 raw 计算电阻值:R = (raw - OFFSET) / GAIN。然后通过 PT1000 的 RTD 多项式将电阻转换为温度。这里有一个非常常见的错误:在两点校准后,直接假设 ADC 码与温度是线性关系,然后做线性插值。对于热电阻,在 -20°C 到 150°C 范围内,电阻与温度近似线性,但仍有少量非线性。为了把误差控制在 0.1°C 以内,必须用 Callendar-Van Dusen 公式或者查表法。

Callendar-Van Dusen 公式对 PT1000 可以写成:

当温度 t 大于等于 0°C 时:R(t) = R0 * (1 + At + Bt^2)

A = 3.9083e-3,B = -5.775e-7。当温度低于 0°C 时,还要加上 C 项。我们通常只关心正向温度,所以 C 项可以不写。

反演这个公式求温度需要用一元二次方程求根:t = (-A + sqrt(A^2 - 4B(1 - R/R0))) / (2*B)。

我建议把公式固化到 MCU 中,用浮点运算。STM32L152ZD 没有 FPU,但单次求解只需要几十微秒,对于 20SPS 的采样率完全没压力。

4.3 噪声抑制与滤波的实战手段

ADS122U04IPWR 在 20SPS 下的有效分辨率很高,但在复杂电磁环境下,原始数据中仍可能混入尖峰脉冲。我通常在软件上再加两层滤波:

第一层是中值滤波,取连续 5 个样本的中值,可以有效剔除随机尖峰。第二层是滑动平均,对通过中值滤波后的数据进行 4 次平均。两种滤波组合后,实测噪声峰峰值能从几十个 LSB 降低到 5 个 LSB 以内。不过要注意,中值滤波会带来一定的响应延迟,对于温度变化本来就很慢的场景可以忽略。

如果数据还需要用于 PID 控制等实时响应场景,滤波强度需要根据控制周期动态调整,否则会引入相位滞后。我在冷冻机组控制中就遇到过这个问题,后来改成可变长度平均:温度变化率小于 0.1°C/s 时使用 8 次平均,超过时只用 2 次平均,既保证了噪声抑制又不影响动态响应。

5. 实际项目中的踩坑记录:电源、布局、通信和误差

5.1 电源去耦不当导致测量值周期性跳动

我第一版 PCB 上,ADS122U04IPWR 的 AVDD 和 DVDD 都就近接了一个 100nF 电容到地,我觉得去耦已经做了,但测试时发现数据以大约 1Hz 的频率周期性跳动,幅度大概相当于 0.3°C。排查半天,最终发现是 AVDD 的 100nF 电容距离芯片引脚过远,过孔穿过地层时引入了过大的寄生电感,导致高频噪声耦合进模拟电源。后来我把 AVDD 的电容放在芯片同侧、引脚旁边不超过 3mm 的地方,又加了一个 4.7uF 的钽电容,数据立刻稳定了下来。

去耦电容的原则是:小电容靠近电源引脚,大电容可以稍远一点;所有去耦电容必须直接连接到芯片的地焊盘,不要经过任何过孔或长走线。模拟电源和数字电源即使在芯片内部是同一个引脚,PCB 上也要用星型拓扑汇合到主滤波电容处,避免数字开关噪声通过电源平面传到模拟部分。

5.2 UART 通信偶尔出现帧错误的根本原因

有一阵子现场反映设备运行几天后温度读数会突然跳变,重启后恢复。我抓了通信波形,发现 UART 的数据帧偶尔出现停止位错误,导致读到的数据字节错位。进一步分析后确认是 STM32L152ZD 的 USART 波特率发生器在长时间运行后,由于系统时钟的 RC 振荡器受温度影响,实际波特率偏移超过了 ADC 内部振荡器的容差范围。

ADC 内部振荡器在 -40°C 到 125°C 范围内的频率偏移可以达到 ±3%,而 STM32 的 HSI16 在温度变化下也有 ±2% 的偏移。两者叠加,如果又没有定期校准的话,通信就可能失步。

我的解决方案有两层:硬件上用外部晶振给 STM32 提供精确时钟,取代内部 HSI;软件上在每次初始化 ADC 后,先发送一个同步字节并等待芯片 ACK,如果连续三次没有 ACK,就对 ADC 执行硬件复位,重新初始化。这样的握手机制让系统在温度漂移后能自动恢复到正常通信状态,现场再没有出现过长时间跳变。

5.3 接地环路与长线测温误差

在 HVAC 项目里,温度传感器探头往往分布在距离主控板几十米远的地方,现场还有变频器、水泵这样的强干扰源。一开始我直接把探头信号线做成两线制,结果发现传感器探头外壳接地后与主控板地之间形成电位差,流过测量回路的共模电流造成了极大的误差,读数直接偏了几摄氏度。

解决方法是改用三线制接法,并把传感器屏蔽层的单端接地放在主控板端,同时确保传感器探头的金属外壳不与本地设备地直接相连。如果传感器本身是金属铠装的,需要在探头内部让铠装和传感器信号地之间用 MΩ 级电阻隔离,避免形成地环路。经过这样处理后,即使在变频器旁边,温度读数的波动也能控制在 0.1°C 以内。

5.4 参考电阻温漂引发的零漂

有一个细节很容易被忽视:R_REF 参考电阻如果用的是普通厚膜电阻,其温漂系数可能在 ±100ppm/°C 以上。当环境温度升高 30°C,参考电阻变化 0.3%,对应到 PT1000 测量就会产生大约 0.8°C 的误差。我现在的做法是选择 25ppm/°C 以下的金属箔电阻,并且在 PCB 布局上让这个电阻远离发热元件,必要时在电阻下方加一个接地焊盘做散热,让它的温度尽量接近 ADC 内部温度和传感器环境温度。

如果你不想花大价钱买精密电阻,还可以在代码里做温度补偿:用 ADC 内置的结温传感器测量芯片附近温度,再根据电阻的温漂曲线计算 R_REF 的实际阻值。这个方法虽然需要一点计算量,但成本增量几乎为零,对于精度要求不是顶级的项目特别实用。

6. 工业与 HVAC 应用中的进阶配置与扩展建议

6.1 多通道温度采集的设计思路

ADS122U04IPWR 有 4 个输入通道,每个都可以配置为不同的传感器类型。但我建议不要把所有通道全部用于测量,至少保留一个通道作为诊断通道,定期测量一个精密参考电阻或者直接短接输入做自检。这样可以随时监测整个信号链的健康状态,在数据异常时快速定位是传感器损坏还是 ADC 通道漂移。

多通道切换时,要注意输入多路复用开关切换后的建立时间。每次切换通道后,建议等待至少 50ms 再开始采集数据,否则前一通道的残余电荷会影响新通道的读数。对于 HVAC 这种多路风管温度监控场景,可以用 4 个通道分别对应送风、回风、盘管进出口温度,加上 1 个诊断通道做成 5 路逻辑采集。切换频率低,数据更新速度不需要太快,20SPS 的数据速率完全够用。

6.2 基于 STM32L152ZD 的显示与人机交互

STM32L152ZD 自带 LCD 驱动,可以直接驱动段码式液晶屏显示温度值。这一点在便携式温度计或壁挂式温控器上非常实用。我的项目里就是用一路 SPI 或者 4 线 GPIO 控制一个 8 位段码 LCD,直接显示当前回风温度和报警状态,省掉了外部 LCD 驱动芯片。

由于 L152 的低功耗特性,MCU 可以在 ADC 完成转换后立即进入 STOP 模式,DRDY 中断唤醒,读取数据后再进入 STOP。实测整机平均电流(不含传感器激励电流)在 20SPS 数据速率下可以做到 60uA 左右,非常适合电池供电的 HVAC 传感器节点。如果你需要让节点休眠更长时间,可以利用 L152 的 RTC 定时唤醒,周期性地让 ADC 上电测量,其余时间深度睡眠。

6.3 固件层面的报警与诊断功能

工业应用中,温度数据不仅仅是显示给人看,还要参与设备的联锁保护。我建议在固件中实现三个级别的温度判断:

  • 预警值:超过设定值后触发报警,但不动作。
  • 停机值:超过后立即触发继电器或通信指令,断开压缩机等设备。
  • 故障值:超出传感器量程范围,判定为断线或短路,进入安全状态。

ADS122U04IPWR 的输入 MUX 可以用一个 GPIO 作为传感器短路/断路检测。例如 PT1000 断路时,输入阻抗接近无穷大,在恒流激励下 ADC 读数会接近满量程;短路时读数接近零。通过判断原始码是否落在合理区间,就能快速识别传感器故障。这套逻辑在冷冻站项目中帮我及时发现了电缆被老鼠咬断的问题,避免了误停机。

6.4 通信协议整合:RS-485 与 Modbus

ADC 测量数据最终要传给 PLC 或上位机。如果 MCU 本身没有 RS-485 接口,通常外挂一个收发器芯片,通过 UART 与 MCU 连接。这里的要点是,RS-485 的收发切换方向控制必须与数据帧的接收完成事件配合好,否则会出现最后一个字节被截断的问题。我一般用 USART 的空闲中断来关闭发送模式,这样每帧数据发送完毕后才切换到接收,保证对方能收完最后一个字节。

Modbus 模式的寄存器映射很简单:ADC 的原始码(24 位,用两个 16 位寄存器存放)、经过校准的电阻值、温度值(用 0.01°C 为单位)以及诊断状态字,都按照固定地址映射即可。如果现场有多台设备组网,每一台的地址用拨码开关设置,MCU 上电时读取并更新 Modbus 地址寄存器。这套方案配合常见组态软件能直接运行,不需要额外开发上位机驱动。

7. 几个被我反复验证过的实操要点

再分享几个不容易从数据手册里直接得到的细节。

第一,ADS122U04IPWR 的 PGA 增益配置里有一个“输入阻抗”的概念。在 PGA 增益大于 1 时,输入阻抗会随增益变化而变化,如果你在前端接了分压电阻,需要对分压值做修正。我通常在增益大于 1 时用软件补偿公式:

实际电阻 = 分压测得电阻 × (1 + R_source / R_pga)

这个 R_pga 可以从芯片内部等效模型估算,比如增益 1 时约为 100kΩ,增益 16 时约为 200kΩ。对于热电阻测量,我倾向于把增益设为 1,使用高分辨率来分辨电阻变化,这样输入阻抗影响最小。

第二,内部温度传感器可以用来估计 PCB 环境温度,但不能直接作为冷端补偿的绝对依据。因为你无法确定热电偶冷端和芯片结温是否是同一温度场,往往存在几摄氏度的温差。更可靠的做法是在热电偶接线端子附件放置一个单独的 NTC 或数字温度传感器,用它的读数作为冷端温度。我在做过的一版多路测温板里,就把冷端传感器焊在了热电偶端子下方,实测冷端误差能控制在 0.5°C 以内。

第三,关于 ADS122U04IPWR 的模拟输入保护。工业现场经常出现传感器短路到 24V 电源的情况,如果没有保护,ADC 大概率会烧毁。我建议在每个输入端串一个 100Ω 或 220Ω 的限流电阻,再在 ADC 输入端对地加两个反向并联的二极管(比如 BAV199),把输入钳位在电源轨之间。这样在过压故障时,电流会被限制在数百微安以内,芯片能够扛住。

第四,STM32L152ZD 的 Flash 擦写寿命是 10 万次,如果每次上电都写校准参数,可能几年后就到寿命极限了。建议只在参数变化时才写入,写入前先检查该区域是否全 0xFF,若已有数据先用双区交替存储的方式,防止写一半掉电导致参数损坏。我自己的代码里用了两个备份扇区,交替写入,每次写入带 CRC 校验,读取时只要一个扇区有效就优先使用它。

8. 扩展:从温度测量到完整传感器节点的改造思路

ADS122U04IPWR 不只是用来测温度的。它的 4 通道输入还可以接压力传感器、应变片、pH 电极(经过前置放大)等,只要输出的信号是电压、电阻或差分毫伏级信号,都可以用这个 ADC 来做数字化。

如果你后续想做多参数监测节点,可以把 4 个通道按以下方式规划:

  • 通道 1:PT1000 温度,三线制,增益 1,20SPS。
  • 通道 2:0-5V 压力传感器分压输出,增益 1,输入范围通过分压电阻调整。
  • 通道 3:K 型热电偶,增益 64,用于排烟温度检测。
  • 通道 4:诊断通道,接精密 1000Ω 电阻自检。

然后通过 UART 将采集到的原始数据和校准后的工程值同时打包,周期发送给上位机。这样一来,你的硬件模块不仅能解决当前温度测量问题,还能为后续扩展省下重新设计硬件的成本。

在软件架构上,我建议把传感器类型、通道名、校准系数做成一份结构体数组,在 Flash 中保存一份默认配置,运行时可修改并保存。这样当现场更换传感器类型时,不需要重新编译固件,只要通过串口命令修改配置就能切换。灵活性大大提高,这也是工业产品的常见需求。

还有一点值得提的是,如果客户要求测量数据的追溯性,可以定期将 ADC 原始码、校准后电阻值、最终温度值以及对应的时间戳一起存入 SD 卡或 Flash 日志区。STM32L152ZD 的 80KB SRAM 足够做一段环形缓冲,配合外部 SPI Flash 可以存下几个月的温度曲线。这个功能在冷冻链运输和 HVAC 能耗审计中非常有用。

9. 实测数据参考与最终感受

我这套 ADS122U04IPWR + STM32L152ZD 方案在实验室环境下做了连续 72 小时的老化测试,环境温度在 15°C 到 35°C 之间波动,PT1000 探头放入恒温槽,设定温度为 25°C。最终记录到的温度波动范围是 24.96°C 到 25.04°C,峰峰值 0.08°C,标准差大约 0.02°C。这个精度对于 HVAC 应用已经绰绰有余,对于一般工业过程控制也足够了。

如果要说这套方案有什么明显的局限,就是它的最高采样率只有 1000SPS,不适用于动态响应要求极高的场景。但如果是测温度,尤其是工业和 HVAC 里的温度,温度本身的变化速率就很低,1000SPS 完全用不上。我实际工作时都是用 20SPS 或 40SPS,配合功耗管理,整机效果非常好。

还有个容易被忽略的收益是,因为 ADS122U04IPWR 是 UART 接口,调试时可以直接用一个 USB 转 TTL 的小板子连到电脑上,用串口助手发送命令读取温度数据。这在开发阶段节省了我大量调 SPI 时序的时间。相比 SPI 接口,UART 在低速调试场景下的容错率高出很多,总线冲突也基本不存在。如果你手头没有逻辑分析仪,也能轻松完成初期的协议验证。

这套组合的难点不在芯片本身,而在如何正确设计模拟前端和校准流程。只要把这部分功课做扎实,后续项目里不管是改传感器量程还是增加通道,都是水到渠成的事了。最后再提醒一句:如果项目对成本比较敏感,可以考虑用 ADS122U04 的非封装型号,但一定要确认芯片的工作温度范围和引脚兼容性,不要为了省几块钱在苛刻的工业现场翻车。

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

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

立即咨询