
1. 工业与HVAC温度测量方案的整体设计思路工业现场和HVAC系统里的温度测量跟我们在实验室用个开发板随便接个热敏电阻完全是两码事。工业环境里电磁干扰大、线缆长、温度范围宽HVAC场景又对长期稳定性和成本极度敏感。我做过好几个类似的项目从锅炉房到洁净车间从冷库到数据中心空调末端踩过的坑足够写一本小册子。这次要聊的方案核心是ADS122U04IPWR这颗24位Δ-Σ ADC搭配STM32F373RC这颗自带16位ADC和DAC的混合信号MCU组合起来做一套高精度、抗干扰、可长期运行的工业级温度采集方案。先说清楚这套组合能干什么。ADS122U04IPWR是TI的一款24位、4通道、带PGA和激励电流源的Δ-Σ型ADC内置2.048V基准支持SPI和UART两种接口。STM32F373RC是ST的Cortex-M4内核MCU主频72MHz自带3个16位ADC、3个12位DAC、比较器、运放还有丰富的定时器和通信外设。两者搭配可以覆盖PT100、PT1000、热电偶、NTC热敏电阻等多种温度传感器的信号采集精度能做到0.1℃以内长期漂移控制在0.05%以内。适合谁参考做工业自动化、楼宇自控、HVAC控制器、冷链监控、过程仪表的朋友尤其是那些被现场干扰搞得焦头烂额、被客户投诉温度跳变的人。为什么选这个组合而不是直接用STM32F373RC自带的16位ADC这是很多人第一个会问的问题。STM32F373RC的16位ADC在单端输入、短距离、干净电源下确实能用但工业现场长线缆引入的共模干扰、地环路、工频耦合会让它的有效位数直接掉到12位甚至更低。ADS122U04IPWR的Δ-Σ架构配合PGA对低频干扰有天然的抑制能力加上它支持差分输入和内置的50/60Hz陷波滤波在同样恶劣的现场能把有效精度稳定在18位以上。这个差距在测PT100时特别明显STM32F373RC直接测温度跳动可能有0.5℃换成ADS122U04IPWR跳动能压到0.05℃以内。另一个关键考量是激励方式。PT100是电阻型传感器必须给它一个稳定的激励电流。ADS122U04IPWR内置了两路可编程激励电流源支持10μA到1.5mA多档选择配合它的比率式测量模式可以消除激励电流漂移带来的误差。如果用STM32F373RC自己搭恒流源需要额外的运放、基准电阻和精密电阻温漂和噪声都很难控制。ADS122U04IPWR把这一块集成进去外围只需要几个电阻电容PCB面积和BOM成本都省下来了。HVAC场景还有一个特殊需求多点测量。一个空调箱可能同时要测送风温度、回风温度、盘管进出水温度、室外温度四到八个测点是常态。ADS122U04IPWR有4个差分通道配合外部多路复用器可以扩展到8路甚至16路。STM32F373RC负责轮询、数据处理、通信和逻辑控制两者通过SPI连接STM32F373RC做主ADS122U04IPWR做从通信速率可以跑到4MHz一次完整采集加处理在10ms以内完全满足HVAC系统的实时性要求。提示选型时不要只看ADC位数。24位ADC在工业现场的有效位数取决于前端设计、PCB布局和软件滤波。ADS122U04IPWR的优势在于它把PGA、基准、激励源、陷波滤波都集成进去了减少了外围不确定性这才是它在工业场景里真正的价值。2. 核心器件特性与关键参数拆解2.1 ADS122U04IPWR的四个关键能力ADS122U04IPWR这颗芯片我把它拆成四个核心能力来看低噪声PGA、双匹配激励电流源、灵活的数字滤波器、内置基准。这四个能力直接决定了它在温度测量里的表现。低噪声PGA的增益可以设1到128倍。测PT100时100Ω在0℃时产生的电压是100Ω×1mA100mV这个信号直接进ADC相对于2.048V基准只用了不到5%的量程浪费了大部分动态范围。把PGA设成16倍信号放大到1.6V接近满量程有效分辨率直接提升。PGA的噪声在增益16、数据率20SPS时大约是1.5μV RMS折算到PT100上是0.004℃这个噪声水平对工业温度测量来说绰绰有余。双匹配激励电流源是测电阻型传感器的关键。两路电流源可以分别设置成10μA、50μA、100μA、250μA、500μA、1000μA、1500μA。测PT100通常用500μA或1mA测PT1000用100μA到250μA测NTC用10μA到50μA避免自热。两路电流源匹配度典型值是0.1%这意味着如果用比率式测量激励电流的漂移会被大幅抵消。具体做法是电流源流过参考电阻和PT100串联ADC同时测量参考电阻上的电压和PT100上的电压两者相除得到电阻比值再查表或计算温度。这样即使电流源随温度变化了10%比值仍然准确。数字滤波器这块ADS122U04IPWR支持Sinc3、Sinc1、50/60Hz陷波等多种模式。工业现场最头疼的是工频干扰50Hz和它的谐波会直接耦合到长线缆上。用50/60Hz陷波滤波器配合20SPS的数据率对50Hz和60Hz的抑制都能做到80dB以上。我实测过在变频器旁边走2米长的屏蔽线用陷波滤波器后温度读数跳动从0.3℃降到0.02℃。内置基准是2.048V初始精度0.05%温漂5ppm/℃。这个基准在0到70℃范围内变化大约0.35mV折算到PT100测量上是0.09℃的误差。如果对精度要求更高可以外接一个更好的基准比如REF5025但大多数工业HVAC场景用内置的就够了。2.2 STM32F373RC在方案里的角色定位STM32F373RC在这套方案里不是打酱油的。它要做四件事SPI主控与数据读取、温度换算与线性化、通信与协议处理、系统监控与故障诊断。SPI主控这块STM32F373RC的SPI1可以跑到18MHz但ADS122U04IPWR的SPI最高支持4MHz所以实际用4MHz。每次采集STM32F373RC先发命令配置ADS122U04IPWR的输入通道、PGA增益、数据率然后等待DRDY引脚变低再读24位数据。整个过程用中断或DMA都可以我习惯用DRDY下降沿触发外部中断在中断里启动SPI读取这样CPU占用最低。温度换算和线性化是STM32F373RC的强项。PT100的非线性用Callendar-Van Dusen方程处理热电偶用NIST多项式或者查表加插值。STM32F373RC有硬件FPU跑这些计算毫无压力。我一般把PT100的分度表做成一个数组用二分查找加线性插值精度做到0.01℃以内计算时间不到50μs。通信与协议处理方面STM32F373RC自带CAN、USART、I2C、USB可以轻松对接Modbus RTU、BACnet MS/TP、CANopen等工业协议。HVAC领域Modbus RTU用得最多STM32F373RC的USART加一个RS485收发器就能搞定。如果要接BACnet可以用MSTP或者IPSTM32F373RC的资源也够跑轻量级协议栈。系统监控与故障诊断这块经常被忽略但工业现场特别重要。STM32F373RC要监测传感器断线、短路、超量程、ADC无响应等情况。ADS122U04IPWR本身有开路检测功能可以注入一个小电流看电压是否超范围。STM32F373RC还可以用它的内部温度传感器监测板温用看门狗防止程序跑飞用备份寄存器记录故障代码。2.3 关键参数的计算与选择依据测PT100时激励电流选多大这需要算一笔账。PT100在0℃时100Ω在100℃时138.51Ω在200℃时175.86Ω。如果激励电流用1mA200℃时功耗是1mA²×175.86Ω0.176mW自热引起的温升在标准封装下大约0.02℃可以接受。如果用500μA功耗降到0.044mW自热温升0.005℃但信号电压减半对ADC噪声要求更高。我一般选500μA到1mA之间看传感器封装和精度要求。PGA增益怎么选信号电压激励电流×电阻。用1mA激励0℃时100mV200℃时175.86mV。ADS122U04IPWR的基准是2.048VPGA增益16倍时满量程输入是2.048V/16128mV。100mV的信号在128mV满量程下用了78%200℃时175.86mV会超量程。所以增益16只适合测到大约50℃。要测到200℃增益得降到8倍满量程256mV175.86mV用了69%。如果测到400℃PT100是247.09Ω1mA下247mV增益8倍满量程256mV刚好够。所以增益选择要跟测量范围匹配不能一刀切。数据率选多少ADS122U04IPWR支持5SPS到2000SPS。工业温度测量不需要太快20SPS足够而且20SPS时50/60Hz陷波滤波器正好工作。如果要多通道轮询4个通道每个20SPS一轮80ms对HVAC控制来说完全够用。如果要测快速变化的温度比如发动机排气可以提到200SPS或1000SPS但噪声会增大需要权衡。参考电阻怎么选比率式测量时参考电阻和PT100串联参考电阻上的电压要接近但不超过基准电压。用1mA激励基准2.048V参考电阻最大2.048V/1mA2.048kΩ。实际选1.8kΩ电压1.8V留了余量。参考电阻的精度和温漂直接影响测量精度我一般用0.1%、5ppm/℃的精密电阻比如Vishay的PTF系列或者VPG的箔电阻。这个电阻是整套方案里最不能省钱的元件之一。3. 硬件设计与实操要点3.1 模拟前端电路设计细节模拟前端是这套方案里最考验功底的部分。ADS122U04IPWR的输入是差分PT100通常三线制或四线制接法。三线制可以抵消引线电阻四线制精度最高但线多。工业现场三线制用得最多因为省线。三线制接法的原理是PT100两端各引一根线其中一端再引一根线作为补偿线。ADS122U04IPWR的两个激励电流源分别流过PT100和补偿线ADC测量PT100两端电压和补偿线电压通过计算抵消引线电阻。具体电路是AIN0接PT100一端AIN1接PT100另一端AIN2接补偿线AIN3接参考电阻一端。激励电流源1从AIN0流出经过PT100到AIN1再经过引线到地。激励电流源2从AIN2流出经过补偿线到地。ADC测量AIN0-AIN1的电压和AIN2-AIN1的电压两者相减得到PT100上的净电压。这个电路里输入滤波特别关键。ADS122U04IPWR的输入端要加RC滤波截止频率设在1kHz到10kHz之间。我一般用1kΩ电阻加100nF电容差分和共模都要滤。电阻要用低温度系数的薄膜电阻电容用C0G或X7R。滤波电阻不能太大否则会引入噪声ADS122U04IPWR的输入偏置电流在PGA开启时是几十nA1kΩ上产生的误差可以忽略。基准和电源去耦是另一个重点。ADS122U04IPWR的AVDD和DVDD要分开供电AVDD用3.3V或5VDVDD用3.3V。每个电源引脚都要加100nF和10μF电容100nF尽量靠近引脚。基准引脚REFIN也要加1μF到10μF电容。我习惯在AVDD上再加一个LC滤波用10μH电感和10μF电容把开关电源的纹波压到100μV以下。PCB布局上模拟部分和数字部分要严格分开。ADS122U04IPWR放在模拟区STM32F373RC放在数字区地平面用单点连接或者用0Ω电阻桥接。SPI信号线要走数字区不要穿过模拟区。PT100的引线要用屏蔽双绞线屏蔽层单端接地接在模拟地附近。这些细节听起来老生常谈但我在现场见过太多因为布局不当导致温度跳变的案例。3.2 STM32F373RC的外围配置STM32F373RC的外围配置相对简单但有几个点要注意。晶振用8MHz无源晶振加两个22pF电容PLL倍频到72MHz。复位电路用10kΩ上拉加100nF电容再加一个复位按钮。调试接口用SWD四根线方便下载和调试。SPI接口用SPI1SCK、MISO、MOSI、CS四根线。CS用GPIO控制不要用硬件NSS因为ADS122U04IPWR的CS需要软件精确控制时序。DRDY引脚接STM32F373RC的外部中断比如PA0下降沿触发。SPI的时钟极性设成空闲低电平第二个边沿采样跟ADS122U04IPWR的SPI模式匹配。RS485通信用USART2加一个MAX485或者SP3485收发器。收发器的DE和RE引脚用GPIO控制发送时拉高接收时拉低。RS485的A、B线要加TVS管和终端电阻终端电阻120Ω用跳线选择是否接入。工业现场长距离通信时终端电阻和偏置电阻都要加偏置电阻用680Ω上拉到5V下拉到地保证空闲时总线有确定电平。电源设计上STM32F373RC用3.3VADS122U04IPWR的AVDD可以用3.3V或5V。如果用5VSTM32F373RC的SPI输出是3.3V电平ADS122U04IPWR的DVDD是3.3V逻辑电平匹配没问题。如果ADS122U04IPWR的DVDD也用5V就需要电平转换。我一般统一用3.3V省事。看门狗用STM32F373RC的独立看门狗IWDG时钟源用内部40kHz RC超时设1秒。主循环里定期喂狗如果程序跑飞1秒后复位。备份寄存器用来记录故障代码和运行时间掉电不丢。3.3 传感器选型与接线实操PT100选型要看应用场景。工业HVAC一般用薄膜PT100或者绕线PT100。薄膜PT100体积小、响应快、成本低适合风管和水管温度测量。绕线PT100精度高、稳定性好适合精密测量。精度等级选A级或AA级A级在0℃时误差±0.15℃AA级±0.1℃。长期稳定性方面薄膜PT100年漂移大约0.04℃绕线PT100更小。接线方式上三线制最常用。PT100的三根线颜色通常是红、红、白或者红、白、白。具体要看厂家说明书。接线时两根同色的线接PT100两端第三根线接补偿端。如果线色分不清用万用表量PT100两端电阻在100Ω左右补偿线和其中一端之间电阻接近0Ω。屏蔽和接地是现场接线最容易被忽视的。PT100的引线要用屏蔽双绞线屏蔽层在控制器端单点接地传感器端悬空。如果传感器端也接地会形成地环路引入干扰。双绞线要绞得密一些每厘米至少一绞这样对磁场干扰有抑制作用。线缆尽量远离动力线如果必须交叉要垂直交叉不要平行走线。冷端补偿是热电偶测量必须处理的。如果用热电偶ADS122U04IPWR需要一个冷端补偿传感器比如PT1000或者LM35接在另一个通道上。STM32F373RC读取冷端温度再根据热电偶类型查表计算热端温度。冷端补偿的精度直接影响整体精度PT1000做冷端补偿可以做到0.1℃以内。注意PT100的自热效应在静止空气中比流动空气中严重。如果传感器用在静止空气或者小体积样品里激励电流要降到100μA到250μA否则自热误差可能超过0.1℃。我吃过这个亏一个冷库温度探头用1mA激励读数比实际高了0.3℃后来降到250μA才准。4. 软件实现与核心代码解析4.1 ADS122U04IPWR的寄存器配置与SPI通信ADS122U04IPWR有4个配置寄存器分别控制输入多路复用器、增益、数据率、工作模式等。上电后STM32F373RC要先发RESET命令然后写配置寄存器。配置寄存器的写入顺序是先写配置寄存器0到3再发START/SYNC命令启动转换。配置寄存器0控制多路复用器和增益。测PT100三线制时多路复用器设成AIN0和AIN1差分增益设成8或16。配置寄存器1控制数据率和工作模式数据率设20SPS工作模式设正常模式。配置寄存器2控制基准选择、激励电流源和IDAC路由。基准选内部2.048V激励电流源1和2都开电流设500μA或1mA。配置寄存器3控制IDAC的引脚路由和DRDY模式。SPI通信的时序是CS拉低发送命令字节等待读取数据。ADS122U04IPWR的命令有RESET、START、POWERDOWN、RDATA、RREG、WREG等。读数据时发RDATA命令然后读3个字节组成24位数据。写寄存器时发WREG命令加寄存器地址然后写数据。// ADS122U04IPWR SPI读写示例 #define ADS122U04_CS_LOW() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET) #define ADS122U04_CS_HIGH() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET) uint8_t ADS122U04_WriteReg(uint8_t reg, uint8_t data) { uint8_t cmd 0x40 | (reg 2); // WREG命令 ADS122U04_CS_LOW(); HAL_SPI_Transmit(hspi1, cmd, 1, 100); HAL_SPI_Transmit(hspi1, data, 1, 100); ADS122U04_CS_HIGH(); return 0; } uint32_t ADS122U04_ReadData(void) { uint8_t cmd 0x10; // RDATA命令 uint8_t rx[3]; ADS122U04_CS_LOW(); HAL_SPI_Transmit(hspi1, cmd, 1, 100); HAL_SPI_Receive(hspi1, rx, 3, 100); ADS122U04_CS_HIGH(); return ((uint32_t)rx[0] 16) | ((uint32_t)rx[1] 8) | rx[2]; }这段代码里WREG命令的格式是0100 rrnnrr是寄存器地址nn是写入的字节数减1。RDATA命令是0001 xxxx。SPI的速率设4MHzHAL_SPI_Transmit和HAL_SPI_Receive的超时设100ms。实际使用时DRDY中断触发后调用ADS122U04_ReadData读到的24位数据是二进制补码需要转换成有符号整数。4.2 PT100温度换算的两种实现方式PT100的温度换算有两种常用方法查表加线性插值和Callendar-Van Dusen方程。查表法简单快速适合资源有限的MCU。Callendar-Van Dusen方程精度高适合对精度要求高的场景。查表法的做法是把PT100的分度表做成一个数组每1℃一个点从-200℃到850℃。STM32F373RC读到ADC值后先算出电阻值然后在数组里二分查找找到相邻两个点后线性插值。这个方法的精度取决于表的密度1℃间隔的表插值后精度大约0.01℃。STM32F373RC的Flash有256KB存一个1051个点的float数组占4KB完全没问题。Callendar-Van Dusen方程是当T≥0℃时R(T) R0 × (1 A×T B×T²)当T0℃时R(T) R0 × (1 A×T B×T² C×(T-100)×T³)其中R0100ΩA3.9083×10⁻³B-5.775×10⁻⁷C-4.183×10⁻¹²。这个方程的反函数没有解析解需要用迭代法求解。我一般用牛顿迭代法迭代3到4次就能收敛到0.001℃。STM32F373RC有FPU一次迭代大约20个时钟周期4次迭代80个周期在72MHz下不到2μs。// Callendar-Van Dusen方程牛顿迭代求温度 float PT100_ResistanceToTemp(float resistance) { const float R0 100.0f; const float A 3.9083e-3f; const float B -5.775e-7f; const float C -4.183e-12f; float T; if (resistance R0) { // T 0用二次方程 T (sqrtf(A*A - 4*B*(1 - resistance/R0)) - A) / (2*B); } else { // T 0用牛顿迭代 T (resistance - R0) / (R0 * A); // 初始猜测 for (int i 0; i 4; i) { float f R0 * (1 A*T B*T*T C*(T-100)*T*T*T) - resistance; float df R0 * (A 2*B*T C*(4*T*T*T - 300*T*T)); T T - f / df; } } return T; }这段代码里T≥0时直接用二次方程求根T0时用牛顿迭代。实际使用时电阻值由ADC值算出R_PT100 (ADC值 / 增益) × (参考电阻 / 满量程) × ... 具体公式取决于电路接法。比率式测量时R_PT100 R_ref × (ADC_PT100 / ADC_ref)这样激励电流和基准漂移都被抵消。4.3 多通道轮询与数字滤波多通道轮询是HVAC多点测量的核心。ADS122U04IPWR有4个差分通道但同一时间只能测一个通道。轮询的做法是配置通道0启动转换等DRDY读数据切换到通道1重复。4个通道一轮80ms每个通道20ms。轮询时要注意通道切换后的稳定时间。ADS122U04IPWR内部的多路复用器切换后输入端的RC滤波需要时间稳定。如果外部RC滤波的截止频率是1kHz时间常数是1ms切换后等5ms再启动转换比较稳妥。我一般切换通道后延时10ms再发START命令。数字滤波方面除了ADS122U04IPWR内部的Sinc3和陷波滤波器STM32F373RC还可以做二次滤波。我常用滑动平均滤波加中值滤波的组合。滑动平均取8个点中值滤波取5个点。滑动平均抑制随机噪声中值滤波抑制脉冲干扰。这两个滤波加起来CPU开销很小但效果很明显。// 滑动平均加中值滤波 #define AVG_SIZE 8 #define MED_SIZE 5 float filter_buffer[AVG_SIZE]; float med_buffer[MED_SIZE]; uint8_t avg_index 0; uint8_t med_index 0; float Filter_Update(float new_value) { // 滑动平均 filter_buffer[avg_index] new_value; avg_index (avg_index 1) % AVG_SIZE; float sum 0; for (int i 0; i AVG_SIZE; i) { sum filter_buffer[i]; } float avg sum / AVG_SIZE; // 中值滤波 med_buffer[med_index] avg; med_index (med_index 1) % MED_SIZE; float temp[MED_SIZE]; memcpy(temp, med_buffer, sizeof(temp)); // 冒泡排序 for (int i 0; i MED_SIZE - 1; i) { for (int j 0; j MED_SIZE - 1 - i; j) { if (temp[j] temp[j1]) { float t temp[j]; temp[j] temp[j1]; temp[j1] t; } } } return temp[MED_SIZE / 2]; }这段代码里滑动平均的窗口是8中值滤波的窗口是5。实际使用时每个通道单独维护一套滤波缓冲区因为不同通道的温度变化速率不同。滤波后的数据再送去做温度换算和通信上报。4.4 Modbus RTU通信与寄存器映射HVAC系统里Modbus RTU是最常见的通信协议。STM32F373RC的USART2加RS485收发器跑Modbus RTU从站。寄存器映射要提前规划好比如寄存器地址内容数据类型说明0x0000通道0温度float送风温度单位℃0x0002通道1温度float回风温度单位℃0x0004通道2温度float盘管进水温度单位℃0x0006通道3温度float盘管出水温度单位℃0x0008状态字uint16bit0-3通道故障bit4-7超量程0x0009故障代码uint16最近一次故障代码Modbus RTU的帧格式是地址、功能码、数据、CRC。功能码03读保持寄存器06写单个寄存器16写多个寄存器。STM32F373RC收到帧后先检查地址是否匹配再检查CRC然后处理功能码。响应帧的格式类似最后加CRC。// Modbus RTU CRC16计算 uint16_t Modbus_CRC16(uint8_t *buf, uint16_t len) { uint16_t crc 0xFFFF; for (uint16_t i 0; i len; i) { crc ^ buf[i]; for (int j 0; j 8; j) { if (crc 0x0001) { crc 1; crc ^ 0xA001; } else { crc 1; } } } return crc; }Modbus RTU的波特率一般用9600或19200数据位8停止位1无校验。RS485的收发切换要在发送前拉高DE发送完最后一个字节后等TC标志置位再拉低DE。这个切换时机很关键拉低太早会截断最后一个字节拉低太晚会影响接收响应。5. 常见问题与排查技巧实录5.1 温度读数跳动大的排查思路温度读数跳动是现场最常遇到的问题。排查要按信号链从后往前查先看ADC原始数据跳不跳再看电源纹波再看输入滤波最后看传感器和接线。如果ADC原始数据跳动大先查电源。用示波器看AVDD和DVDD的纹波如果超过1mV就要加LC滤波或者换LDO。ADS122U04IPWR的PSRR在50Hz时大约80dB但开关电源的纹波频率高PSRR会下降。我遇到过用开关电源给AVDD供电纹波20mV温度跳动0.5℃换成LDO后降到0.02℃。如果电源没问题查输入滤波。ADS122U04IPWR的输入端RC滤波截止频率太高工频干扰会进来。把截止频率从10kHz降到1kHz跳动会明显改善。如果还不行检查PT100的屏蔽线接地。屏蔽层要单端接地接在模拟地附近不能两端都接。如果以上都没问题查ADS122U04IPWR的配置。数据率设太高Sinc3滤波器的抑制能力下降。把数据率从200SPS降到20SPS跳动会小很多。PGA增益设太高噪声也会放大。增益16倍时噪声是增益8倍的两倍如果信号够大增益降一档。5.2 传感器断线与短路的检测方法传感器断线和短路检测在工业现场是刚需。ADS122U04IPWR本身有开路检测功能通过注入一个小电流看电压是否超范围。具体做法是配置寄存器里打开开路检测ADS122U04IPWR会注入一个10μA电流如果传感器断线输入端电压会拉到AVDD或AVSSADC读到满量程或零。软件上STM32F373RC要判断ADC值是否在合理范围内。PT100在-200℃到850℃对应的电阻是18.52Ω到390.48ΩADC值对应一个范围。如果ADC值超出这个范围就报断线或短路。断线时ADC值通常是满量程或零短路时ADC值接近零。// 传感器故障检测 #define PT100_MIN_ADC 1000 // 对应-200℃ #define PT100_MAX_ADC 16700000 // 对应850℃ uint8_t Check_Sensor_Fault(uint32_t adc_value) { if (adc_value PT100_MIN_ADC) { return FAULT_SHORT_CIRCUIT; // 短路 } else if (adc_value PT100_MAX_ADC) { return FAULT_OPEN_CIRCUIT; // 断线 } return FAULT_NONE; }实际使用时ADC值的范围要根据电路参数计算。比率式测量时ADC值对应电阻比值范围计算更复杂。我一般先在实验室测几个标准电阻记录ADC值然后在软件里设阈值。5.3 常见问题速查表现象可能原因排查方法解决方法温度读数跳动大电源纹波大示波器看AVDD纹波加LC滤波或换LDO温度读数跳动大输入滤波截止频率太高检查RC参数降低截止频率到1kHz温度读数跳动大数据率太高检查配置寄存器降到20SPS温度读数偏高自热效应降低激励电流从1mA降到250μA温度读数偏低引线电阻未补偿检查三线制接法确保补偿线接对温度读数固定不变传感器断线量PT100电阻更换传感器温度读数满量程传感器短路量PT100电阻更换传感器SPI读不到数据CS时序不对示波器看CS和SCK调整CS拉低拉高时机SPI读不到数据SPI模式不对检查CPOL和CPHA设成模式1Modbus通信失败波特率不匹配检查双方波特率统一波特率Modbus通信失败CRC错误检查CRC计算用标准CRC16算法Modbus通信失败RS485收发切换时机不对示波器看DE和TX等TC标志再拉低DE5.4 实操心得与避坑技巧第一个坑是ADS122U04IPWR的基准电容。数据手册要求REFIN引脚加1μF到10μF电容我一开始只加了100nF结果噪声很大。后来换成10μF钽电容加100nF陶瓷电容并联噪声立刻降下来。这个电容不能省而且要用低ESR的。第二个坑是SPI的CS时序。ADS122U04IPWR的CS拉低后要等至少100ns才能发SCK。我一开始用硬件NSSCS和SCK几乎同时变化结果读数据不稳定。后来改成软件控制CS拉低后延时1μs再发SCK问题解决。第三个坑是PT100的引线电阻。三线制接法虽然能补偿引线电阻但前提是三根线的电阻完全一致。如果三根线长度不同补偿就不准。我一般要求三根线等长而且用同一种线材。如果线长超过10米引线电阻可能达到几欧姆对PT100来说就是几度的误差必须补偿。第四个坑是冷端补偿的位置。如果用热电偶冷端补偿传感器要放在接线端子附近不能放在PCB上远离端子的地方。接线端子的温度才是真正的冷端温度PCB上的温度可能差好几度。我一般把PT1000贴在接线端子旁边用导热胶固定。第五个坑是Modbus的字节序。STM32F373RC是小端模式Modbus RTU是大端模式。float类型的数据要拆成两个16位寄存器高字在前低字在后。我一开始搞反了上位机读到的温度是乱码。后来统一用大端发送问题解决。第六个坑是看门狗的喂狗时机。IWDG超时设1秒主循环里喂狗。但如果某个任务阻塞超过1秒看门狗会复位。我一般把喂狗放在主循环的开头确保每个循环都喂。如果某个任务可能阻塞就在任务里也喂一次。提示ADS122U04IPWR的DRDY引脚是开漏输出需要上拉电阻。上拉电阻用10kΩ到100kΩ太小会增加功耗太大上升沿会变缓。我一般用47kΩ实测上升沿在100ns以内满足SPI时序要求。6. 系统校准与长期稳定性保障6.1 出厂校准与现场校准的流程校准是保证精度的最后一道关。出厂校准在常温下做用精密电阻箱模拟PT100在几个温度点比如0℃、50℃、100℃记录ADC值算出增益和偏移。现场校准用标准温度计对比调整偏移量。出厂校准的步骤是先把PT100换成精密电阻箱设成100Ω记录ADC值设成138.51Ω记录ADC值设成175.86Ω记录ADC值。然后用最小二乘法拟合增益和偏移。STM32F373RC把校准系数存在Flash里运行时用这些系数修正。现场校准更简单把标准温度计和PT100放在同一个恒温槽里等温度稳定后读标准温度计的值和PT100的值算出差值把这个差值作为偏移量存起来。如果差值随温度变化说明增益也有偏差需要两点校准。// 校准系数应用 typedef struct { float gain; float offset; } CalibCoeff; CalibCoeff calib {1.0f, 0.0f}; float Apply_Calibration(float raw_temp) { return raw_temp * calib.gain calib.offset; }校准系数存在STM32F373RC的Flash里用备份寄存器或者EEPROM模拟。我一般用Flash的最后一页存校准系数加CRC校验防止数据损坏。6.2 长期漂移的监测与补偿长期漂移主要来自三个方面PT100本身的老化、参考电阻的温漂、ADS122U04IPWR的基准漂移。PT100的年漂移在0.04℃左右参考电阻用5ppm/℃的年漂移可以忽略。ADS122U04IPWR的基准温漂5ppm/℃在0到70℃范围内变化0.35mV折算到温度是0.09℃。监测长期漂移的办法是定期用标准电阻校准。如果系统有上位机可以每隔一个月自动校准一次。如果没有可以在系统里加一个精密电阻定期切换到ADC上测量看读数是否变化。这个精密电阻要放在恒温环境里或者用温度系数极低的箔电阻。补偿长期漂移的另一个办法是软件补偿。如果知道PT100的老化规律可以在软件里加一个时间相关的补偿量。但PT100的老化规律因厂家而异不好通用。我一般建议客户每年校准一次把校准系数更新。6.3 电磁兼容与现场防护工业现场的电磁兼容问题不能忽视。ADS122U04IPWR的输入端要加TVS管防止浪涌。TVS管选低电容的比如PESD系列电容小于10pF不影响信号。RS485的A、B线也要加TVS管防止雷击和浪涌。电源入口要加压敏电阻和共模电感抑制共模干扰。共模电感用10mH到100mH压敏电阻用14D471K。如果现场有变频器电源入口还要加EMI滤波器截止频率设在1MHz以下。PCB布局上模拟地和数字地要分开用0Ω电阻或者磁珠连接。ADS122U04IPWR的模拟输入走线要短尽量远离数字信号线。如果实在避不开中间加地线隔离。晶振要靠近STM32F373RC走线要短下面不要走其他信号线。外壳要用金属的接大地。如果外壳是塑料的内部要加屏蔽罩。PT100的屏蔽线要接到外壳上外壳再接大地。这样形成一个完整的屏蔽体系能有效抑制辐射干扰。注意现场防护不是堆料而是系统设计。TVS管、共模电感、屏蔽罩都要配合好的接地才能起作用。我见过加了TVS管但接地不良的案例浪涌照样打坏芯片。接地电阻要小于4Ω最好小于1Ω。7. 方案扩展与不同场景的适配7.1 从PT100扩展到热电偶和NTC这套方案的核心是ADS122U04IPWR加STM32F373RC换传感器只需要改配置和软件。测热电偶时ADS122U04IPWR的PGA增益设成32或64因为热电偶的输出电压只有几十μV/℃。K型热电偶在100℃时输出4.095mV增益64倍后262mV接近满量程。冷端补偿用PT1000接另一个通道STM32F373RC读冷端温度后查表计算。测NTC时激励电流要降到10μA到50μA避免自热。NTC的阻值随温度指数变化线性化用Steinhart-Hart方程。STM32F373RC跑Steinhart-Hart方程需要浮点运算但它的FPU足够快一次计算不到10μs。7.2 多路扩展与分布式测量4个通道不够用怎么办两个办法外部多路复用器和多片ADS122U04IPWR。外部多路复用器用ADG708或ADG16088通道或16通道STM32F373RC用GPIO控制通道选择。多片ADS122U04IPWR用不同的CS引脚STM32F373RC轮询访问。多片方案成本高但精度和隔离性好适合分布式测量。分布式测量时每个测点放一片ADS122U04IPWR加一个隔离器通过RS485或者CAN总线连到主控。STM32F373RC做主控轮询各个从站。这种架构适合大型HVAC系统比如整栋楼的空调监控。7.3 低功耗设计与电池供电场景如果测点没有市电要用电池供电低功耗设计就很重要。ADS122U04IPWR支持单次转换模式转换完自动进入低功耗。STM32F373RC可以进Stop模式等DRDY中断唤醒。这样平均功耗可以做到100μA以下用一节锂亚电池能跑好几年。低功耗设计的关键是占空比。温度变化慢不需要连续测量。可以每10秒测一次每次测量20ms占空比0.2%。ADS122U04IPWR在单次转换模式下的功耗是几百μASTM32F373RC在Stop模式下是几μA平均下来不到10μA。电池寿命计算2000mAh电池除以10μA等于200000小时约22年。实际有自放电和温度影响5到10年没问题。我在实际项目里用这套方案做过冷链运输的温度记录仪一节18650电池跑了3年多数据通过无线模块定时上传。关键是把ADS122U04IPWR和STM32F373RC的低功耗模式用透该睡的时候睡该醒的时候醒不要一直跑。