如果你正在做HVAC项目,想用STM32F100ZE去读温度传感器,十有八九最后会选到ADS122U04IPWR这颗24位ADC。做工业或者空调控制,最怕的就是采集链路不稳定,因为后面PID、联锁、能效统计全指望这一路温度准。ADS122U04IPWR自带可编程增益放大器和激励电流源,又用UART接口与STM32F100ZE通信,在冷冻水流量计、风管温度、压缩机油温和HVAC节能控制里都能直接搭起来用。这篇文章就把这套温度测量链路从选型、原理、电路、固件到抗干扰经验完整捋一遍,适合正在做温控仪表、楼宇自控或工业数据采集的嵌入式工程师参考。
1. 项目思路:为什么是ADS122U04IPWR加STM32F100ZE这套组合
1.1 工业与HVAC测温,真正卡脖子的地方是什么
先说痛点。很多刚接触温度采集的工程师,第一反应是“MCU自带ADC不就行了”。放到HVAC项目里,这个想法很快会被现实教训。PT100在0℃时是100Ω,温度每变化1℃,电阻大约只变化0.385Ω。假设激励电流是1mA,对应的电压变化只有385μV,如果要分辨0.1℃,就是38.5μV。普通MCU的12位ADC,参考电压3.3V时,一个LSB大约是0.8mV,离这个精度差了二十多倍。热电偶更夸张,K型热电偶灵敏度大约41μV/℃,在常温附近测0.1℃也才几个微伏,MCU内置ADC根本没法直接处理。
除了信号弱,工业现场和HVAC机房的干扰也特别讨厌。变频压缩机、风机、水泵、电磁阀这些设备一开,电源线上都是毛刺,地电位也会来回飘。传感器线如果从风管拉到控制柜,走个十几米很正常,沿线会收集到工频、PWM开关噪声和静电放电。所以这类应用需要的不是“一个ADC”,而是一条能抗干扰、能远程通信、能稳定复现微弱信号的完整模拟链路。ADS122U04IPWR这种24位Delta-Sigma ADC,天然就是干这个的。
1.2 选型时我对比过的几颗器件
我在选型阶段对比过不少方案,包括ADS1220、ADS124S08、AD7124-4和ADI的几种Sigma-Delta ADC。ADS1220是便宜,SPI接口,双差分输入,做简单测温没问题,但SPI隔离麻烦,而且还得自己写驱动。ADS124S08通道多、功能全,适合多路采集站,可价格和封装复杂度也上去了。AD7124-4性能很好,软件生态也成熟,但在一些时期供货和价格不太友好。
ADS122U04IPWR这台最吸引我的地方是UART接口。工业现场如果想做长距离传输,UART加光电隔离或者转RS-485都非常顺,比SPI隔离省事很多。它同样内置PGA、两个激励电流源、内部温度传感器和外部基准输入,用来测PT100或热电偶绰绰有余。下面这张表是我当时的对比记录:
| 芯片 | 接口 | 输入通道 | 内部激励源 | PGA | 适合场景 |
|---|---|---|---|---|---|
| ADS122U04IPWR | UART | 4路单端/2路差分 | 有 | 有 | 远程温度、隔离采集、HVAC |
| ADS1220 | SPI | 2路差分 | 有 | 有 | 简单测温、近距离 |
| ADS124S08 | SPI | 12路输入 | 有 | 有 | 多通道数据采集站 |
| AD7124-4 | SPI | 4路差分/8路单端 | 有 | 有 | 高精度通用仪表 |
最终选UART版本还有一个原因:STM32F100ZE自带多个USART,而且支持DMA,硬件上几乎零成本,对后续做RS485网关也顺手。
1.3 STM32F100ZE为什么够用
STM32F100ZE是Cortex-M3内核,主频72MHz,属于ST的基础型产品。虽然性能上不如F4、H7,但做温度采集绰绰有余。ZE后缀代表144引脚,大容量Flash,具体资源我记得是512KB Flash和32KB SRAM左右,存引导程序、表格和算法都够。它还有多个USART、SPI、I2C、DMA、看门狗和CRC模块,正好对付ADS122U04IPWR的串口通信。
有人会觉得F100ZE老,但温度采集这种活,资源大量富余。我实际用下来,初始化ADC、DMA收数据、做滤波和线性化,CPU负载不到10%。剩下的资源还能跑Modbus协议栈、控制继电器、处理按键和LCD。更重要的是F100系列工作温度范围宽,供货稳定,价格比F103还便宜,在工业/HVAC产品里成本敏感,这就很有优势。
2. 核心原理:一条从传感器到数字量的完整信号链
2.1 从uV级信号到24位数字量
Delta-Sigma ADC的核心理念是“用速度换精度”,内部用极高频率对模拟输入采样,再通过数字滤波器把带内噪声整形掉。跟普通逐次逼近型ADC相比,它对前端抗混叠滤波的要求低得多,非常适合低频、小信号的温度测量。
ADS122U04IPWR内部还有可编程增益放大器(PGA),这是关键。没有PGA的时候,几毫伏的信号直接进ADC,会被噪声和失调吃掉。打开PGA后,信号先被放大,再做模数转换,微小变化就能被分辨出来。以PT100接500μA激励为例,0℃时信号约50mV,100℃时约69.25mV。如果PGA增益设成8,ADC满量程输入范围大约是±0.256V(内部Vref约2.048V时),这个范围刚好让PT100的电压处在中间区域,既不饱和又有足够分辨率。
分辨率这块也要算清楚。24位ADC理论上的最小码,在满量程±0.256V、增益8的情况下,一个LSB约合30nV,远低于PT100在0.1℃对应的电压变化。实际有效分辨率会被噪声限制,但把采样率降到20SPS左右,打开内部滤波器,做到17到18位有效分辨率没有问题,对应温度分辨率能到0.001℃级别,至少是够用了。
2.2 比例测量:同一个电流源解决温漂
温度采集有个容易被忽略的问题:激励电流源本身会随温度漂移。如果我用一个恒流源给PT100供电,再单独用ADC的参考电压去测PT100上的电压,电流源的漂移会直接变成温度误差。解决方法是比例测量。
ADS122U04IPWR可以把外部精密电阻Rref接在ADC的参考输入端,同时让同一个激励电流流过PT100和Rref。这样参考电压就是电流乘以Rref,而PT100上电压就是电流乘以RTD电阻。做除法时,电流那一项被约掉,最终公式变成:
- RTD电阻 = 原始ADC码比例 × Rref
这就像两个人用同一把尺子量东西,尺子自己热胀冷缩了,只要对比的是两者的相对长度,误差就抵消了。比例测量的本质就是这个。外部Rref一定要选低温漂、高精度的金属箔电阻,精度0.1%、温度系数5ppm/℃以下,基本是标配。
如果是三线制PT100,要想抵消导线电阻,还要靠两个激励电流源配合。原理上是用两个等大的电流,分别流过两根相同长度的导线,在线阻上产生的压降相近,ADC差分输入在公共地端把这两个电压减掉。四线制更干脆,用独立的两根感应线去测RTD电压,线路上没有电流,线阻再大也不影响精度。在HVAC现场,如果传感器线超过两三米,我强烈建议至少用三线制,能直接省掉很多现场调零。
2.3 UART接口到底特别在哪
ADS122U04IPWR把SPI换成UART,这件事很多人不理解。实际上在工业现场,UART比SPI实在。SPI需要至少四根线,而且时钟线在长距离传输时非常容易辐射和受扰。UART只有TX/RX两根线,加个光耦或数字隔离器,就能把ADC和MCU的电气地完全断开,地环路噪声直接被切断。
从软件角度讲,STM32F100ZE的USART外设是现成的,配置波特率和DMA就能收发,比模拟SPI时序省事。要注意的是,UART是异步协议,两边的波特率必须严格一致,最好都用外部晶振,别用MCU内部的RC振荡器,否则温度一变,时钟漂移,通信就会偶发错帧。ADS122U04IPWR的UART命令格式也不复杂,基本就是地址字节、命令字节、数据字节的组合,具体寄存器偏移以数据手册为准。搭建系统时可以先发一条复位命令,再读寄存器回读验证通路。
3. 硬件电路设计与实操:HVAC现场最怕走弯路的地方
3.1 PT100和热电偶的最小参考电路
我的最小系统一般这样搭:ADS122U04IPWR供电用3.3V,外部参考用精密电阻Rref接在REFP和REFN之间。电流源IDAC设置成500μA,一路流经RTD,另一路做三线制补偿。PT100按四线制接法,激励电流从RTD一端进,另一端回到地,测量线直接接ADC差分输入,这样导线电阻不参与计算。
具体元件上,Rref选1.5kΩ或2kΩ,低温漂。输入到ADC之间加一级RC低通,比如33Ω加1nF,截止频率大约4.8MHz?这个值其实不够。工程上我更常看到100Ω加1μF,截止频率1.6kHz,能把变频器PWM的高频干扰滤掉。但要注意RC不能太大,否则ADC内部的采样电容充不满,反而引入建立误差。所以实际取值要看数据手册输入模型,通常在数据手册推荐范围里选,别自己瞎改。
ADS122U04IPWR的AIN输入引脚不用时不要悬空,建议接到公共地,防止静电荷积累。另外,激励电流源必须始终有回路,否则会在芯片内部积累电压,导致寄存器配置异常。我开始时犯过这个错,传感器没接就上电配置,读数乱七八糟。
3.2 与STM32F100ZE的接口连接
接口电路本身很简单,关键是引脚映射别搞错。理论上ADS122U04IPWR的UART_TX要接STM32的RX,UART_RX要接STM32的TX。我习惯用USART1做调试,USART2接ADS122U04IPWR,这样调试和采集互不干扰。引脚分配可以参照芯片手册和STM32的AF复用表,具体连接如下:
| 信号 | ADS122U04IPWR | STM32F100ZE |
|---|---|---|
| 供电 | AVDD/DVDD 3.3V | 稳压器输出 |
| UART发送 | UART_TX | USART2_RX |
| UART接收 | UART_RX | USART2_TX |
| DRDY/INT(如有) | 状态输出 | EXTI中断输入 |
| 复位 | RESET | GPIO输出控制 |
这里有个细节:如果MCU和ADC距离很近,可以共用一个3.3V电源,但要加好去耦电容。如果ADC在传感器端,MCU在控制端,中间走长线,必须用光耦或数字隔离器。光耦那边要选速率够快的,UART波特率如果跑115200,光耦的传播延迟最好在几十纳秒级别。
3.3 PCB布局、接地与隔离,后面省一半时间
PCB布局上,第一原则是模拟地和数字地不要大面积混在一起。我习惯把ADS122U04IPWR、Rref、输入RC滤波和传感器接口放在同一块模拟区域,数字芯片放在另一侧,模拟地平面和数字地在电源处用磁珠或者0Ω电阻单点相连。不要在ADC底下走数字线,尤其是PWM信号和串口线,这些数字边沿会耦合到模拟输入。
电源去耦也别省。ADS122U04IPWR的AVDD引脚附近放0.1μF加2.2μF陶瓷电容,尽量靠近引脚。STM32F100ZE的电源脚按手册要求布置,所有去耦电容的地回到对应地平面。
隔离要放到系统层面考虑。HVAC控制柜里有变频器,变频器输出线是高电压、高di/dt的干扰源。如果ADC和传感器都在强电柜里,我的做法是:传感器线用屏蔽双绞线,屏蔽层单端接地;串口两侧加数字隔离,例如用ADuM1201或者国产兼容光耦;隔离后的ADC侧电源用单独的小功率DC-DC,比如B0505S,再接一个低噪声LDO。这样即使控制柜里有大电机,读数也基本不受影响。
4. 固件实现:读数不难,难的是每一步都稳
4.1 STM32F100ZE初始化USART和DMA
固件第一件事是初始化USART。要把STM32F100ZE的GPIO复用成USART功能,TX配置成推挽输出,RX配置成浮空输入。波特率我设115200,数据位8位,无校验,1位停止位。UART连接的是ADS122U04IPWR,两边波特率必须一致,而且时钟源要用外部晶振。
接着配置DMA接收中断。为什么不直接在主循环里读串口?因为ADS122U04IPWR的响应帧不是固定快到能当场读走的,如果主循环在忙别的,UART接收缓冲就会溢出。用DMA把数据搬到内存环形缓冲区,再在中断里解析帧,这样即使采集任务多了也不会丢包。STM32F100ZE的DMA模块配置不复杂,关键是内存缓冲区长度要设成帧长的整数倍,避免帧被拆断。
上电时还要做一次硬件复位。ADS122U04IPWR的RESET引脚先拉低再拉高,延时几毫秒等内部时钟稳定,然后通过UART发送复位命令。复位后最好回读寄存器确认芯片在线,这一步能提前暴露接线问题。
4.2 寄存器配置:PGA、IDAC和采样率的取舍
ADS122U04IPWR寄存器配置顺序一般是:先设置PGA增益和输入通道,再配置激励电流源和参考电压,最后设置数据速率和滤波器。我在PT100工程里常用的一组参数大致是这个意思:
- PGA增益:8倍
- 激励电流:500μA
- 参考电压:外部Rref
- 数据速率:20SPS
- 滤波器:同时抑制50Hz和60Hz
- 输入通道:开差分测量
写寄存器时不要相信默认值。默认增益可能是1,默认电流源可能是关闭,直接读数据会得到一堆无意义的值。我的做法是先读出所有寄存器,打印到串口,然后逐项修改,最后再回读一次,确认全部写进去。
PGA增益和激励电流要配套选。如果RTD阻值大,比如PT1000,就不要用1mA去激励,否则电压接近满量程会限幅。PT100用500μA比较合适,自热也小。如果测热电偶,通常不需要激励电流,而是把PGA增益设到64或128,因为热电偶信号只有几十微伏。
4.3 把AD码换算成温度:比例公式和线性化
数据读回来后是24位有符号数,但不能直接当温度。对比值测量来说,先拿到RTD比例,再乘以Rref,求得实际电阻。公式可以简化为:
- RTD电阻 = AD码比例系数 × Rref
比例系数哪里来?最简单的方法是在固件里保存一个“理想满量程码”,然后做一次软件校准。严格做法是把Rref两端的电压也通过ADC读进来,代码同一条链路,这样电流源的微小变化不会影响结果。我在项目里常用一个简化版:每次开机先读一次Rref通道,得到参考码,之后RTD电阻 = RTD码 / 参考码 × Rref。这个办法很实用。
拿到RTD电阻后,PT100线性化我用Callendar-Van Dusen公式。0℃以上:
- 温度t = (电阻 / 100 - 1) / A,再修正二次项
或者直接代入标准系数:A=3.9083×10⁻³,B=-5.775×10⁻⁷,C=-4.183×10⁻¹²。0℃以上解一元二次方程,0℃以下要解三次方程。程序中我用牛顿迭代法,迭代三次就能收敛到0.01℃以内。整个过程不复杂,但系数一定别写错,否则温度会偏得离谱。
4.4 校准流程:不是所有误差都能靠公式消除
公式只能解决理想情况,实际链路里还有基准电阻误差、PGA失调、ADC失调、导线电阻偏差等。所以产品出厂前最好做两点校准。
第一点是零点校准:把RTD换成精密100Ω电阻,读取AD码,记为offset。理想情况下100Ω应该对应某个码值,偏差就是零点误差。第二点是增益校准:换一个已知精密电阻,比如138.51Ω对应100℃,再计算增益系数。最后软件里对每次测量的电阻做:
- 修正电阻 = (实测电阻 - 零点偏移) × 增益修正系数
校准之后,我实测常温附近能到0.05℃以内的重复性。如果现场只允许做一次校准,我会选在系统实际工作温度附近的单一温度点做校准,再把数据表做平移,效果比乱做两点法好。
5. 工业与HVAC场景里的抗干扰和可靠性
5.1 变频器、压缩机、电磁阀的噪声怎么挡
HVAC的干扰源特别多。变频器输出侧是高电压、高频率的PWM跳变,电磁阀动作瞬间会产生几十伏的感性尖峰,继电器触点火花也能辐射宽带噪声。这些干扰如果进到模拟输入里,轻则末位数跳,重则温度读数来回飘好几度。
我总结的三道防线是:屏蔽、滤波、隔离。传感器线选屏蔽双绞线,屏蔽层在控制柜一侧接地,不两端都接地,避免形成地环路。ADC输入口前面加RC低通,把高频成分滤掉。串口加隔离,让模拟地和数字地彻底断开。做完这三步,绝大多数现场干扰都能解决。
软件里再补一刀:中值平均滤波。比如连续采5个点,去掉最大值最小值,剩下取平均,对付偶发尖峰特别有效。当然滤波会增加响应时间,HVAC系统温度变化本来就慢,几十毫秒延迟无所谓。
5.2 断线、短路检测不能省
现场PT100断线太常见了,接头氧化、线缆被老鼠咬、接线端子松动,都会导致断线。如果固件不做检测,断线后ADC输入悬空,读数可能跳到满量程或者某个奇怪值,然后控制器以为温度很高或很低,触发误动作。
ADS122U04IPWR本身没有专用的断线检测引脚,但可以用偏置电阻方案。在AI N差分输入两端分别加一个高阻值电阻,比如1MΩ,一端接到参考电压,一端接地。正常时RTD电阻只有100多欧姆,1MΩ偏置电阻对分压的影响小到可以忽略;一旦传感器断开,差分输入会被拉到接近满量程,软件判断“测量值超出合理范围”就报断线。短路检测则看读数是否接近零,结合传感器上限判断。
我建议固件里做三档状态:正常、断路、短路,通过状态寄存器上传给上位机。这样运维人员不用去现场拿万用表,直接在触摸屏上就能定位故障。
5.3 长期稳定性:自热、漂移和定期维护
PT100通电流必然自热。500μA激励在100Ω上只有0.025mW,放在水里或金属管里散热好,基本感觉不到。但如果传感器放在不流动的空气里,自热可能造成零点几度的偏大。想减小自热,可以降低激励电流到250μA,代价是信号变小,需要更高增益。实测下来,PT100自热影响远小于热电偶,正常选型不用太焦虑。
长期看,基准电阻会老化,PT100在高温下也会漂移。所以标定周期得看应用,HVAC一般一年校准一次,工业现场如果精度要求高,建议半年一次。每次校准后固件里的零点偏移和增益系数要能在线更新,别写死在Flash里,否则运维人员只能回厂刷程序。
6. 实测问题与排查技巧实录
6.1 读数跳字严重,先查这几个地方
如果现场出现温度读数乱跳,不要急着改软件滤波,先按下面这张表排查硬件。
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| 末位持续跳动 | 采样率太高 | 数据速率降到20SPS,打开内部50/60Hz抑制 |
| 读数明显偏大 | 基准电阻精度差 | 换0.1%精度、5ppm温漂的电阻 |
| 读数全满幅或全零 | 传感器断线/短路/接反 | 检查端子,确认RTD接线和激励回路 |
| 上电读数正常,压缩机一开就跳 | 变频器干扰进入模拟输入 | 加RC低通,屏蔽层单端接地,串口隔离 |
我遇到最多的是“调速风机一开,温度波动的像心电图”。最后发现ADC输入前只放了10nF电容,没有串电阻,高频干扰直接灌进采样电容。加上100Ω和1μF的RC后,读数立刻稳定下来。
6.2 UART偶发丢帧,不一定是波特率问题
丢帧分两种。一种是单片机能发命令但收不到完整响应,原因往往是时钟源不对。STM32F100ZE内部RC振荡器在全温度范围可能偏百分之几,导致波特率偏移,ADS122U04IPWR那边的采样点错位。解决办法是改用外部8MHz或16MHz晶振,并且把USART的波特率误差控制在1%以内。
另一种是逻辑混乱,比如状态机还没等到完整帧就超时,或者DMA缓冲区覆盖。我习惯在解析层加长度校验和状态位校验,任何一帧不合法就丢弃,不往外发错误数据。如果加了RS485,别忘了首尾终端电阻和A/B偏置电阻,否则总线空闲时电平不确定,丢帧会非常随机。
6.3 几个经验上的避坑记录
- 不要在传感器端子用普通排针,氧化后接触电阻漂移特别烦。HVAC产品里至少用镀金端子,最好用带锁扣的接线端子。
- 焊完板子先测Rref两端实际电压,再设ADC参考。我发现很多“精度差”的故障,其实就是Rref焊错阻值或者虚焊。
- PT100校准时别用冰水混合物,温度梯度太大。有条件就用干井炉或者电桥,没条件就用精密电阻箱,效率和精度都更好。
- 如果同时测多路温度,并把空气温度和水温放同一个接线盒里,要考虑发热器件靠近传感器导致的局部温度场变化。
- 所有传感器线尽量走单独线槽,远离动力线。实在避免不了就用屏蔽层或金属管。
这套ADS122U04IPWR加STM32F100ZE的测温方案,我前前后后在四个项目里用下来,最大的体会是:精度不仅仅取决于ADC是不是24位,更取决于整条链路。传感器接线、基准电阻、电源噪声、布线和固件校准,每一项都可能毁掉那0.1℃。如果你正在做工业或HVAC测温,建议先搭一个最小系统,用精密电阻箱当传感器,把链路调稳后再接现场传感器。这样排查问题集中度高,效率也最高。最后分享一个小技巧:调试时把ADC原始码和最终温度一起打印,问题定位比只看温度快得多。