去年我在整理一条暖通空调控制器的产线时,碰到一个挺折腾的需求:冷冻水管水温要求在0到100℃范围内误差不超过±0.2℃,传感器还要拉到现场30米以外。原方案用普通模拟量采集板,不是被导线压降坑,就是被变频器的工频干扰折磨。后来我把前端采集整体重做了一遍,核心就是TI的ADS122U04IPWR这颗24位Delta-Sigma ADC,搭配STM32F302VC做主控,顺便把温度换算、标定流程、现场排错一整套经验都攒了下来。这篇文章就把这套系统的完整思路写出来,给同样在做工业和HVAC测温的同行一个可参考的方案。
这套组合说简单也简单,说麻烦也麻烦。ADS122U04IPWR和STM32F302VC都不是特别新的器件,但把它们配合好,覆盖从传感器到控制器再到上位机的整条链路,里面有不少文档上不会明说的细节。如果你正准备设计类似的温度采集板,或者已经在用但遇到了读数不稳、误差超差、通信偶发丢数据这类问题,这篇文章应该能帮你省下不少调试时间。
1. 从"为什么选这两个芯片"说起:需求拆解与选型逻辑
1.1 先搞清楚测量对象:HVAC与工业测温的差异
很多人一上来就挑ADC,这不对。选型的第一件事是弄清楚被测对象到底要求什么精度、什么量程、什么环境。
HVAC领域的温度测量,舒适性空调回路通常做到±1℃就够了,但恒温恒湿工艺性空调、冷冻水供回水温差测量、变风量系统的风温补偿,要求往往到±0.2℃甚至更苛刻。这几个场景的共性问题是:传感器距离控制器远,现场有压缩机、变频器、电动阀这些强干扰源,线缆还可能和动力电缆并行走线。工业场景则更宽泛,从-50℃的冷库到几百摄氏度的工艺管道,RTD和热电偶都可能用,24V供电环境、恶劣电磁环境是常态。
我把需求和场景梳理成了一张表,选型时对着看就好:
| 需求维度 | HVAC典型场景 | 工业典型场景 |
|---|---|---|
| 测温范围 | 0~50℃(水管/风管),-40~60℃(室外) | -50℃~850℃(RTD全量程) |
| 典型精度 | ±0.2℃~±1℃ | ±0.1℃~±0.5℃ |
| 传输距离 | 10~50m | 可能上百米 |
| 干扰源 | 变频器、压缩机、开关电源 | 电机、接触器、电磁阀 |
| 通道数 | 每控制器4~8路常见 | 视系统规模而定 |
从这个表能看出来,不管是HVAC还是工业,光一个"高精度"不够,还得能长线传输、抗干扰。这就是选型的主线。
1.2 ADS122U04:一颗带UART口的24位Delta-Sigma ADC
ADS122U04IPWR是一颗24位Delta-Sigma ADC,片内集成了可编程增益放大器PGA、两个激励电流源IDAC、内部电压基准,还带50/60Hz工频滤波。它是四通道器件,可以配置成差分或单端输入,VQFN封装,工作温度范围-40℃~125℃。PWR后缀说明是卷带包装形式,量产的都知道,这个细节很容易搞错。
这颗器件最有意思的是它的接口:UART。ADC带UART接口,这在选型时是很大的优势。为什么这么说?传统ADC大多用SPI或I2C,SPI在长距离传输时时钟线会带来信号完整性问题,I2C抗干扰能力和速度又有限。UART协议本身成熟、线少,很适合传感器板与主控板分离的结构。不过要提醒一句:ADS122U04的UART是芯片自定义的二进制半双工指令-响应协议,不是PC上调试用的标准ASCII串口。刚开始容易被名字带偏,实际调试时按照数据手册的通信章节来写驱动就行。
选这颗芯片还看中了它对传感器前端的高度集成。测温系统最麻烦的激励电流源、可编程增益、基准源,它全给你放进一个芯片里了。外部要加的料很少,PCB面积和BOM成本都能压下来。如果不用这种高集成度方案,用分离运放加24位ADC再加精密基准,布线难度和调试周期会成倍增加。
1.3 STM32F302VC:不只提供一个CPU那么简单
STM32F302VC是ST的Cortex-M4内核MCU,主频72MHz,带FPU,100脚封装,256KB Flash。在F3系列里定位是"混合信号"控制芯片,内部集成的高速ADC、DAC、比较器、运放不是摆设,但在这套系统里,我更多是看中它作为HVAC整机主控的能力。
温度采集只是整个控制器的一块功能。HVAC控制器通常还要管压缩机变频控制、风机调速、电磁阀开关、人机交互和RS485通信。STM32F302VC的定时器资源丰富,带死区生成的互补PWM正好驱动电机,CAN和UART等接口也能覆盖现场总线需求。选它意味着温度前端和电机控制可以在同一颗芯片上共存,不用为了测温专门挂一颗低端MCU,再把数据从一个板子搬到另一个板子。
至于FPU,这个也实际有用。温度换算要查表、要算多项式,PID控制也是高频执行,浮点运算指令在F302上能一条搞定,用M0之类没有FPU的内核,光做浮点乘法就得软件模拟,代码写起来复杂,跑起来也慢。所以从整机角度看,F302不是"大材小用",而是"刚好够用还留了余量"。
2. 硬件链路搭建:RTD、激励电流与模拟前端的完整思路
2.1 PT100还是PT1000?传感器选型决定系统下限
传感器是整条链路的源头,它定死了系统的天花板。PT100和PT1000是同一种铂电阻材料,温阻特性一样,只是0℃标称电阻不同:PT100是100Ω,PT1000是1000Ω。
PT100的好处是传感器和探头行业存量巨大,四线制PT100在工业高精度测量里是标配。缺点是电阻值小,导线电阻的影响相对更大,需要三线制或四线制补偿才能做高精度。PT1000的灵敏度是PT100的10倍,导线电阻影响占比小得多,但探头的成本通常会高一些,而且在工业现场可替换性不如PT100普及。
在这套系统里,ADS122U04片内自带激励电流源,所以我的建议是:HVAC场景优先考虑PT1000,配250μA到500μA的激励电流,这样自热小、导线压降影响相对低;工业场景看现场习惯,如果客户维修体系都是PT100,就老老实实做三线制PT100,配合片内电流源做补偿。
这里有个很关键的底层参数:激励电流的选择。激励电流越大,RTD上的压降越大,ADC信噪比越高,但自热效应也越强。PT100在100℃时138.5Ω,用1mA激励,自热功率是0.14mW,这在普通探头里基本可忽略,但如果是薄膜型RTD贴在小散热片上,可能就明显偏高。我通常控制在0.25mA到0.5mA之间,既保证信号幅度够,又不会制造额外的温度误差。
2.2 三线制接法与导线电阻的数学抵消
说个算数题:如果只用两根线接PT100,导线电阻直接和RTD电阻串联。假设现场走线单根10Ω,两根就是20Ω,以PT100在0℃时100Ω为例,测量电阻变成120Ω,按0.385Ω/℃折算,误差高达52℃。这就是为什么二线制做不了高精度测温。
三线制把导线电阻的影响抵消掉,核心思路是:让两个匹配的激励电流源分别流过两根导线,用差分测量把导线压降减掉。你可以这样理解:一根导线从电流源到RTD,RTD上产生压降I×R;另有两根导线从RTD两根引出线分别到ADC的两个差分输入端,其中一路被同样的电流源的第二个电流驱动。当两路导线电阻相等、两个电流源匹配时,导线电阻在两个输入端的压降方向相反,在差分信号里正好相消。数学上这就是I×r1减去I×r2,匹配好的情况下结果趋近于零。
ADS122U04的IDAC1和IDAC2可以提供成对匹配的电流源,这正是给它配三线制PT100准备的。硬件接法并不复杂:RTD一端接IDAC1和一路激励,RTD另一端分出两根线,分别接到AINP和AINN,同时让IDAC2接入AINN这一路的导线上。具体引脚分配可以参考数据手册的三线制RTD典型电路,照着接就不会错。
如果精度要求再上一个台阶,比如实验室级或工业校验仪,就得上四线制:两根线给RTD送激励电流,另外两根线只做电压侦测,电压线上几乎没有电流,所以导线电阻完全不产生压降误差。代价是多一根线,接线端子也多一路。
2.3 电源、基准与UART电平匹配
ADS122U04的模拟电源要干净,这点不用我多说。实际设计时我给AVDD做了两级滤波:一级磁珠加10μF钽电容,二级是0.1μF陶瓷电容紧贴引脚。数字电源和模拟电源从同一个LDO出来之后分路走,在芯片处单点汇合,避免数字开关噪声直接耦合进模拟前端。
更聪明的做法是比率测量。ADS122U04的激励电流源和内部基准电压都跟随模拟电源变化,只要电源的短期漂移在合理范围,激励电流和基准电压的相对关系保持稳定,ADC输出码就不会跟着电源波动走。这就等于把电源纹波的影响自动抵消了一大部分。这也是为什么我强烈建议使用内部基准而不是外挂精密基准:外挂基准精度虽高,但激励电流源和它不同源,电源变化照样通过电流源引入误差,反而破坏了比率测量的优势。
UART电平这块是个容易踩的坑。ADS122U04的IO供电范围和模拟供电范围不完全一样,要和STM32F302VC的3.3V IO对接。用万用表确认双方的电平范围兼容,如果不匹配,中间加电平转换芯片。工业板卡上常见用5V给ADS122U04供电、3.3V MCU的情况,这时候一定要核实引脚电平,不能想当然直接连。
3. 固件侧实现:UART命令协议与寄存器配置的细节
3.1 认识ADS122U04的命令-响应框架
ADS122U04的通信看着像UART,但它的帧结构是芯片自定义的二进制半双工协议。主机通过一条数据线发指令,芯片在同一个通信周期内返回状态字节和数据。所有操作都由主机发起,从机不会主动上报。这意味着你想读数据,就得周期性地给芯片发读命令,它才会把最新结果吐出来。
这个框架下,最核心的几条命令包括:
- 写寄存器WREG:配置寄存器0到寄存器4
- 读寄存器RREG:回读当前配置,调试时非常有用
- 启动转换START:触发一次或连续转换
- 读数据RDATA:读取最新转换结果,返回1个状态字节加3个数据字节
开发时我会先把RREG命令跑通,配置完寄存器后回读一遍,确认写入值和预期一致再继续调数据。这一步能省掉大量"配置半天不知道写没写进去"的排查时间。
3.2 五个寄存器的关键位:别被数据手册吓到
ADS122U04的寄存器从00到04,一共五个。我实际调试时最关心的位就几处:
寄存器0主要配置输入多路复用器和PGA增益。三线制PT100场景,我把增益设成8倍。为什么是8倍?算一下:0℃时PT100压降0.1V左右(250μA×100Ω),100℃时0.138V。PGA=8时,满量程范围约±0.25V,信号占满量程约55%,这是在分辨率和裕量之间的平衡。增益太小浪费24位分辨率,增益太大信号接近满量程又怕有意外过冲。
寄存器2配两个IDAC电流源的大小和方向。选择250μA或500μA,具体值取决于传感器类型和自热预算。
寄存器3配数据速率和滤波器模式。这里要特别提50/60Hz工频抑制:如果启用FIR滤波器的50Hz抑制模式,数据速率会落在50Hz的整数分频上,现场抗工频干扰效果立竿见影。HVAC现场变频器一堆,这个配置我建议从一开始就打开。
给一段示意性的STM32侧配置代码框架:
// 伪代码框架,具体命令码和位定义以数据手册为准 uint8_t config[5] = {0}; config[0] = 0x06; // MUX配置为AINP/AINN差分,PGA=8 config[2] = 0x00; // IDAC电流源配置为250uA config[3] = 0x02; // 数据速率+50Hz工频抑制模式 ads122_write_reg(0x00, config, 5); // 一次性写入全部寄存器 ads122_read_reg(0x00, config, 5); // 回读验证 ads122_send_command(START); // 启动转换很多人照着参考例程抄寄存器配置,抄完发现读数不对,最后定位到是某个保留位没配好。所以我强烈建议把数据手册最后一页的寄存器表打印出来,一行一行对着核对,别嫌麻烦。
3.3 STM32侧读取流程:定时触发与DMA
STM32F302VC这边我采用定时器周期触发加UART DMA接收的方式。温度采集不需要连续不停地读,按控制周期来就行。比如PID控制周期是100ms,就让定时器每100ms触发一次读数据命令,DMA把返回的4字节(状态+数据)收到缓冲区,然后在主循环里解析。
这么做的好处有三点:一是CPU不用忙于等待UART收发,二是保证采样间隔均匀,三是DMA在后台搬运数据不占用中断处理时间。对于F302这种内核,哪怕同时挂4~8个通道的ADS122U04,处理起来也毫无压力。
解析返回数据时要小心符号扩展。24位ADC输出是二进制补码,如果直接用uint32_t存数据再当float算,正数没问题,负温度直接就错了。我在第一次调试负温时就栽在这上面,最后是加了一句有符号扩展的宏才修复。这个细节代码审查时一定要有人盯。
4. 从原始码到温度:查表、公式与标定的取舍
4.1 查表插值:最稳妥的工程做法
拿到ADC原始码之后,第一步把它换算成电压:
float rtd_voltage = ((int32_t)raw_code * vref) / (8388608.0f * pga_gain);电压除以激励电流得到电阻,接下来就到了从电阻到温度这一步。查表插值是工业界最常用的做法。标准铂电阻的温度-阻值表到处都能下载,把它作为const数组存进Flash,查表时先二分法定位区间,再做线性插值。因为PT100在-50℃到200℃之间的阻值-温度曲线非常接近线性,线性插值在分区足够细的情况下误差可以忽略。
查表法最大的优点是可追溯。审核时拿标准表一查就知道算法对不对,不用解释系数从哪来。缺点是表格占存储,不过PT100表细分成0.1℃间隔也就几千个点,F302的Flash完全放得下。
4.2 Callendar-Van Dusen公式:适合曲线拟合
如果不想存表,可以用Callendar-Van Dusen方程按需计算。PT100在0℃以上:
R = R0 × (1 + A×t + B×t²)
0℃以下多一项:
R = R0 × [1 + A×t + B×t² + C×(t-100)×t³]
其中A=3.9083e-3,B=-5.7750e-7,C=-4.1830e-12。这个公式用起来省Flash,程序也简单,但它是从电阻反推温度还是从温度正推电阻?通常工程上更方便的是存一张精简表,然后按CVD公式在表节点之间插值,既保证全量程精度,又不需要存超大数组。
F302带FPU,算这个公式几乎不花时间。有同事问我,为什么不用牛顿迭代反解CVD方程?我的回答是:查表插值的误差已经足够小,迭代求解属于给自己找活干。除非你要在极宽温度范围内做无节点连续计算,否则没必要。
4.3 系统标定:为什么说标定比算法更重要
算法再准,也救不了系统的增益误差和偏移误差。ADC本身的增益误差、内部基准的初始精度、电阻的容差、以及PCB上的各种微小失调,叠加在一起可能让最终误差轻松超出0.5℃。这时候唯一的办法是标定。
工程上最实用的两点标定:在量程低端和高端各选一个标准点,多数温度控制器用0℃和100℃。0℃可以用冰水混合物(标准大气压下冰水共存),100℃用沸水,但沸水受海拔影响,工业上更可靠的是精密电阻箱直接模拟标准电阻值。
标定的目标就是把系统简化成一条直线:真实温度等于读数温度乘以增益修正再加偏移修正。测出两个标准点的读数,就能算出修正系数。这个思想虽然朴素,但非常有效,我在量产工厂里见过的绝大多数高精度温度板,靠的都是这一招。
5. 实测数据与误差拆解:24位不代表0.001℃
5.1 实测结果:标准电阻箱和真实传感器的表现
在实验室用精密电阻箱模拟PT100,分别设置在几个标准电阻值上,记录系统换算出的温度,得到下面这组数据:
| 标准电阻(Ω) | 理论温度(℃) | 实测温度(℃) | 误差(℃) |
|---|---|---|---|
| 100.00 | 0.00 | 0.03 | +0.03 |
| 119.40 | 50.00 | 49.96 | -0.04 |
| 138.51 | 100.00 | 100.12 | +0.12 |
| 157.33 | 150.00 | 150.08 | +0.08 |
这是在未做精细校准、仅靠芯片默认配置加两点标定之后的水平。可以看到误差都在±0.15℃以内,对HVAC应用已经绰绰有余。如果做更细的多点标定,误差能压到±0.05℃上下,但再往下就受限于标准电阻箱本身的精度了。
真实传感器测试比电阻箱复杂得多。同一个PT100探头在布线、安装方式不同时,读数会差出不少,尤其是探头插在套管里和直接浸没在液体里,热传导路径不一样,动态响应和稳态误差都会有差异。所以实测时别只看实验室数据,一定要到现场装上去摸一遍真实偏差。
5.2 噪声来源:电源、工频、自热与导线
24位理论分辨率听起来吓人,但实际有效分辨率往往只有20位左右。这很正常,Delta-Sigma ADC的ENOB本来就受数据速率和滤波器配置影响,速率越低噪声越低。我在20SPS、50Hz滤波模式下实测,输出码的低位抖动通常只有几个LSB,折算到温度约0.01℃级别,这对目标是0.2℃的系统来说完全说得过去。
真正能把精度啃掉的噪声源,按我的经验排序是:电源纹波通过激励电流引入的误差、工频共模干扰、RTD自热、以及连接器热电动势。电源纹波这一项在比率测量下已经抵消大半,剩下的主要靠去耦电容和PCB布局。工频干扰靠芯片的FIR滤波器解决,但前提是你确实启用了50Hz抑制模式。RTD自热则需要你控制激励电流,前面已经说过。
还有一个容易被忽略的:连接器的热电动势。不同金属接触点之间如果有温差,会产生微伏级电势,这个量级在普通应用里无所谓,但在0.1℃级别的系统里就不能忽视。用铜鼻子压接、尽量减少不同金属的过渡连接次数,这是免费的精度提升。
5.3 一个完整的两点校准流程
我把自己每次调试都用的流程记在这里,照着做就行:
- 用精密电阻箱分别模拟0℃和100℃对应的标准电阻值,记录原始ADC码
- 根据两个点算出偏移修正和增益修正系数
- 把修正系数写进F302的Flash参数区,确保掉电不丢失
- 用第三个电阻值如50℃对应的119.4Ω做验证,确认误差在范围内
- 重复加电测试,验证标定参数在冷启动后仍然生效
这套流程最快十分钟能走完。量产时把它自动化,用夹具自动切换电阻箱、自动读数据、自动算系数、自动烧录,效率会更高。
6. 现场调试排查实录:三线反接、工频干扰与掉字节
6.1 三线制接反后的症状与判断
三线制RTD的接线是有讲究的,两根进ADC的线必须从RTD的同一端引出来。我调试时有一次接反了,现象特别隐蔽:室温下读数正常,但用手去摸传感器延长线时读数会明显变化,而且变化方向和实际温度变化对不上。
排查思路是这样:先断开激励电流源,把传感器那边用短接线模拟,再分段量线序。最终发现是把AINP和AINN两边对应导线接反了,导致两路导线电阻匹配关系被破坏,补偿算法失效。所以配线时一定要用万用表逐一确认导线两端的通断关系,别想当然地按颜色接。
我的建议是:接线图打印出来贴在调试工位上,每一根线两端都做标识。这种低级错误往往最容易消耗调试时间。
6.2 诡异漂流的真正元凶:工频干扰
还有一次更磨人:读数稳定一段时间后突然整体偏移,偏移幅度大概0.3℃左右,过几秒又自己回来了。刚开始怀疑是传感器坏了,换一个新的还是这样。后来用示波器挂在ADC输入端看波形,发现共模电压在工频周期上波动,幅度不算大但恰好落在ADC的输入范围内。
原因清楚了:现场有一台大功率变频器启动时,地环路把50Hz干扰耦合进了模拟测量回路,而芯片配置里我一开始没启用工频抑制模式。把寄存器3切到50Hz滤波模式,并且改用屏蔽双绞线从传感器引线,问题当场消失。
这里有个教训:HVAC和工业现场环境复杂,仪器的抗干扰配置应该从设计一开始就默认打开,等出问题再补配置,调试时间成本就上去了。
6.3 UART通信偶发掉数据:电平与时序的双重排查
掉字节这个问题在长线通信里很常见。ADS122U04和STM32之间的UART线如果走线超过0.5米,又没有做电平整形,偶发丢帧不可避免。我最早遇到的现象是读数每隔几分钟跳一次零值,后来定位到是主机读数据的时序超过了从机的响应窗口,导致读取命令丢失或返回不完整。
UART这类协议最核心的是时序。主机发完命令后,要给从机足够的响应时间,不能刚发完就立刻去读接收缓冲区。同时,长线需要降低通信速率,并在接收端做超时重试机制。
我的排查链路是:先用示波器同时抓发送线和接收线的波形,确认电平幅值和毛刺;然后确认每条命令之间的时间间隔;最后在固件里加超时重发,连续三次无响应就上报通信故障。这三步走完,掉字节的问题基本绝迹。
7. 把原型变成产品:布局、测试与量产建议
7.1 PCB布局与电源设计要点
原理图能在几天内画好,但PCB布局的好坏直接决定现场能不能稳定工作。模拟信号路径尽量短而粗,让RTD的差分信号线走紧密的差分对,并且避开继电器、变压器这类强磁元件。模拟地单独画一块,通过一个焊点和数字地连接,连接点放在ADC芯片下面最理想。
电源树要理清楚:STM32F302VC的数字电源和模拟电源分路,ADS122U04的AVDD要有独立滤波。我见过很多板子把所有电源都从一个3.3V扇出去,结果ADC参考电压和MCU的IO翻转噪声互相串扰,测量精度直接掉一个量级。
7.2 量产逐板标定方案
原型能跑起来之后,要考虑的是几百上千块板子怎么保证同一精度。手工标定不可行,效率太低。量产标定夹具是这么做的:单片机通过UART接收PC指令,PC控制一个高精度电阻切换板,自动向被测板的每个通道注入标准电阻,然后读取每块板子计算出的标定系数并写回Flash。
这样做一套夹具的成本不高,但能把原来每块板几分钟的调试工作压缩到几十秒,而且标定记录自动归档,出问题可以追溯到每一块板子。温度测量产品到了量产阶段,拼的不是谁的ADC芯片更贵,而是谁的标定流程更高效、更规范。
7.3 我个人的经验小结
回看这个项目,ADS122U04IPWR和STM32F302VC这套组合给我最大的感受是:高精度测温的难点并不在芯片本身,而是整条链路从传感器、激励、基准、通信到软件标定的系统性设计。一颗带激励和滤波的高集成度ADC能减少很多硬件层面的麻烦,但真正决定精度的还是你对误差来源的理解和对标定流程的执行。
最后分享一个实操习惯:每次调试前把精度预算表列出来,从传感器允许误差、ADC量化噪声、基准漂移、导线电阻、自热效应到标定残余误差,一项项估算分配。有了这张表,遇到问题能快速定位该查哪里,而不是凭感觉换器件、改参数。这套方法论在几乎所有的模拟测量项目里都通用。
如果你的项目和我的场景相似,也在为HVAC或工业测温折腾,建议优先从误差预算表和传感器接法入手验证,再去抠固件和算法细节。方向对了,后面每一步都踏实。