☰
基于ADS122U04与STM32F439的工业级高精度温度测量方案
2026/11/5 1:04:38 网站建设 项目流程

1. 工业与HVAC温度测量项目的整体设计思路

工业现场和商用HVAC系统里的温度测量,跟我们在实验室用个DS18B20随便测测完全是两码事。工业场景对温度采集的要求集中在几个硬指标上:宽温区覆盖(-200℃到+850℃的PT100/PT1000是常态)、抗电磁干扰(变频器、接触器、大功率电机就在旁边)、长期稳定性(设备装上去可能五年不校准)、以及远距离传输能力(传感器离控制柜几十米很常见)。HVAC场景稍微温和一些,但同样面临长线缆、多点巡检、低功耗待机这些实际约束。

这个项目选用的核心器件是ADS122U04IPWR和STM32F439ZG。前者是TI的一款24位ΔΣ模数转换器,内置PGA、双匹配电流源、UART接口,专门为RTD、热电偶、热敏电阻这类小信号传感器设计;后者是ST的Cortex-M4旗舰型号,180MHz主频、带FPU、2MB Flash、256KB SRAM,跑复杂的温度线性化和多点滤波算法绰绰有余。两者搭配的逻辑很清晰:ADS122U04负责把微弱的RTD电阻变化转换成高精度数字量,STM32F439ZG负责算法处理、系统调度和通信上报。

为什么不用STM32自带的12位ADC直接测?这是很多人第一反应会问的问题。STM32F439的ADC分辨率是12位,参考电压3.3V的情况下,最小分辨电压是3.3V/4096≈0.8mV。PT100在0℃时是100Ω,在100℃时是138.51Ω,如果用1mA激励电流,100℃对应的电压变化只有38.5mV,12位ADC能分出的有效码值大约48个,折算到温度分辨率接近2℃。这个精度在工业场景里根本不够看。ADS122U04是24位,有效位数(ENOB)在PGA=1、20SPS时能到21位以上,同样的38.5mV变化能分出几十万个码值,温度分辨率轻松做到0.01℃级别。这就是为什么必须上外置高精度ADC的根本原因。

整个方案的信号链是这样的:PT100传感器 → 三线制或四线制接线 → ADS122U04的模拟输入 → 内部PGA放大 → 24位ΔΣ调制 → 数字滤波 → UART输出 → STM32F439ZG接收 → 温度换算算法 → 显示/上报/控制。激励电流由ADS122U04内部的双匹配电流源提供,省掉了外部恒流源电路,这对PCB面积和成本都是好事。

注意:ADS122U04的UART接口是2线制,TX和RX,波特率最高支持到115200bps。它跟STM32的USART外设可以直接对接,不需要额外的电平转换,因为两者都是3.3V逻辑电平。但如果你用的是5V的STM32型号,那就必须加电平转换芯片,否则会烧掉ADS122U04的IO口。

选型上还有一个细节值得说:ADS122U04IPWR的封装是TSSOP-16,PWR后缀表示的是卷带包装,适合批量生产。如果你只是打样验证,买几片散装的也行,但要注意焊接温度曲线,TSSOP-16的引脚间距是0.65mm,手工焊接需要一定的技巧,建议用热风枪配合助焊膏。

2. ADS122U04IPWR的核心细节与配置要点

2.1 内部结构拆解与关键寄存器

ADS122U04的内部结构可以分成几个模块来理解:输入多路复用器(MUX)、可编程增益放大器(PGA)、ΔΣ调制器、数字滤波器、内部振荡器、双匹配电流源、UART通信接口。每个模块都有对应的配置寄存器,上电后必须正确初始化才能正常工作。

寄存器一共4个,都是8位的:配置寄存器0(Config0)、配置寄存器1(Config1)、配置寄存器2(Config2)、配置寄存器3(Config3)。每个寄存器的每一位都有特定含义,写错一位就可能导致测量结果完全不对。

Config0控制输入多路复用器选择和增益设置。MUX[3:0]位决定哪个输入通道被连接到PGA,比如0000表示AIN0和AIN1作为差分输入,0011表示AIN2和AIN3作为差分输入,还有专门用于电流源测量的配置。GAIN[2:0]位设置PGA增益,从1到128共8档。测PT100的时候,如果激励电流是1mA,0℃时差分电压是100mV,100℃时是138.5mV,这个信号幅度用PGA=1就够了。但如果用100μA的激励电流来降低自热效应,信号幅度只有10mV到13.85mV,那就需要PGA=8或16来放大。

Config1控制数据速率、工作模式和转换模式。DR[2:0]位设置数据速率,从5SPS到2000SPS共8档。工业温度测量通常用20SPS就够了,因为温度变化本身很慢,而且低速率下数字滤波器的陷波频率更低,对50Hz/60Hz工频干扰的抑制更好。CM位设置转换模式,0是单次转换,1是连续转换。连续转换模式下,ADC会以设定的速率不断输出数据,STM32只需要读取即可。

Config2控制电流源、基准电压选择和IDAC路由。IDAC[2:0]位设置激励电流大小,从10μA到1500μA共8档。测PT100通常用100μA到500μA,太大自热效应明显,太小信噪比不够。VREF[1:0]位选择基准电压源,可以用内部2.048V基准,也可以用外部基准。内部基准的初始精度是±0.05%,温漂是5ppm/℃,对于大多数工业温度测量已经够用。如果要求更高精度,可以外接一个REF5025之类的精密基准。

Config3控制IDAC的电流输出引脚、基准旁路电容和温度传感器模式。I1MUX[2:0]和I2MUX[2:0]分别设置两个电流源的输出引脚。测三线制PT100的时候,两个电流源分别从RTD的两端注入,第三根线用于补偿引线电阻。这个配置是ADS122U04的一大亮点,省掉了外部匹配电路。

2.2 三线制与四线制RTD接法的取舍

PT100的接线方式直接决定了测量精度。两线制最简单,但引线电阻会直接叠加到测量结果里。假设引线是0.5mm²的铜线,每米电阻约0.035Ω,如果传感器离控制柜50米,来回就是100米,引线电阻3.5Ω。PT100在0℃时是100Ω,3.5Ω的误差对应约9℃的温度偏差。这显然不能接受。

三线制是工业上最常用的折中方案。它假设三根引线的电阻相同,通过两次测量来抵消引线电阻的影响。ADS122U04内部的双匹配电流源就是为这个场景设计的:IDAC1从AIN0流入,经过引线1到达RTD,再经过引线2从AIN1流出到IDAC2,引线3从RTD的另一端连接到AIN2用于测量。通过合理的配置,引线电阻在两次测量中相互抵消。三线制的残余误差主要来自三根引线电阻的不匹配,通常能控制在0.1Ω以内,对应0.25℃左右的误差。

四线制是精度最高的方案,完全消除了引线电阻的影响。两根线负责注入激励电流,另外两根线负责测量RTD两端的电压。因为测量线没有电流流过,所以引线电阻上不产生压降。四线制需要占用ADS122U04的四个输入引脚,适合对精度要求极高的场合,比如校准实验室或计量级应用。

实操心得:三线制接线时,三根引线的长度和线径必须完全一致,最好用同一根电缆里的三根芯线。如果现场已经布好了线但三根线的电阻不一致,可以在软件里做补偿,但补偿效果有限。我遇到过现场用不同批次电缆的情况,三根线电阻差了0.3Ω,温度偏差到了0.8℃,后来换了整根电缆才解决。

2.3 激励电流的选择与自热效应计算

激励电流的选择是一个权衡:电流越大,信号幅度越大,信噪比越好;但电流越大,RTD自身的发热越严重,自热效应带来的误差就越大。PT100的自热系数通常在0.2到0.5℃/mW之间,具体取决于封装和安装方式。空气中的自热系数比液体中大,因为散热条件差。

假设用1mA激励电流,PT100在100℃时的电阻是138.5Ω,功耗是I²R = (0.001)² × 138.5 = 0.1385mW。按0.3℃/mW的自热系数算,自热误差约0.04℃。这个可以接受。但如果用1.5mA,功耗变成0.31mW,自热误差约0.09℃,开始有点大了。如果用100μA,功耗只有0.0014mW,自热误差可以忽略,但信号幅度只有13.85mV,对ADC的噪声要求更高。

我的经验是:对于封装较大的PT100(比如铠装探头),用500μA到1mA没问题;对于薄膜式PT100或微型封装的,建议用100μA到200μA,牺牲一点信噪比换取更低的自热误差。ADS122U04在PGA=16、20SPS时的等效输入噪声大约是1.5μV RMS,100μA激励下13.85mV的信号对应约9200:1的信噪比,折算温度分辨率约0.01℃,完全够用。

3. STM32F439ZG的软件架构与温度换算实现

3.1 UART通信协议与数据帧解析

ADS122U04的UART接口工作方式比较特殊,它不是标准的异步串口,而是命令-响应模式。STM32发送命令字节,ADS122U04根据命令返回相应的数据。命令分为几类:读寄存器(RREG)、写寄存器(WREG)、开始转换(START)、停止转换(STOP)、读数据(RDATA)、复位(RESET)。

读寄存器的命令格式是:0x20 | (寄存器地址 << 2),后面跟一个字节表示要读几个寄存器。比如读Config0到Config3共4个寄存器,命令是0x20 | (0x00 << 2) = 0x20,然后跟0x03(表示读4个寄存器,因为0x03+1=4)。ADS122U04会返回4个字节的寄存器值。

写寄存器的命令格式是:0x40 | (寄存器地址 << 2),后面跟要写入的数据。比如写Config0,命令是0x40 | (0x00 << 2) = 0x40,然后跟Config0的值。

读数据的命令是0x10,ADS122U04返回3个字节的24位转换结果,MSB在前。STM32收到这3个字节后,需要拼成一个32位有符号整数。注意ADS122U04输出的是二进制补码格式,正负号的处理不能搞错。

// STM32 HAL库接收ADS122U04数据的示例 uint8_t rx_buf[3]; int32_t adc_code; HAL_UART_Receive(&huart2, rx_buf, 3, 100); adc_code = ((int32_t)rx_buf[0] << 16) | ((int32_t)rx_buf[1] << 8) | rx_buf[2]; // 处理符号扩展:24位补码转32位 if (adc_code & 0x00800000) { adc_code |= 0xFF000000; }

注意:ADS122U04的UART在连续转换模式下,如果STM32没有及时读取数据,新的转换结果会覆盖旧数据。所以要么用中断方式接收,要么确保轮询周期小于转换周期。20SPS对应50ms的转换周期,STM32有充足的时间处理。

3.2 PT100温度换算的算法选择

拿到ADC码值之后,下一步是换算成温度。这里有两种主流方法:查表法和公式法。

查表法是把PT100的电阻-温度对照表存在STM32的Flash里,用查表和线性插值的方式换算。优点是精度高、计算量小,缺点是占用Flash空间,而且只覆盖表里的温度范围。标准的PT100对照表从-200℃到+850℃,每1℃一个点,共1051个条目,每个条目用2字节存储电阻值(单位0.01Ω),总共约2KB Flash。STM32F439ZG有2MB Flash,这点空间完全不是问题。

公式法是用Callendar-Van Dusen方程直接计算。这个方程分两段:0℃以上用二次多项式,0℃以下用四次多项式。

0℃以上:R(t) = R0 × (1 + A×t + B×t²) 0℃以下:R(t) = R0 × (1 + A×t + B×t² + C×(t-100)×t³)

其中R0=100Ω,A=3.9083×10⁻³,B=-5.775×10⁻⁷,C=-4.183×10⁻¹²。

从电阻反推温度需要解方程,0℃以上可以直接用求根公式,0℃以下需要用迭代法。STM32F439ZG有FPU,跑这些计算毫无压力。

我个人的选择是:如果温度范围主要在0℃以上,用公式法就够了,代码简洁,精度也够。如果覆盖全温区,建议用查表法,因为0℃以下的四次方程迭代收敛有时候会出问题,而且查表法的精度是确定的。

3.3 数字滤波与工频干扰抑制

工业现场的电磁环境很恶劣,变频器、接触器、大功率电机都会产生强烈的工频干扰。ADS122U04的数字滤波器在20SPS时的-3dB带宽约5.3Hz,对50Hz和60Hz的抑制分别能达到-100dB和-120dB以上。但这要求ADC的转换速率和工频周期严格同步,否则抑制效果会打折扣。

更稳妥的做法是在STM32端再加一级数字滤波。最简单的是滑动平均滤波,取N个连续采样值的平均。N的选择要权衡响应速度和噪声抑制:N越大,噪声越小,但响应越慢。对于温度这种慢变量,N取16或32都行。

如果现场干扰特别严重,可以用中值滤波加滑动平均的组合。先取5个采样值,去掉最大和最小,剩下3个取平均,然后再做滑动平均。这样既能抑制脉冲干扰,又能平滑随机噪声。

#define FILTER_LEN 16 float temp_buffer[FILTER_LEN]; uint8_t buf_index = 0; float temp_sum = 0.0f; float filter_temperature(float new_temp) { temp_sum -= temp_buffer[buf_index]; temp_buffer[buf_index] = new_temp; temp_sum += new_temp; buf_index = (buf_index + 1) % FILTER_LEN; return temp_sum / FILTER_LEN; }

实操心得:滑动平均的初始阶段,缓冲区里全是0,会导致输出偏低。解决办法是上电后先连续采样FILTER_LEN次填满缓冲区,再开始正常输出。或者用一个标志位判断是否已经填满,没填满之前用实际采样次数做分母。

4. 常见问题与排查技巧实录

4.1 测量值跳变或噪声过大

这是最常见的投诉。可能的原因有几种:激励电流太大导致自热效应波动、引线接触不良、ADC配置错误、电源纹波太大。

排查步骤是这样的:先用万用表直接测量PT100的电阻,确认传感器本身没问题。然后把ADS122U04的配置寄存器读回来,逐位核对是否和预期一致。特别是GAIN位和DR位,写错的话测量结果会完全不对。接着用示波器看ADS122U04的模拟输入引脚,如果有明显的工频干扰或高频噪声,说明前端滤波不够。可以在模拟输入引脚旁边加RC低通滤波,截止频率设在1kHz左右。

电源纹波也是常见问题。ADS122U04的模拟电源和数字电源最好分开供电,模拟电源用LDO单独稳压,数字电源可以共用。如果共用开关电源,纹波会通过电源引脚耦合到ADC内部,导致测量值跳动。我遇到过用同一个DCDC给STM32和ADS122U04供电的情况,测量值跳了0.5℃,后来加了一个LC滤波器才压下去。

4.2 温度读数偏差固定值

如果测量值总是偏高或偏低一个固定值,通常是引线电阻补偿没做好,或者基准电压不准。

三线制接法下,如果三根引线电阻不匹配,会产生固定偏差。可以用精密电阻箱模拟PT100,在0℃和100℃两个点校准,算出偏差值,然后在软件里做线性补偿。

基准电压不准也会导致固定偏差。ADS122U04的内部基准初始精度是±0.05%,对应温度误差约0.13℃。如果要求更高,可以外接精密基准,比如REF5025的初始精度是±0.05%,温漂3ppm/℃,比内部基准好一个数量级。

4.3 UART通信失败或数据错位

ADS122U04的UART接口对时序有一定要求。如果STM32发送命令后没有及时读取响应,或者读取的字节数不对,就会导致数据错位。

最常见的错误是读寄存器时字节数搞错。比如读4个寄存器,命令里写的是0x03,但实际只读了3个字节,剩下的1个字节会留在ADS122U04的发送缓冲区里,下次通信时就会错位。解决办法是每次通信前先发一个复位命令(0x06),把ADS122U04的状态机复位,然后再发正式命令。

另一个坑是波特率不匹配。ADS122U04的UART波特率是固定的115200bps,不能配置。STM32的USART必须设置成115200、8位数据、无校验、1位停止位。如果STM32的时钟配置有问题,实际波特率偏离太大,通信就会失败。可以用示波器测量TX线上的波形,确认位宽是否准确。

4.4 常见问题速查表

现象可能原因排查方法解决方案
测量值跳变电源纹波大示波器看电源引脚加LC滤波或LDO
测量值跳变引线接触不良万用表测引线电阻重新接线或更换电缆
固定偏差引线电阻不匹配测量三根引线电阻软件补偿或更换电缆
固定偏差基准电压不准测量VREF引脚电压外接精密基准
通信失败波特率不匹配示波器测位宽重新配置USART
通信失败命令格式错误逻辑分析仪抓包核对命令字节
自热误差大激励电流太大计算RTD功耗降低激励电流
噪声大PGA增益不够检查Config0提高PGA增益

最后再分享一个小技巧:ADS122U04的PGA在增益大于1时,输入共模电压范围会缩小。如果RTD的共模电压接近电源轨,PGA会饱和,输出全是满量程码值。解决办法是把RTD的共模电压设置在电源电压的一半左右,比如1.65V。可以通过调整电流源的注入点和基准电压来实现。这个坑我在第一次调试的时候踩过,花了整整一个下午才找到原因。

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

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

立即咨询