1. 为什么选"独立24位ADC + 超低功耗MCU"这种组合
工业与暖通空调(HVAC)场景下的温度测量,看着是个简单需求,真做起来坑一点都不少。风管温度、冷冻水进出水温差、压缩机排气温度、换热器表面温度,这些测点信号幅度小、环境干扰大、还经常需要多通道轮询,而且设备往往处于长期通电运行状态,功耗和稳定性都得认真对待。
我最初对比过三套方案:直接用 STM32L152RE 内部 ADC、用 I2C 数字温度传感器、以及"独立 ADC + MCU"的组合。第一套方案率先被否定——STM32L152RE 内部 ADC 是 12 位分辨率,参考电压取 3.3V 时,一个 LSB 大约是 0.8mV。听起来不算差,但算一笔账就明白了:PT100 在 1mA 激励电流下,温度每变化 1℃ 电阻变化约 0.385Ω,换算成电压变化只有 0.385mV。想在 0.1℃ 分辨率下稳定分辨信号,0.8mV 的量化步长差了一个数量级,根本不够用。第二套方案在精度上可行,但 I2C 温度传感器芯片的测温范围、探头形式、长期稳定性都受限,而且无法直接适配 PT100/热电偶这类工业现场最常用的传感器。
所以最终方案定为ADS122U04IPWR + STM32L152RE:一颗 24 位 Δ-Σ ADC 负责把微伏级传感器信号变成可靠数字量,一颗超低功耗 Cortex-M3 负责运算、校准和系统控制。
ADS122U04IPWR 的几个点非常契合这个场景。首先是 24 位分辨率,结合内部可编程增益放大器(PGA),即便热电偶这种每摄氏度只有几十微伏变化幅度的传感器,也能获得足够的分辨率。其次是接口形式,它走 UART 而非传统的 SPI/I2C,这在工业环境里是很大的优势——UART 抗干扰能力强、线缆可以拉得比较长、协议调试也直观,很大程度上避免了 SPI 在长走线下的时序抖动问题。它还有四路模拟输入通道,可以切换测量多路传感器,这在需要轮询多个测点的 HVAC 控制柜里非常实用。此外,芯片内部集成了激励电流源(IDAC),做 RTD 测量时可以直接用来给 PT100/PT1000 供电,省掉外围恒流源电路。
STM32L152RE 这边,选它的理由主要是低功耗和资源余量。工业 HVAC 设备经常要求 7×24 小时运行,静态功耗和休眠策略都得考虑,L1 系列在低功耗方面做得相当成熟。512KB Flash、80KB RAM 的配置也足够跑温度线性化、PID 控制、协议解析这些逻辑。另外它内部有多路 USART,可以用一路和 ADC 通信,一路做 Modbus RTU 从站输出,调试和生产维护都很方便。
两颗芯片的分工很清晰:ADS122U04 负责"感知",把物理世界的温度信号转换成高置信度的数字码流;STM32L152RE 负责"思考",把码流换算成工程值,处理滤波、报警、通信。这种边界明确的架构,后期无论是单独升级传感器前端还是更换主控,耦合成本都很低。
2. ADS122U04IPWR 的信号链路拆解
2.1 Δ-Σ 架构为什么适合小信号测量
ADS122U04 采用的是 Δ-Σ(Delta-Sigma)调制架构。它的核心思路不是逐次逼近,而是用极高的采样速率对输入信号进行过采样,再通过数字滤波器把带内噪声压低。听起来复杂,实际效果就是:它能把 quantization noise(量化噪声)推到高频段,然后由后级数字滤波器滤除,从而在较低的数据速率下实现很高的有效分辨率。
这块芯片支持的数据速率范围从几 SPS 到上千 SPS 可配。实测下来,做温度测量时我一般把速率设置在 20 SPS 到 100 SPS 之间。20 SPS 时数字滤波器对工频 50Hz 及其谐波有较强的抑制能力,积分时间刚好是 50ms,能天然滤掉一整个工频周期;如果现场有变频器干扰,50Hz 附近的高频噪声会非常明显,这时可以再叠加外部 RC 滤波。
2.2 PGA 与参考电压对测量结果的决定性影响
ADS122U04 内部有一个低噪声 PGA,增益可编程。这个 PGA 的价值在于:它能在信号进入 Δ-Σ 调制器之前先放大,让微小信号的电平远离 ADC 的噪声本底。比如测 K 型热电偶,常温下热电势大约 41μV/℃,如果 PGA 设为 128 倍,那么 1℃ 的变化放大后约为 5.2mV,ADC 完全有能力分辨。但要注意,增益越高,可测量的绝对电压范围越窄,而且 PGA 自身的失调电压会被一起放大。所以选增益时要根据传感器的实际输出范围来算,不是越大越好。
参考电压同样关键。ADS122U04 支持外部参考电压输入,也有内部参考。做 PT100 测量时,我更推荐用比率式接法:用同一个激励电流源流过 PT100 和一个精密参考电阻,把两个电压分别接到 ADC 的输入通道和参考输入端。这样电流源的任何漂移都会同时作用于信号和参考,最终码值只取决于电阻比值,从原理上消除了激励电流温度漂移带来的误差。实测下来,这种接法比绝对电压测量稳定得多。
2.3 通道复用与传感器类型匹配
芯片的四路模拟输入可以组合成多组差分输入,这也意味着它能同时挂不同种类的传感器——比如通道 1 接 PT100 测风管温度,通道 2 接 K 型热电偶测压缩机排气管表面温度,再用内部温度传感器测冷端。配置输入多路复用器时,需要留意未使用通道的处理,绝不能悬空,否则漏电流可能会影响正在测量的通道。我习惯把闲置通道短接到 AGND,并且通过配置寄存器把对应的输入通道设为禁用。
3. 硬件电路与传感器连接:从原理图层面规避噪声
3.1 供电与去耦:模拟电路的第一道防线
ADS122U04 的模拟电源和数字电源建议分开走线,最后在 PCB 的电源入口处汇合。电源引脚附近必须放 0.1μF 陶瓷电容和 10μF 钽电容做去耦,而且这些电容要尽量靠近芯片引脚。AVDD 和 DVDD 之间不建议直接短接后只加一个电容,而是各自按规格敷设。参考电压引脚 REFP0/REFN0 旁边更需要重点滤波,参考电压是整个测量系统的标尺,它不稳,后面做得再精细都是白搭。
我在实际项目里用的是 3.3V 单电源给 STM32 和 ADC 供电,ADC 的 DVDD 和 AVDD 各接一个铁氧体磁珠再汇入 3.3V 平面,实测可以把开关电源的高频纹波挡掉不少。如果现场电源质量很差,可以再加一级 LC π 型滤波。
STM32L152RE 的供电同样需要做好去耦,尤其是它驱动外部通信接口时的动态电流变化,可能会通过地回路耦合到模拟前端。PCB 布局上,ADC 模拟输入走线必须远离 MCU 的晶振引脚、数字信号线和大电流走线。我的经验是:在 ADC 周围局部铺一个模拟地平面,用 0Ω 电阻或磁珠在一点与数字地连接,模拟走线全部在这块小地平面上走,数字走线严禁穿越这块区域。
3.2 RTD 传感器接线:二线、三线还是四线
PT100/PT1000 的接线方式直接决定测量误差水平。
- 二线制:两根导线电阻直接串入传感器回路,导线的数十毫欧到数欧姆会全部折算成温度误差。PT100 的话,每 0.385Ω 误差就是 1℃,铜导线哪怕只有 1m,也会有明显的偏差。所以二线制只建议用于精度要求不高的场合,且导线电阻必须已知。
- 三线制:在工业现场最常用。三条线中两条给传感器提供激励电流,第三条线接到 ADC 的测量参考点,用软件做线阻抵消。ADS122U04 的差分输入配合 IDAC 激励,天然适合三线制接法,测量精度基本能满足暖通系统的 0.5℃ 要求。
- 四线制:精度最高。由独立的激励电流线对和感应电压线对组成,导线电阻的影响几乎完全消除。实验室或高精度计量场合用四线制,代价是多一根导线和一路输入通道。
我在项目里给冷冻水温度测点用了三线制 PT1000。选 PT1000 的原因是它的信号比 PT100 大十倍,在低功耗场景下可以用更小的激励电流,自身发热更小。PT100 在 1mA 电流下自热效应还算可控,但如果电流偏大,测温结果会偏高;PT1000 在 0.5mA 下就有很干净的信号。
3.3 热电偶接线与冷端处理
K 型热电偶输出的是毫伏级电势,而且它测的是"热端减去冷端的相对温差",必须知道冷端温度,才能算出热端的真实温度。ADS122U04 内部集成的温度传感器可以用来测冷端,做法是:在热电偶的接入端子附近放一个 PCB 铜箔块,让 ADC 内部温度传感器尽可能贴近实际冷端温度,然后软件里读取内部温度传感器的码值,换算成冷端温度后叠加进热电偶的计算公式。
值得注意的是,热电偶信号线必须采用差分接入,而且最好用屏蔽双绞线引到 PCB。屏蔽层在传感器端单端接地,不要让屏蔽层电流流过 PCB 模拟地。另外,K 型热电偶引线如果直接焊在 PCB 上,两种金属的接触会产生额外的热电势,所以很多工业模块会在端子处刻意保持对称,确保冷端温度一致。
3.4 STM32 与 ADC 的 UART 连接
ADS122U04 的 UART 接口是 TTL 电平,与 STM32L152RE 的 USART 可以直接连接。这里要确认引脚方向:ADC 的 UART_TX 接 STM32 的 RX,ADC 的 UART_RX 接 STM32 的 TX,共地。两块芯片间串联 1kΩ 电阻可以在异常时起到保护作用,SPI 场景常见的电平转换芯片这里完全不需要。
如果 ADC 板和 MCU 板是分离的,且连接线超过 10 厘米,建议把 UART 波特率控制在 115200 以内,并在 STM32 侧使能输入上拉或者加一个小幅值的终端电阻。线的长度超过 30 厘米时,我的经验是 UART 数据帧里一般有较宽的脉宽,相比 SPI 的高频时钟对导线寄生电容更宽容,但也不建议无限拉长。
4. STM32L152RE 侧固件实现:UART 指令收发与控制逻辑
4.1 USART 初始化的关键参数
ADS122U04 的 UART 接口是一个标准的异步串行通信接口。STM32 侧配置一个 USART 实例,波特率按 ADC 的数据手册设置,常见配置是 115200。需要注意数据位、停止位和校验位必须和 ADC 侧对齐,否则数据完全解不出来。我用 HAL 库初始化时,代码大致是:
USART_HandleTypeDef huart2; void MX_USART2_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; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } }初版调试时,我习惯在 STM32 的 RX 中断里先做字节接收,等收到完整的响应帧后再解析。千万不要在中断里做滤波或线性化运算,这些开销放在主循环里处理就行。ADS122U04 的响应时间取决于数据速率,数据速率越低,从发指令到拿到数据的时间越长,所以主循环的轮询间隔要留足余量。
4.2 指令帧结构与寄存器配置
ADS122U04 通过 UART 接收命令字节来完成配置和数据读取。命令包括复位、启动转换、读寄存器、写寄存器、读数据等。配置寄存器组中的内容主要涉及:输入通道选择、PGA 增益、数据速率、IDAC 电流源开关和大小、传感器检测模式等。寄存器操作必须遵循严格的时序,写配置之后建议等待一小段时间再启动转换,让内部滤波器稳定下来。
这里分享一个调试时的土办法:先用 USB-TTL 转接板把 ADS122U04 接在电脑上,用串口助手手动发命令帧,确认寄存器读写能正常返回。把这一层验证通了再接 STM32,能避免很多不必要的排查环节。
4.3 主轮询逻辑示例
主循环里的典型流程是:发送"启动转换"命令 → 等待转换完成(延时) → 发"读数据"命令 → 解析 24 位码值 → 做均值滤波 → 换算温度 → 走 Modbus 上报。如果用连续转换模式,则只要周期性读数据即可,MCU 侧减轻了发命令的压力。代码框架:
int32_t ads122u04_read_single_sample(void) { uint8_t tx_cmd = ADS122U04_CMD_START_CONVERSION; uint8_t rx_buf[4] = {0}; HAL_UART_Transmit(&huart2, &tx_cmd, 1, 100); HAL_Delay(ADS122U04_CONV_TIME_MS); tx_cmd = ADS122U04_CMD_READ_DATA; HAL_UART_Transmit(&huart2, &tx_cmd, 1, 100); HAL_UART_Receive(&huart2, rx_buf, 3, 100); uint32_t raw = ((uint32_t)rx_buf[0] << 16) | ((uint32_t)rx_buf[1] << 8) | rx_buf[2]; if (raw & 0x800000) { raw |= 0xFF000000; } return (int32_t)raw; }代码里手动做了符号扩展,因为 24 位 ADC 的输出是有符号码值,存到 int32_t 里必须把高 8 位补成全 1。这个细节有问题的话,温度计算会直接出错,而且尽力排查时一个容易跳过的地方。
4.4 数据准备好与 CRC 校验
工业分区环境中,UART 总线上偶尔会出现误码。ADS122U04 支持 CRC 校验时,建议启用:发送方在数据后附加 CRC 字节,接收方在 STM32 侧用同样的多项式验一遍。CRC 失败时,我最常见的处置方法是丢弃本次采样并计数,连续 N 次失败再触发报警或重启通信。直接重置通信的代价有点激烈,不建议第一次 CRC 失败就复位,可能频繁打断正在进行的转换。
5. 从 ADC 码值到真实温度:RTD 与热电偶的换算与校准
拿到原始码值之后,真正体现工程师功底的是怎么把它变成准确、可复现的温度值。
5.1 PT100/PT1000 的三步换算法
以三线制 PT1000 为例,激励电流设为 250μA。参考电阻采用高精度低温漂电阻,比如 1kΩ 0.01% 25ppm/℃。这里选择 RTD 对应的测量顺序:
第一步,记录比例:ADC 码值本质上是 V_rtd / V_ref(两通道电压比值)。由于采用了比率式接法,传感器电阻直接是:
R_rtd = (Code_rtd / Code_ref) × R_ref
实际计算中,不用分别解出两个绝度电压,直接把两个通道的 ADC 原始码值相除即可。这一步就把激励电流源漂移、基准电压漂移全部抵消掉了。
第二步,查表或多项式拟合:PT1000 在 -40℃~150℃ 范围内的电阻-温度关系,用 Callendar-Van Dusen 方程的一组系数可以算得很准。为了在 MCU 上省资源,我把标准表做成一维数组,用二分查找加线性插值法求温度。每 1℃ 一个点位,插值误差不超过 0.05℃,MCU 开销非常小。
第三步,补偿线阻:三线制接法下,两条激励线上的电阻都会产生压降,导致 V_rtd 偏高。做法是先测一次短路状态下的线阻,然后在计算时减去这部分压降。
5.2 热电偶线性化与冷端补偿
K 型热电偶的标准电势表是分段多项式,直接展开成大表格也行,但 MCU 内存够用的话,建议采用 NIST 的多项式表示。实际计算有两步:
- 第一步,用冷端温度 T_cold 查表得到对应的冷端电势 E_cold;
- 第二步,测出的热电势 E_measured 加上 E_cold,得到总电势,再反查表得到热端温度 T_hot。
如果直接用 STM32 的内置温度传感器做冷端检测,注意 MCU 自身发热会污染冷端温度,所以冷端温度传感器应该尽量放在接线端子附近,而不是放在 MCU 旁边。ADS122U04 内部温度传感器因为离热电偶输入引脚较近,恰好适合这个任务。实际测量时把内部温度传感器的码值读出来,按数据手册的线性换算公式得到结温,然后在热电偶算法里使用该结温作为冷端温度。
5.3 零点校准和两点校准
即便有理论公式,实际板卡出来还是会存在零点偏移和增益误差。我的做法是:批量生产前,用精密电阻箱模拟 RTD 阻值,或者用恒温水槽 + 标准温度计校准。零点是很好修的——在接线端子短接状态下读一个码值,记为 OFFSET;增益误差则通过两个标准温度点的测量值,算出实际斜率和理想斜率的比值,存到 Flash 参数区里。
校准结果示例:
| 校准点 | 标准温度(℃) | ADC 计算温度(℃) | 修正后(℃) |
|---|---|---|---|
| 零度槽 | 0.0 | 0.32 | 0.00 |
| 热水槽 | 80.0 | 79.6 | 80.0 |
校准补偿公式:
T_corrected = (T_raw - OFFSET) × GAIN_FACTOR
GAIN_FACTOR = (T_std2 - T_std1) / (T_raw2 - OFFSET - T_raw1 + OFFSET)
这类参数在每台设备出厂时写入独立地址,生产环节可以快速烧录。
6. 工业与 HVAC 场景下的实测问题和应对经验
6.1 变频器和接触器带来的共模干扰
HVAC 系统里变频器随处可见,它们产生的共模干扰会通过电源、地线、或者空间辐射耦合进模拟前端。第一次现场调试时,我发现 ADC 读数在变频器启动时跳动了约 0.3℃,排查后发现是共模电压导致 ADC 输入端超出共模范围。解决措施有几个:
- 增加输入端的共模滤波电容(比如 10nF 到模拟地);
- 信号线用双绞屏蔽线,屏蔽层在传感器侧单端接地;
- 给 ADC 供电加一级共模电感。
还有一点很重要:ADS122U04 和 STM32 之间的 UART 线,如果与变频器动力线走同一个线槽,误码率会明显上升。现场布线时,通信线要远离动力线 20cm 以上,或者改用带屏蔽的 RS485 做长距离传输,把 UART 转成差分信号。
6.2 低功耗采样策略
STM32L152RE 支持多种低功耗模式,但工业测量设备通常要求的是"平均功耗低"而不是"随时休眠"。我的做法是:ADC 设置为单次转换模式,主控平时进入 STOP 模式,用 RTC 闹钟定时唤醒,唤醒后给 ADC 发命令完成一次采样,处理完再次睡眠。ADS122U04 单次转换完成时间与数据速率有关,20SPS 对应约 50ms,这个时间内可以保持 MCU 处于 RUN 状态,完成后立刻进入 STOP。实测这套策略在 1 分钟采样一次的工况下,平均电流可以降到百微安级别。
如果采用连续转换模式,ADC 会持续输出数据,MCU 要么频繁唤醒取数据,要么让 USART 用 DMA 接收循环缓冲区。DMA 方案更省电,让 CPU 沉睡,由 DMA 把接收到的数据搬到内存,等缓存里攒了若干帧再唤醒统一处理。
6.3 长期稳定性与看门狗设计
温度测量设备是要长时间运行的,最怕的是死机后输出错误高温低温值导致控制逻辑误动作。所以 STM32 侧的看门狗不仅要防死循环,还要防"数据不更新"逻辑:设定一个时间上限,如果超过 2 个采样周期 ADC 都没有新数据到达,就进入通信故障处理,输出安全状态。
另外,供电浪涌和雷击在工业现场也是不可忽视的风险,特别是温度传感器线缆很长,很可能成为感应雷的入口。传感器输入端口需要增加 TVS 管和正温度系数热敏电阻(PTC)做保护。TVS 的结电容会稍微影响 ADC 建立时间,选型时要注意其电容值不要过大,否则高频噪声会更容易耦合进来。
6.4 多通道轮询时最容易踩的坑
多通道测量时,相邻通道之间可能会串扰。原因主要是模拟输入多路复用器在切换通道后,内部采样电容没有完全稳定。解决办法有两个:一是每个通道切换后丢弃前几次转换结果,二是降低数据速率留出建立时间。我在三通道轮询 PT1000 时,每个通道连续转换连续两次,用第二次的结果作为有效值。这个"丢弃前一次"的套路在很多高精度 ADC 项目里都适用。
另外,当一个通道接 RTD,另一个通道接热电偶时,两者需要的 PGA 增益和输入配置不同。代码里每切换一次通道,都要重新写一遍配置寄存器,不能懒到只改通道编号。我就是在这个地方吃过亏:通道 1 用 128 倍增益测热电偶,切到通道 2 测 PT1000 后没改增益,接线又恰好是两线制,结果读数部分的精度完全不对。
6.5 量产和调试时数据稳定性验证
在实验室条件验证稳定的数据,到现场未必能做到一致。我的测试流程是:先在室温下连续采集 10 分钟,看最大最小温升;再用热风枪局部加热模拟前端,看数据是否随环境温度明显漂移。如果 PCB 局部受热导致参考电压或 PGA 偏移,最大的问题往往来自 PCB 布局而非芯片本身——参考电压走线过长、模拟地和数字地混在一起,这类问题在热应力下特别容易暴露。
电感、风扇、物位开关等设备在同一柜内时,我还会做一次"开关噪声测试":反复开关骚扰负载,同时监测 ADC 原始码值的跳变幅度。如果跳变超过预期,就用上述提到的滤波和保护措施逐项排查,直到最终满足 ≤ 0.1℃ 的多次采样抖动目标。
整套方案从样机到量产定型,ADS122U04 负责的信号采集链路在稳定性和精度上几乎没有让我操过心,反而是在接线方式、数据滤波、寄存器切换这些"软件细节"上反复打磨了很久。如果你的项目也需要在工业或 HVAC 环境里做多路、高精度温度测量,这个组合是很值得参考的起点。