前阵子帮客户做了一批用于 HVAC 风管、水管和环境温度采集的板卡,信号链主控用了 ADS122U04IPWR 和 STM32L152RE 这对组合。ADS122U04 是 TI 一颗 24 位四通道内置 PGA 的低功耗 ΔΣ ADC,接口走 UART;STM32L152RE 则是 ST 家的超低功耗 Cortex-M3 控制器。两个芯片都不算新,但放到工业和暖通场景里,这组合的性价比、抗干扰能力和调测便利性都很能打。这篇文章把这套方案的完整思路、硬件参数、固件算法以及调试中踩过的坑整理出来,给正在做多通道温度采集、或者想自己搭一块模拟量输入板的同学一个可以直接参考的案例。
先说一个总的判断:如果只是测几个点的温度,用 DS18B20 或者 PT100 配专用变送器确实更省事。但当你需要同时测十几路模拟量、要保证全温度范围内误差小于 0.5℃、还要把数据通过 UART 送到主控跑逻辑时,一颗高分辨率 ADC 加一颗低功耗 MCU 的传统离散方案反而是最稳妥的。ADS122U04IPWR 和 STM32L152RE 的组合能把信号链的每一级都握在自己手里,后面的文章我会逐段展开。
1. 项目背景与方案选型思路
1.1 HVAC 场景对温度测量的核心需求拆解
工业和 HVAC 应用里的温度测量,往往不是简单“测个温度”这么简单。以我这次的项目为例,客户要求覆盖三类物理量:风管送风温度、水管供回水温度、机柜环境温度。这些量的共同特点是变化缓慢、量程不大,但精度要求高。风管从 -20℃ 到 80℃ 是常事,水管在 5℃ 到 95℃ 之间波动,环境温度则是 0℃ 到 55℃。最核心的指标是全量程误差不超过 ±0.5℃,部分计量级点位要求 ±0.2℃。
这个精度需求意味着传感器输出信号在微伏到毫伏级别,ADC 的分辨率必须足够高。温度变化 0.1℃ 时,PT100 的电阻变化只有约 0.04Ω,如果激励电流是 500μA,对应电压变化只有 20μV 左右。普通的 12 位或 16 位 ADC 在这个量级下根本分辨不出来,必须用 24 位级别的 ΔΣ ADC 才能留出足够的设计余量。
另一个容易被忽略的需求是多通道。HVAC 机组往往一台就要监测 4 到 8 个温度点,如果每个点都配一颗 ADC 和一套隔离电路,成本立刻失控。ADS122U04 一个芯片带四路模拟输入,配合模拟多路开关还能继续扩展。这颗芯片内置了可编程增益放大器 PGA、两个匹配的激励电流源 IDAC、内部基准、内部温度传感器,几乎把模拟前端的所有元组件都集成进去了,这对板面积和 BOM 成本都是实打实的优化。
1.2 ADC 选型逻辑:为什么是 ADS122U04IPWR
ADS122U04 这个型号我第一次看数据手册时就注意到它的后缀 U,这个 U 代表 UART 接口版本。同系列的 ADS122C04 是 I2C 接口,ADS1220 则是纯 SPI。市面上常见的 24 位 ADC 基本都是 SPI 或 I2C,UART 接口的反而是少数。那为什么要选一个 UART 接口的 ADC?
主要有三个原因。第一,STM32L152RE 的 USART 资源相对丰富,用 UART 跟 ADC 通信不需要额外占用 SPI 外设,IO 口占用也只有 TX/RX 两线,和 4 线 SPI 相比节省了两根线。第二,UART 在长距离传输上的抗干扰能力比 SPI 好一些,工业现场经常要把传感器板卡和主控板拉开几十厘米甚至几米,UART 波特率放低一点,线缆走双绞线,通信稳定性明显优于高速 SPI。第三,UART 协议天然是字节流,调试时可以拿 UART 转 USB 器直接抓 ADC 输出,逻辑分析仪都不用接,排查问题非常方便。
在 24 位 ADC 阵营里,ADS122U04 的核心竞争力在于内置 PGA 和 IDAC。如果没有内置 PGA,热电偶输出几十微伏的信号就必须外接仪表放大器,成本和噪声都上去了。如果没有内置 IDAC,RTD 和 NTC 的激励电流就得自己用恒流源搭,温漂和匹配度很难保证。这颗芯片把这两样东西都集成了,而且 IDAC 的匹配度做得相当好,正负激励电流之间的偏差在几个微安级别,这对比例式测量至关重要。
1.3 温度传感器选型对比:RTD、NTC 还是热电偶
确定了 ADC 和 MCU 之后,紧接着要确定传感器类型。温度传感器选型是整个信号链最前端的关键决策,选错了后面精度怎么调都找不回来。我结合项目需求做了一张对比表,供大家参考:
| 传感器类型 | 精度等级 | 测量范围 | 线性度 | 信号电平 | 主要成本 | 适合场景 |
|---|---|---|---|---|---|---|
| PT100 | ±0.1%~±0.3% 全温度范围 | -200℃~850℃ | 较好,需查表或多项式 | 100Ω,毫伏级 | 中等 | 风管、水管、工业设备 |
| PT1000 | 同 PT100,但阻值大 10 倍 | -200℃~850℃ | 同上 | 1kΩ,毫伏级 | 中等偏高 | 低功耗、长线缆、小封装 |
| NTC 热敏电阻 | 窄范围较高,宽范围差 | -50℃~150℃ | 差,需 Steinhart-Hart | 数千欧,电压较高 | 低 | 环境温度、消费级 HVAC |
| 热电偶 | 中高,依赖冷端补偿 | -200℃~1800℃ | 较差 | 微伏级 | 低 | 高温、排气、压缩机 |
HVAC 场景里用得最多的是 PT100 和 NTC。PT100 胜在稳定性和全量程精度,水管测温、计量级点位我基本都选它。NTC 胜在便宜和灵敏度高,做环境温度、风管温度这种要求不高的点位非常合适。热电偶在 HVAC 里主要是测压缩机的排气温度,温度动不动上百摄氏度且现场有强电磁干扰,这时候热电偶加上 ADS122U04 的高增益 PGA 反而是唯一的经济选择。这套方案我把三类传感器都覆盖了,后面硬件和固件部分会分别说明配置差异。
2. 硬件设计核心细节与参数计算
2.1 比例式测量原理:为什么不能直接测绝对电压
很多同学第一次用 ADC 测电阻类传感器时,习惯性的做法是 ADC 采样传感器两端电压,然后根据恒流源电流大小计算阻值。这个思路本身没错,但忽略了一个致命问题:激励电流源的绝对精度和温漂。假设 IDAC 设定 500μA,实际输出 498μA,偏移 0.4%,换算成温度误差可能超过 1℃,这在 HVAC 场景是无法接受的。
解决这个问题的方法叫比例式测量。原理很朴素:让同一个激励电流同时流过传感器和一颗精密基准电阻,然后把基准电阻的压降作为 ADC 的参考电压。转换结果就不再依赖电流的绝对值,而只取决于传感器电阻与基准电阻的比值。基准电阻可以选低温漂、高精度的金属箔电阻,它的稳定性远好于任何内置恒流源。
具体到 ADS122U04,做法是这样的:IDAC1 从某个引脚输出电流,电流依次流过 RTD 和基准电阻 R_BIAS 回到地。RTD 两端的电压接到 ADC 的差分输入,R_BIAS 两端的电压接到 ADC 的参考输入 REFP/REFN。ADC 输出码值近似等于:
code ≈ 2^23 × PGA × R_RTD / R_BIAS注意这个公式里根本没有 IDAC 的数值。只要电流源没饱和、没有超过基准电压范围,它的绝对误差和温漂就被完整抵消掉了。我在第一版设计时曾经偷懒直接用了内部基准 2.048V,结果温漂和数据手册完全对不上,后来改成比例式测量,整条信号链的稳定性立刻上了一个台阶。
2.2 RTD 测量电路参数计算与 R_BIAS 的选择
比例式测量确定了,下面动手算参数。我以 PT100 测 0℃ 到 150℃ 为例,把计算过程完整走一遍。
PT100 在 0℃ 时电阻是 100Ω,150℃ 时约为 157.33Ω。激励电流选择 500μA,这个值兼顾了信噪比和自热效应。电流太大,PT100 自身发热会造成测量点温度偏高,500μA 在 100Ω 上的功耗只有 25μW,自热误差基本可以忽略;电流太小,信号电平低,对 PGA 噪声和 PCB 走线噪声会更敏感。
电流选定后,传感器压降:
- 0℃ 时 V_RTD = 500μA × 100Ω = 50mV
- 150℃ 时 V_RTD = 500μA × 157.33Ω ≈ 78.67mV
PGA 增益选 8 倍:
- 输入到 ADC 的电压范围约为 400mV 到 629mV
- 距离内部基准 2.048V 还有充裕余量
接下来算基准电阻 R_BIAS。如果要用内部基准的 2.048V 作为 ADC 参考电压的近似替代来估算,R_BIAS 的理想值应该是 2.048V / 500μA = 4096Ω。但这里有个工程上的精细操作:参考电压实际上会随着 IDAC 的实际输出值浮动,这正是比例式测量的精髓。电阻选 E96 系列的 4.02kΩ,0.1% 精度,温漂 25ppm/℃ 足够用。
最终信号跨度的估算:150℃ 对应的电阻变化是 57.33Ω,乘以 PGA=8,在 ADC 输入端的电压变化约 229mV;基准电压约 2.01V。对应码值跨度大约是 229mV / 2010mV × 2^23 ≈ 95.6 万 LSB。折算下来 1LSB 对应温度约 0.00016℃,说明系统噪声才是精度的瓶颈,ADC 分辨率远不是。这也是为什么 24 位 ADC 在这个场景里真正有价值的原因。
2.3 NTC 和热电偶通道的配置扩展
NTC 通道测量方法类似,但要注意 NTC 的电阻跨度非常大。我用的 10kΩ 型号,0℃ 时大概 33kΩ,25℃ 时 10kΩ,60℃ 时约 3kΩ。IDAC 如果还用 500μA,0℃ 时 NTC 压降高达 16.5V,远超基准电压,直接把电路打饱和。
所以 NTC 通道要把 IDAC 配到最小档,比如 50μA,同时把 PGA 配到 4 倍。这样 0℃ 时 NTC 压降 1.65V,加上 PGA 增益后接近但不超过参考电压,既保证了信号分辨率又避开饱和。NTC 通道对基准电阻的要求不像 RTD 那么高,因为 NTC 本身精度就有限,常温下做到 ±0.5℃ 已经不错,但即便如此我还是建议保留比例式接法,至少能消除 IDAC 绝对值的温漂。
热电偶通道则是另一套思路。热电偶输出的是微伏级的差分电压,K 型热电偶灵敏度约 40μV/℃,测量 0℃ 到 400℃ 对应的差分电压约 16mV。这种情况下 PGA 要拉到 32 或 64 倍,基准电压可以直接用内部基准。关键难点在冷端补偿:热电偶的参考端必须和 ADS122U04 的内部温度传感器保持热耦合,芯片内部刚好有一颗二极管温度传感器,读出来的管芯温度可以直接当作冷端温度。把冷端温度换算成热电偶热电势,再补偿到测量结果里。这部分算法我会在后面固件章节细说。
2.4 模拟前端滤波与 PCB 布局实战
硬件设计里最容易被轻视的就是模拟前端滤波和 PCB 布局。我第一版板子就是在这里栽了跟头,试产 20 片中有 5 片在电磁干扰强的现场出现数据跳字,排查到最后就是低通滤波参数和地线处理没做到位。
每路差分输入都加了一个一阶 RC 低通滤波。电阻取 1kΩ,差分电容取 1μF,计算截止频率约 160Hz。别小看这个简单的滤波器,它对 50Hz 工频干扰和电机驱动产生的高频噪声都有明显的抑制作用。在 RTD 通道上,电容建议选用 C0G 或 NPO 材质,X7R 在大电压波动下会有压电效应,反映到微弱信号上就是莫名其妙的噪声。
PCB 布局方面,我总结了三条实际经验。第一,ADS122U04 的模拟输入走线要远离数字 IO 和电源走线,最好在模拟区域下方铺一块完整的地铜,不要被信号线打断。第二,RTD 如果通过线缆引出,必须采用四线制开尔文连接,两条驱动线走电流,两条检测线走电压,这样即使线缆电阻有几欧姆,也不会引入测量误差。第三,芯片电源引脚和参考电压引脚附近各放一个 0.1μF 陶瓷电容,再并联一个 10μF 钽电容,形成完整的电源去耦网络。
3. 固件实现:从 UART 到温度线性化
3.1 STM32L152RE 的 UART 初始化与硬件连接
硬件板卡跑起来之前,先要保证 MCU 和 ADC 之间的 UART 链路是通的。STM32L152RE 我用的 USART2,波特率设置 115200,8 位数据位,无校验,1 位停止位。ADS122U04 的 UART 时序有它自己的特定帧结构,建议直接以数据手册的 UART 接口章节为准,重点确认起始位解析、命令帧格式和上电时序。第一次调板时最稳妥的做法是用 USB 转 TTL 工具监听 ADC 的 TX 引脚,看看器件上电后有没有主动输出任何字节,如果有,基本说明芯片供电和时钟正常。
代码层面我用的是 STM32 标准外设库,UART 初始化片段大致如下:
USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStructure);这里有个容易忽略的坑:ADS122U04 的 UART 逻辑电平如果和 MCU 不一致,需要在两者之间加电平转换。工业板卡上我通常把 ADC 部分用 3.3V 供电,STM32L152RE 也是 3.3V,直接互联没问题。如果 ADC 单独供电或用了隔离,就必须把隔离器选型提前设计进去,否则通信会随机丢字节。
初始化完成之后,先发一个复位命令让 ADC 回到已知状态,延时 10ms,然后读回默认寄存器值做校验。只有读回的数据和手册默认值一致,才能认为通信链路是正常的。这一步能过滤掉大批因焊接、供电导致的隐性硬件故障。
3.2 ADS122U04 寄存器配置与转换流程
ADS122U04 的配置全部通过寄存器完成,寄存器配置决定了测量模式、通道选择、PGA 增益、数据速率、激励电流等关键参数。在正式写配置之前,建议先画出功能需求表,把每一个要用的通道对应的输入引脚和通道配置都列出来,避免写代码时搞混。
我的 RTD 通道配置大致如下:AIN0/AIN1 组成差分输入,MUX 选择对应通道,PGA 增益 8,数据速率选 20SPS,转换模式选连续转换,IDAC1 设为 500μA,IDAC 从 AIN0 引脚输出电流,基准源选择外部基准引脚 REFP0/REFN0。寄存器写入过程是一次写多个寄存器,示例代码:
uint8_t config[4]; config[0] = 0x36; // MUX = AIN0-AIN1, 增益 = 8 config[1] = 0x10; // 数据速率 = 20SPS, 连续转换模式 config[2] = 0x00; // 参考源 = 外部基准 config[3] = 0x06; // IDAC1 = 500uA, IDAC 输出到 AIN0 ads122u04_write_reg(0, config, 4);写完寄存器之后,要等 DRDY 信号拉低表示转换完成,再发送读数据命令把 24 位转换结果读回来。整个流程可以放在周期性定时中断里,或者用 DRDY 外部中断触发 MCU 读取。在 HVAC 场景里,温度变化很慢,20SPS 的数据速率足够,功耗还低。如果需要滤除 50Hz 工频干扰,20SPS 正好是 50Hz 的整数分之一,ΔΣ ADC 的积分特性会直接把工频成分压制下去,这是选这个速率的重要原因。
读回来的 24 位数据是二进制补码格式,需要先转成有符号数,然后按照基准电压和 PGA 增益反向换算成电压值,再除以 IDAC 得到电阻值,最后查表或拟合出温度。这条链路上每一步都有坑,我会在下一小节详细展开。
3.3 温度线性化算法:PT100 与 NTC 的工程化处理
ADC 输出的码值只是电压比例,距离真正的温度还隔着一段很长的路。PT100 的电阻-温度关系用 Callendar-Van Dusen 方程描述,工程上最直接的处理是建一张分度表。以 0.1℃ 为步长,把 -50℃ 到 200℃ 的对应阻值预先算好放进 Flash 里,MCU 上电后把实时阻值和表项做二分查找,然后线性插值。这个表格大概 2500 项,每项存 float 或 int32,Flash 资源完全够用。
查表法虽然直观,我最终还是换成了查表加偏移修正的方案。因为 PT100 的出厂个体差异和 ADC 内部基准的微小偏差会导致系统性偏差,仅仅靠理想分度表无法消除。做法是:在产线标定时,把探头放到 0℃ 冰水槽和 100℃ 沸水槽,记录两组 ADC 计算出的电阻偏差,然后建立一个线性修正系数,在软件里统一补偿。这样产线效率和精度都能兼顾。
NTC 的线性化则不同。NTC 的电阻-温度关系高度非线性,查询表虽然也能用,但步长太大会导致插值误差。更优雅的做法是直接用 Steinhart-Hart 方程:
1 / T = A + B × ln(R) + C × (ln(R))^3使用厂商给出的 A、B、C 系数,代入当前电阻值算温度,精度在全量程范围内约 ±0.1℃。三个系数的获取一般都在 NTC 数据手册里直接给,或者通过三点校准自己解方程组得到。
热电偶通道的线性化最麻烦。热电偶的热电势和温度之间是非线性关系,而且测量到的毫伏值必须减去冷端的热电势。标准做法是:读取芯片内部温度传感器得到冷端温度,反查热电偶分度表得到冷端对应的热电势,把它加到实测毫伏值上,再用修正后的毫伏值正查分度表得到实际温度。ADS122U04 内置的温度传感器精度大约 ±1℃,用于冷端补偿已经足够,对大多数暖通场景来说这个补偿精度是可以接受的。
4. 系统标定与环境测试
4.1 上电自检与出厂测试流程
量产阶段的标定流程决定了一批板卡的合格率,我在这里分享一个经过验证的流程。
每一块板卡上电后,MCU 首先执行通信自检:尝试复位 ADC、读取寄存器、读回默认值。校验成功后系统进入测温状态,同时 ADC 的内部温度传感器和外部 RTD 通道会同时采样。首轮测试用高精度电阻箱模拟 PT100,分别设定 100Ω、119.4Ω、138.5Ω 三档,对应 0℃、50℃、100℃ 三个标准点。
每个标定点采集 100 次取平均,记录码值和计算电阻值。然后用两点法计算实际增益和偏移量,写入板卡的 EEPROM。整个测试过程中,我会重点关注前 3 分钟的数据漂移:如果首采的平均值和 10 分钟后的平均值差异超过 0.05℃,说明激励电流自热或板上热平衡还没有稳定,这块板子在出货前需要重新筛选。
4.2 精度评估与实测数据
标定完成后,最好用真实验证环境而不是一直依赖电阻箱。我把板卡放入恒温槽,设定 25℃、45℃、70℃ 三档,同时用高精度温度计做参考值。实测结果中,PT100 通道全量程误差在 ±0.3℃ 以内,NTC 通道在常温段误差约 ±0.5℃,热电偶通道在冷端补偿到位时误差约 ±1℃,基本覆盖了 HVAC 项目的设计指标。
数据速率方面,我测过 20SPS 和 200SPS 两种配置下的峰峰值噪声。20SPS 时码值噪声大约在 ±4 LSB,折合温度约 ±0.0007℃,远优于需求;200SPS 时噪声增大到 ±12 LSB,虽然也能用,但遇到现场有变频器驱动的 HVAC 系统时,偶尔还是会出现个别的毛刺。所以实际量产固件里我统一用 20SPS,后面的项目也建议沿用这个保守选择。
功耗测试结果:STM32L152RE 跑在低频模式,只有进行周期采样时唤醒 UART,整板功耗在 3.3V 供电下约 8mA 左右。接上电池可以撑很长时间,这一点是在做便携式现场检测仪时非常重要的收益。
5. 常见问题与调试实录
5.1 数据跳字与工频干扰
现象:上电后测量常温,数据稳定几秒后出现 ±20 LSB 的随机跳变,尤其在靠近变频器和压缩机的现场更严重。
排查过程:先用示波器看 RTD 差分输入波形,能观察到 50Hz 工频和少量高频噪声叠加。代码里把数据速率从 200SPS 改成 20SPS,跳变幅度立刻下降了近一半。接着确认差分电容是否存在虚焊,补焊后跳变基本消失。
结论:ΔΣ ADC 的数据速率和工频抑制是强耦合的,设计阶段就应该同步考虑,而不是等现场出了问题再降速。此外,RC 滤波电容不能省,位置尽量靠近 ADC 引脚,引线过长会形成环路天线反而引入噪声。
5.2 IDAC 自热和激励电流异常
现象:同样的 PT100 探头,插到第二块板卡上读数比第一块板卡高约 0.8℃。
排查过程:用万用表测 IDAC 实际输出电流,发现两块板卡的 IDAC 差异超过了 5μA,直接导致传感器压降不一致。换用比例式测量后,重新测试两块板卡读数几乎一致。
结论:凡是测电阻类传感器,一律用比例式测量,不要依赖 IDAC 的绝对精度和跨芯片一致性。如果实在要用内部基准做绝对电压测量,就必须在产线上逐板校准,工作量会大很多。
5.3 UART 通信偶发失败
现象:设备长时间运行后,偶尔出现读不到转换结果,重启后恢复正常。
排查过程:用串口日志定位,发现是 ADC 进入了不正确的状态机。把复位命令和回读校验逻辑加进每次读数据流程之前,问题基本不再出现。同时发现如果主控和 ADC 之间的地线压差过大,UART 信号质量会严重劣化,后来在 PCB 上用多点接地把模拟地和数字地连在一起,彻底解决。
结论:工业通信没有玄学,所有偶发问题背后都有确定的根因。建议每次读数据前主动发一次同步命令,即使 ADC 处于正常状态也会丢弃该命令,并不影响转换流程,却能显著提升系统在恶劣环境下的鲁棒性。
5.4 热电偶冷端补偿误差
现象:K 型热电偶在 100℃ 标准温度源上读数是 99.2℃,偏低 0.8℃。
排查过程:用测温枪测热电偶端子座的温度,发现端子座和 ADS122U04 芯片之间有约 6℃ 的温差。芯片内部温度传感器测量的是芯片管壳温度,不是端子温度,误差直接被带入补偿结果。
结论:冷端传感器不能随便放。正确做法是把热电偶端子尽可能靠近 ADC 芯片,并在 PCB 上做热等温设计,也就是在端子座和芯片之间铺一块连续的铜箔,让两者温度趋近一致。如果结构上做不到,就应该外用一颗 NTC 贴在端子座上,用它的读数值做补偿源。
最后再分享一个我这两版设计换来的体会:第一版死在 PCB 布局和通信稳定性上,第二版真正稳定下来,靠的不是换更高精度的元件,而是把比例式测量、保守的数据速率和产线标定这三件事做扎实了。给做温度采集的朋友一个建议,不要迷信 24 位 ADC 的高位数,先把基准、激励电流和传感器这三者之间的关系理清楚,24 位才有意义。ADS122U04IPWR 与 STM32L152RE 这套组合,硬件架构和软件框架都不复杂,真正的护城河在于对信号链细节的掌控。