☰
基于ADS122U04IPWR与STM32F765ZI的工业及HVAC温度测量系统设计
2026/11/5 5:03:47 网站建设 项目流程

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

1.1 为什么选择ADS122U04IPWR加STM32F765ZI这套组合

工业现场和HVAC系统里的温度测量,跟实验室里拿个万用表测室温完全是两码事。工业场景往往要求-40℃到125℃甚至更宽的范围,传感器可能离主控几米远,现场还有变频器、接触器、电机这些干扰源。HVAC场景虽然温度范围窄一些,但通道多、成本敏感、长期无人值守,对稳定性和免维护要求极高。

这套方案的核心思路是:用ADS122U04IPWR这颗24位ΔΣ ADC做前端采集,用STM32F765ZI做数据处理和系统控制。为什么这么搭?ADS122U04IPWR是四通道、24位、带PGA和激励电流源的ADC,内置2.048V基准,SPI接口,TSSOP-16封装。它最擅长的就是直接接RTD、热电偶、热敏电阻这些温度传感器,尤其是两线制或三线制RTD,因为它自带匹配的激励电流源,能有效抵消引线电阻带来的误差。

STM32F765ZI则是ST的Cortex-M7内核,216MHz主频,带双精度浮点单元,1MB Flash,512KB RAM,外设丰富。选它不是因为算力过剩,而是因为温度测量里要做的事情比想象中多:多通道轮询、数字滤波、非线性查表或多项式拟合、冷端补偿、故障诊断、通信协议栈,这些加起来对实时性和浮点运算都有要求。F765ZI的FPU做RTD的Callendar-Van Dusen方程求解,或者热电偶的多项式拟合,基本是几个周期的事,不用查表也能跑得飞快。

注意:ADS122U04IPWR的“U”代表它是超小型封装版本,焊接时风枪温度建议控制在300℃以内,时间不超过10秒,否则容易损伤内部基准。

1.2 系统架构与信号链拆解

整个信号链可以拆成四段:传感器、模拟前端、数字处理、通信与输出。

传感器层,工业上最常见的是PT100/PT1000铂电阻和K型热电偶。HVAC里则大量用NTC热敏电阻和铂电阻。PT100在0℃时100Ω,温度系数约0.385Ω/℃,线性度好但需要激励电流;热电偶输出的是μV级电压,需要冷端补偿和放大;NTC便宜但非线性严重,需要查表或Steinhart-Hart方程。

模拟前端就是ADS122U04IPWR。它的四路输入可以配置成两路差分,或者四路单端。内部PGA增益从1到128可调,配合2.048V基准,最小可分辨到2.048V/128/2^24 ≈ 0.95nV,这个分辨率对于热电偶的μV信号绰绰有余。激励电流源有两路,可以分别给两个RTD提供100μA到1.5mA的激励,电流大小通过寄存器配置。

数字处理层是STM32F765ZI。它通过SPI读ADS122U04IPWR的转换结果,然后做滤波、线性化、补偿。F765ZI的硬件SPI可以跑到几十MHz,但ADS122U04IPWR的SPI最高只支持到4MHz左右,所以实际配置在1-2MHz比较稳妥。

通信与输出层,工业上常用RS-485/Modbus,HVAC里则可能是BACnet、Modbus RTU或者直接4-20mA电流环。F765ZI的UART、CAN、以太网外设都能派上用场。

1.3 方案选型的几个关键取舍

有人会问,为什么不直接用STM32内部的ADC?答案很简单:STM32F765ZI的12位ADC,就算过采样也做不到24位有效分辨率,而且内部基准温漂大,PGA增益有限,根本没法直接接热电偶。ADS122U04IPWR的24位ΔΣ架构,配合内部基准和PGA,才是温度测量的正确打开方式。

那为什么不用ADS1248或者MAX31865?ADS1248是8通道24位,通道更多但价格更高,如果只需要2-4路温度,ADS122U04IPWR更划算。MAX31865是专为PT100设计的,集成度高但只支持RTD,灵活性不如ADS122U04IPWR。所以这套组合的定位是:中等通道数、多种传感器类型、需要一定灵活性的工业与HVAC温度测量。

2. 硬件设计细节与关键参数计算

2.1 ADS122U04IPWR外围电路设计要点

ADS122U04IPWR的模拟电源AVDD建议2.7V到5.5V,数字电源DVDD也是2.7V到5.5V。为了信噪比,AVDD最好用LDO单独供电,比如3.3V的低噪声LDO,跟数字电源分开走线,在芯片下方单点接地。

基准方面,虽然内部有2.048V基准,但如果你要测热电偶的μV信号,内部基准的温漂(典型5ppm/℃)会直接引入误差。更稳妥的做法是外接一颗REF5025或者ADR4525,温漂可以做到2ppm/℃以内。不过对于大多数HVAC应用,内部基准其实够用了,毕竟HVAC的温度精度要求通常在±0.5℃左右。

输入滤波是必须的。每个模拟输入脚前面加一个RC低通,R用10Ω到100Ω,C用100nF到1μF,截止频率设在几kHz到几十kHz。注意电阻不能太大,否则会跟PGA输入偏置电流产生误差。ADS122U04IPWR的输入偏置电流典型值只有几百pA,所以10kΩ以下的电阻问题都不大。

激励电流源的走线要对称。如果是三线制RTD,两根激励线要等长等宽,第三根补偿线也要尽量靠近。PCB上最好用地线包围模拟走线,减少漏电流。

实操心得:ADS122U04IPWR的DRDY引脚是开漏输出,必须接上拉电阻,通常10kΩ到DVDD。我试过忘记接上拉,结果SPI读出来全是0,排查了半天才发现是DRDY没拉高。

2.2 温度传感器接口与参数计算

PT100三线制接法是最常见的工业配置。假设用1mA激励电流,PT100在0℃时压降100mV,在100℃时138.5mV。ADS122U04IPWR的PGA设成8,基准2.048V,那么满量程输入是2.048V/8=256mV,100℃时的138.5mV正好在量程内。分辨率方面,24位ADC在PGA=8时,LSB=2.048V/(8×2^24)=15.26nV,对应PT100的0.00004℃,当然实际有效位数受噪声限制,能到18-20位就不错了。

K型热电偶的输出约41μV/℃。冷端在25℃时,热端100℃,温差75℃,输出约3.075mV。PGA设成128,满量程输入2.048V/128=16mV,3mV信号占约19%量程。LSB=2.048V/(128×2^24)=0.95nV,对应0.000023℃,同样实际有效位数会低一些。冷端补偿可以用ADS122U04IPWR的另一路输入接一个PT100或者LM35,也可以用STM32内部的温度传感器,但内部传感器精度只有±1.5℃,对于要求高的场合不够。

NTC热敏电阻通常10kΩ@25℃,B值3435。用激励电流源供电,或者用分压电阻。分压方式更简单:NTC和10kΩ精密电阻串联,接2.048V基准,中点接ADC输入。25℃时中点电压1.024V,PGA=1,正好在量程中央。NTC的非线性用Steinhart-Hart方程处理:1/T = A + B·ln(R) + C·(ln(R))^3,三个系数通过三个温度点校准得到。

2.3 STM32F765ZI与ADS122U04IPWR的SPI接口配置

SPI配置成模式1(CPOL=0,CPHA=1),时钟先降到1MHz调试,稳定后再升到4MHz。ADS122U04IPWR的SPI是标准4线:CS、SCLK、DIN、DOUT,DRDY单独一根线接STM32的EXTI或者普通GPIO轮询。

STM32F765ZI的SPI1在APB2上,时钟源108MHz,分频到4MHz就是27分频,实际用32分频得到3.375MHz,或者16分频得到6.75MHz再降。我一般用SPI_BAUDRATEPRESCALER_32,得到3.375MHz,实测很稳。

CS引脚用软件控制,每次读写前拉低,完成后拉高。ADS122U04IPWR的SPI时序要求CS下降沿到第一个SCLK上升沿至少50ns,STM32的GPIO翻转速度够快,不用额外延时。

DRDY用EXTI中断,下降沿触发。中断里置一个标志位,主循环里检测标志位再读数据。不要在中断里直接读SPI,因为SPI读24位数据需要时间,中断里做太长会影响其他中断响应。

// SPI初始化片段 hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; HAL_SPI_Init(&hspi1);

3. 固件实现与核心算法落地

3.1 ADS122U04IPWR寄存器配置与数据读取

ADS122U04IPWR有四个配置寄存器,通过SPI命令读写。上电后先发RESET命令(0x06),然后写配置寄存器。配置寄存器0设置多路复用器、增益、数据速率;寄存器1设置数据速率、模式、基准、滤波器;寄存器2设置激励电流、IDAC路由;寄存器3设置IDAC大小、DRDY模式等。

以PT100三线制为例,配置如下:MUX选AIN0和AIN1差分,增益8,数据速率20SPS,连续转换模式,内部基准,IDAC1和IDAC2都开,电流1mA,IDAC1走AIN0,IDAC2走AIN3(补偿线)。这样配置后,ADS122U04IPWR会自动连续转换,DRDY每50ms拉低一次。

读数据时,先拉低CS,发RDATA命令(0x10),然后读3个字节,拼成24位有符号数。注意ADS122U04IPWR输出是二进制补码,最高位是符号位。正输入时0x7FFFFF对应满量程,负输入时0x800000对应负满量程。

int32_t ADS122U04_ReadData(void) { uint8_t tx[4] = {0x10, 0x00, 0x00, 0x00}; uint8_t rx[4] = {0}; HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(&hspi1, tx, rx, 4, 100); HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); int32_t data = (rx[1] << 16) | (rx[2] << 8) | rx[3]; if (data & 0x800000) data |= 0xFF000000; // 符号扩展 return data; }

3.2 RTD温度计算的Callendar-Van Dusen方程实现

PT100的电阻-温度关系用Callendar-Van Dusen方程描述。0℃以上:R(T) = R0·(1 + A·T + B·T²),0℃以下还要加C项。A=3.9083e-3,B=-5.775e-7,C=-4.183e-12。反解温度时,0℃以上可以用二次方程求根,0℃以下需要迭代。

实际工程中,更常用的做法是分段线性查表加插值。把-200℃到850℃分成若干段,每段用线性插值,精度可以做到0.01℃以内。STM32F765ZI的Flash够大,存一张1000点的表完全没问题。

我一般用二次方程求根,因为F765ZI有FPU,算起来很快。0℃以上:T = (-A + sqrt(A² - 4B(1 - R/R0))) / (2B)。注意B是负数,所以判别式里是减4B,实际是加。算出来T是开尔文还是摄氏度取决于R0,R0=100Ω时T就是摄氏度。

float PT100_CalculateTemp(float resistance) { const float A = 3.9083e-3f; const float B = -5.775e-7f; const float R0 = 100.0f; float ratio = resistance / R0 - 1.0f; float discriminant = A * A - 4.0f * B * ratio; if (discriminant < 0) return -999.0f; // 故障 float temp = (-A + sqrtf(discriminant)) / (2.0f * B); return temp; }

3.3 热电偶冷端补偿与多项式拟合

K型热电偶的电压-温度关系是非线性的,NIST提供了多项式系数。0℃到1372℃用三段多项式,每段有各自的系数。冷端补偿的做法是:先测冷端温度T_cj,查表得到冷端对应的热电势V_cj,然后热端电压V_total = V_measured + V_cj,再用V_total查表得到热端温度T_hot。

STM32F765ZI做这个计算,用查表加线性插值最稳。NIST的系数表可以存成const数组,每段10-20个点,插值精度足够。冷端温度用ADS122U04IPWR的另一路接PT100或者LM35测得。

注意:热电偶的冷端补偿点一定要在接线端子处,不能离太远。我见过有人把冷端补偿放在主控板上,结果接线端子和主控板温差5℃,测出来误差就大了。

3.4 数字滤波与噪声抑制策略

ADS122U04IPWR内部已经有sinc滤波器,20SPS时抑制50Hz/60Hz工频干扰很好。但工业现场还有低频漂移和突发噪声,所以固件里再加一层滤波。

我常用的是滑动平均加中值滤波。滑动平均窗口取8到16个点,中值滤波取5个点。先中值再平均,能有效去掉脉冲干扰。F765ZI的RAM够大,开两个环形缓冲区就行。

如果对实时性要求高,可以用IIR低通,截止频率设1Hz左右。但IIR有相位延迟,温度测量一般不在乎,所以问题不大。

#define FILTER_WINDOW 16 float moving_average(float new_val) { static float buffer[FILTER_WINDOW] = {0}; static uint8_t index = 0; static float sum = 0; sum -= buffer[index]; buffer[index] = new_val; sum += new_val; index = (index + 1) % FILTER_WINDOW; return sum / FILTER_WINDOW; }

4. 常见问题排查与实战避坑指南

4.1 温度读数跳动大或漂移的排查思路

读数跳动大,先看电源。ADS122U04IPWR的AVDD纹波要小于1mVpp,用示波器交流耦合看,如果纹波大,换LDO或者加π型滤波。再看基准,内部基准虽然方便,但温漂和噪声比外部基准差,如果精度要求高,换外部基准。

如果读数缓慢漂移,多半是激励电流源的问题。IDAC的电流大小受温度影响,虽然ADS122U04IPWR的IDAC温漂典型50ppm/℃,但如果你用的激励电流太大,RTD自热会导致读数偏高。PT100的功耗要控制在1mW以内,1mA激励时功耗0.1mW,没问题;但如果你用1.5mA,功耗0.225mW,还是安全的。自热误差可以用交替极性激励来消除,ADS122U04IPWR支持IDAC电流方向切换,固件里定期翻转就行。

还有一种情况是PCB漏电流。助焊剂没洗干净,或者湿度大,都会导致高阻抗节点漏电。用异丙醇清洗PCB,再涂三防漆,基本能解决。

4.2 SPI通信失败的典型原因与修复

SPI读出来全是0或者全是0xFF,先查CS和DRDY。CS没拉低,或者DRDY没接上拉,都会导致读不到数据。用逻辑分析仪抓SPI波形,看SCLK、DIN、DOUT、CS的时序对不对。

如果时序对但数据不对,检查SPI模式。ADS122U04IPWR是模式1,CPOL=0,CPHA=1。STM32的SPI配置里,CLKPolarity设LOW,CLKPhase设2EDGE。我见过有人设成1EDGE,结果数据错位。

还有一种情况是SPI时钟太快。ADS122U04IPWR的SPI最高4MHz,但如果你走线长、有容性负载,实际能跑的速度会降。先降到1MHz试试,稳定了再往上加。

4.3 温度计算误差偏大的校准方法

如果测出来温度跟标准值差0.5℃以上,先查传感器本身。PT100用标准电阻箱模拟,看读数对不对。如果传感器没问题,查基准电压。用六位半万用表测ADS122U04IPWR的VREF引脚,看是不是2.048V。内部基准的初始精度有±0.1%,加上温漂,误差可能到0.2%。

校准分两点校准和三点校准。两点校准用0℃冰水混合物和100℃沸水,分别记录ADC读数,然后线性修正。三点校准再加一个中间点,比如50℃,用二次修正。工业上通常用两点校准就够了,HVAC里甚至不校准,因为精度要求不高。

实操心得:冰水混合物要加冰块搅拌,等温度稳定在0℃再测。沸水要看当地大气压,海拔高的地方沸点不到100℃,查一下当地沸点再校准。

4.4 常见问题速查表

现象可能原因排查方法解决措施
读数全0CS未拉低/DRDY未上拉逻辑分析仪抓SPI检查GPIO配置,加上拉电阻
读数跳动大电源纹波大/基准噪声示波器看AVDD换LDO,加滤波电容
读数缓慢漂移激励电流自热/PCB漏电测RTD功耗,清洗PCB降低激励电流,涂三防漆
温度误差大基准不准/传感器老化万用表测VREF,电阻箱模拟两点校准,更换传感器
SPI数据错位SPI模式不对/时钟太快逻辑分析仪看时序改模式1,降时钟到1MHz
热电偶读数负偏冷端补偿位置不对测冷端和接线端子温差冷端补偿靠近接线端子

5. 系统集成与现场部署经验

5.1 多通道温度采集的轮询策略

ADS122U04IPWR只有四路输入,如果系统需要测8路或16路温度,就得用多片ADC或者外部多路复用器。多片ADC的方案更简单,每片ADS122U04IPWR接2路差分RTD,4片就是8路。STM32F765ZI有多个SPI接口,可以并行控制多片,也可以共用SPI用不同CS片选。

轮询策略上,如果每片ADC都配成连续转换模式,DRDY会各自独立拉低。STM32用多个EXTI引脚接DRDY,中断里置不同标志位。主循环依次处理,读数据、算温度、存结果。如果ADC数量多,可以用定时器触发转换,STM32发START命令,然后等DRDY,这样时序更可控。

HVAC里通道多但采样率要求低,1秒轮询一遍就够了。工业上有些场合要求100ms以内,那就得用连续转换模式,DRDY中断驱动。

5.2 工业现场的抗干扰与隔离设计

工业现场干扰大,ADS122U04IPWR的模拟部分和STM32的数字部分最好隔离。SPI信号用数字隔离器,比如ADuM3151或者ISO7741,电源用隔离DC-DC。这样即使现场有共模电压,也不会损坏主控。

模拟输入前端加TVS管和共模电感,防止浪涌和共模干扰。RTD的引线用屏蔽双绞线,屏蔽层单点接地。热电偶用补偿导线,极性不能接反。

注意:隔离器的电源也要隔离,不能一边用非隔离电源一边用隔离电源,否则隔离失效。我见过有人SPI隔离了但电源没隔离,结果还是烧了ADC。

5.3 低功耗设计与HVAC长期运行考量

HVAC系统通常24小时运行,功耗不是首要考虑,但长期稳定性很重要。ADS122U04IPWR有单次转换模式,不转换时功耗很低。如果系统用电池供电,可以让STM32定时唤醒,发START命令,等转换完成读数据,然后继续休眠。

长期运行还要考虑传感器老化。PT100用久了会漂移,每年校准一次比较稳妥。NTC的热敏电阻长期高温下阻值会变化,HVAC里如果测的是水温,问题不大;如果测的是排气温度,就要选耐高温的NTC。

固件里加看门狗和故障检测。如果ADC读数超范围,或者SPI通信连续失败,就报故障并重启。STM32F765ZI有独立看门狗和窗口看门狗,用独立看门狗定时喂狗就行。

5.4 从原型到产品的调试记录

我最近做的一个HVAC项目,用ADS122U04IPWR加STM32F765ZI测4路水温,PT100三线制,精度要求±0.3℃。原型阶段读数跳动0.1℃,后来发现是激励电流走线不对称,重新布线后跳动降到0.02℃。校准用两点校准,0℃和50℃,校准后误差在±0.1℃以内。

现场部署时遇到RS-485通信偶尔丢包,查了半天是波特率太高,115200在长距离下不稳定,降到9600就好了。还有一次是电源纹波导致读数漂移,换了LDO加了大电容,问题解决。

这个项目让我印象最深的是,ADS122U04IPWR的配置寄存器一定要仔细看数据手册,尤其是IDAC的路由,配错了要么没电流要么电流走错引脚。我一开始把IDAC2配到AIN2,结果补偿线没电流,三线制变成了两线制,误差大了好几度。

最后分享一个小技巧:ADS122U04IPWR的DRDY引脚在连续转换模式下会周期性拉低,如果你用轮询而不是中断,一定要在DRDY拉低后尽快读数据,否则下一次转换开始后数据会更新,你读到的可能是新旧混合的数据。我一般用中断,中断里置标志,主循环尽快处理,这样最稳。

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

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

立即咨询