基于ADS122U04IPWR与STM32F107VC的工业及HVAC高精度温度测量方案 1. 工业与HVAC温度测量方案的整体设计思路工业现场和HVAC系统里的温度测量跟我们在实验室拿个万用表测室温完全是两码事。实验室里环境恒定、干扰小、对精度要求也没那么苛刻但工业场景下传感器可能挂在几十米长的电缆末端旁边就是变频器、接触器、大功率电机电磁环境极其恶劣。HVAC场景虽然干扰没那么猛但要求长期稳定运行、免维护而且往往需要多点分布式采集。这两种场景对温度测量方案提出的共同要求是高分辨率、低噪声、抗干扰、长期漂移小、接口可靠。ADS122U04IPWR 这颗芯片正是为这类场景量身定制的。它是TI的一款24位Δ-Σ型ADC内置PGA可编程增益放大器、双匹配电流源IDAC、参考电压缓冲、振荡器以及UART接口。注意它输出的是UART串口数据不是SPI或I2C这一点跟很多人的直觉不同。UART接口的好处是布线简单、抗干扰能力强特别适合传感器节点与主控之间有一定距离的场合。而STM32F107VC作为主控带有以太网MAC、CAN、多个UART和丰富的定时器资源在工业网关和HVAC控制器里非常常见用它来对接ADS122U04IPWR可以很方便地把温度数据汇聚后上传到上位机或云端。整个方案的核心链路是这样的PT100或PT1000铂电阻作为感温元件ADS122U04IPWR负责激励电流输出、信号放大和模数转换STM32F107VC通过UART读取转换结果再经过换算得到实际温度值。为什么选PT100/PT1000而不是热电偶或热敏电阻热电偶虽然测温范围宽但冷端补偿麻烦、精度有限热敏电阻便宜但线性度差、互换性不好。PT100在-200°C到850°C范围内线性度好、精度高、长期稳定性优秀是工业和HVAC温度测量的主流选择。ADS122U04IPWR内部的双IDAC可以给PT100提供精确的激励电流配合内部PGA放大微小电压变化再用24位ADC量化整套方案的分辨率可以做到微伏级别对应温度分辨率轻松达到0.01°C甚至更高。这个方案适合谁呢如果你正在做工业温度变送器、HVAC温控器、冷库温度监控、锅炉温度采集、或者任何需要高精度多路温度测量的嵌入式项目这套组合都值得认真考虑。下面我会从芯片选型逻辑、硬件设计细节、软件配置流程、实际调试经验几个维度把整个方案拆开来讲清楚。2. ADS122U04IPWR与STM32F107VC的硬件设计要点2.1 为什么选ADS122U04IPWR而不是普通ADC很多人第一反应是STM32F107VC自带12位ADC直接拿来做温度测量不行吗答案是在要求不高的场合可以但在工业级温度测量里基本不够用。STM32的12位ADC有效位数ENOB通常只有10位左右而且参考电压受电源波动影响大噪声也不小。PT100在0°C时阻值100Ω每摄氏度变化约0.385Ω。如果用1mA激励电流每摄氏度产生的电压变化只有0.385mV。要分辨0.1°C就需要分辨38.5μV的电压变化。STM32的12位ADC在3.3V参考下1LSB约0.8mV根本分辨不出来。ADS122U04IPWR的24位分辨率配合PGA增益可以轻松分辨到纳伏级别这才是高精度温度测量的基础。ADS122U04IPWR的PGA增益可以设置为1、2、4、8、16、32、64、128。对于PT100通常用增益8到32之间比较合适。假设用1mA激励0°C时PT100上压降100mV100°C时压降138.5mV变化范围38.5mV。如果PGA增益设为32输出范围就是3.2V到4.432V超过了ADC的参考电压。所以实际设计时要么降低激励电流要么调整增益。常见做法是用500μA激励电流增益设为16这样0°C时输出800mV100°C时输出1.108V在参考电压2.048V范围内留有余量。这个计算过程在实际选型时非常关键不能拍脑袋决定。2.2 模拟前端电路设计细节PT100的接法有三线制和四线制两种。两线制最简单但引线电阻会直接叠加到测量结果里每米铜线大约0.02Ω几十米电缆就是几欧姆对应十几度的误差完全不能用。三线制可以补偿引线电阻前提是三根线材质长度一致ADS122U04IPWR支持双IDAC分别从两个引脚输出电流配合外部电路可以实现三线制比例测量。四线制精度最高但多一根线成本略高。工业现场推荐四线制HVAC如果传感器离主控不远三线制也够用。具体电路上IDAC1从AIN0输出激励电流经过PT100后回到AIN1再经过参考电阻RREF回到地。IDAC2可以设置成与IDAC1相同电流从另一个引脚输出用于三线制补偿。参考电压取自RREF两端这样激励电流的漂移会被比例测量抵消掉。RREF的选型很关键假设激励电流500μA希望参考电压2.048V那么RREF2.048V/500μA4096Ω。实际选4.12kΩ的精密电阻温漂要低于10ppm/°C否则参考电压漂移会直接变成测量误差。模拟输入端的RC滤波不能省。在AIN0和AIN1各串一个1kΩ电阻再对地接100nF电容截止频率约1.6kHz可以有效抑制高频干扰。但电阻不能太大否则会与IDAC输出阻抗形成分压影响激励电流精度。ADS122U04IPWR的IDAC输出 compliance voltage 有限如果串联电阻过大电流源可能无法维持恒定。实测下来1kΩ串联电阻在500μA电流下压降0.5V加上PT100和RREF上的压降总电压要控制在AVDD-0.8V以内否则IDAC会失稳。电源部分ADS122U04IPWR的AVDD和DVDD可以分开供电AVDD建议用低噪声LDO比如TPS7A4700输出3.3V或5V。DVDD可以跟STM32共用3.3V。模拟地和数字地要单点连接通常在芯片下方用0Ω电阻或磁珠连接。去耦电容每路电源都要有100nF加10μF组合靠近芯片引脚放置。这些细节看起来琐碎但实际调试时很多噪声问题都是电源和地没处理好导致的。2.3 STM32F107VC的UART接口配置ADS122U04IPWR的UART接口是异步串口默认波特率可以配置支持9600到115200甚至更高。STM32F107VC有多个USART选一个带DMA的比如USART1或USART2。接线很简单ADS122U04IPWR的TX接STM32的RXRX接STM32的TX再加上地线。注意ADS122U04IPWR的UART电平是DVDD电平如果DVDD是3.3VSTM32也是3.3V可以直接连。如果DVDD是5V就需要电平转换。STM32这边用HAL库配置USART波特率设1152008位数据无校验1位停止位。建议开启DMA接收因为ADS122U04IPWR在连续转换模式下会持续输出数据用中断接收容易丢数据。DMA缓冲区设大一点比如256字节然后定期解析。解析协议要仔细看数据手册ADS122U04IPWR的输出格式是24位数据加状态字节具体帧格式取决于寄存器配置。建议先用单次转换模式调通再切到连续模式。注意ADS122U04IPWR的UART在芯片复位后需要先发送同步字或配置命令才能进入正常数据输出模式具体流程参考数据手册的“UART Interface”章节。不要一上电就等着收数据那样大概率什么都收不到。3. 软件配置与温度换算的完整实现3.1 ADS122U04IPWR寄存器配置流程ADS122U04IPWR内部有四个配置寄存器分别控制输入多路复用器、增益、数据速率、工作模式、IDAC电流、参考选择等。上电后第一步是复位可以通过发送复位命令或拉低RESET引脚。复位后所有寄存器恢复默认值然后按顺序写入配置。配置顺序建议如下先写寄存器0设置MUX和增益。对于PT100四线制MUX选AIN0和AIN1作为差分输入增益设16。再写寄存器1设置数据速率和模式。数据速率选20SPS或45SPS这两个速率下50Hz/60Hz工频抑制最好。模式选连续转换或单次转换调试阶段用单次。寄存器2设置IDAC电流和参考选择。IDAC选500μA参考选外部RREF。寄存器3设置IDAC路由和烧毁检测等。烧毁检测功能可以检测传感器断线工业场景建议开启。写寄存器通过UART发送命令字每个命令字包含寄存器地址和读写位。具体命令格式0x40|寄存器地址2|写操作。比如写寄存器0命令是0x40。然后跟一个数据字节。发送完配置后回读寄存器确认写入成功。这一步很多人会忽略但实际调试时配置没写进去导致数据不对的情况非常常见。3.2 温度换算的数学过程ADS122U04IPWR输出的是24位有符号整数代表差分输入电压经过PGA放大后的量化值。换算成实际温度需要几步。第一步把24位补码转成有符号整数。如果最高位是1说明是负数需要取补码。第二步计算输入电压。公式是Vin (Code × VREF) / (Gain × 2^23)。其中VREF是参考电压Gain是PGA增益2^23是因为24位ADC的有效位数是23位加符号位。第三步计算PT100阻值。四线制下RPT Vin / IIDAC。第四步用Callendar-Van Dusen方程把阻值转成温度。对于0°C以上的范围公式是R(T) R0 × (1 A×T B×T²)。其中R0100ΩA3.9083×10^-3B-5.775×10^-7。反解T需要用二次方程求根公式。对于0°C以下还要加C项但HVAC场景基本用不到。实际代码里为了效率通常用查表加线性插值或者用分段多项式拟合。如果MCU资源够直接算二次方程也不慢。STM32F107VC是72MHz的Cortex-M3带硬件除法算一次温度换算也就几微秒。我一般会在初始化时算好系数然后每次转换后直接代入。3.3 代码框架与关键函数下面给一个简化的代码框架基于STM32 HAL库和标准外设库都可以移植。核心是UART收发和温度换算两个模块。// ads122u04.h #define ADS122U04_ADDR 0x40 #define ADS122U04_CMD_RESET 0x06 #define ADS122U04_CMD_START 0x08 #define ADS122U04_CMD_RDATA 0x10 void ADS122U04_Init(void); void ADS122U04_WriteReg(uint8_t reg, uint8_t val); uint8_t ADS122U04_ReadReg(uint8_t reg); int32_t ADS122U04_ReadData(void); float ADS122U04_CodeToTemp(int32_t code);// ads122u04.c void ADS122U04_WriteReg(uint8_t reg, uint8_t val) { uint8_t cmd 0x40 | (reg 2); HAL_UART_Transmit(huart1, cmd, 1, 100); HAL_UART_Transmit(huart1, val, 1, 100); } int32_t ADS122U04_ReadData(void) { uint8_t cmd ADS122U04_CMD_RDATA; uint8_t buf[3]; HAL_UART_Transmit(huart1, cmd, 1, 100); HAL_UART_Receive(huart1, buf, 3, 100); int32_t code (buf[0] 16) | (buf[1] 8) | buf[2]; if (code 0x800000) code | 0xFF000000; // 符号扩展 return code; } float ADS122U04_CodeToTemp(int32_t code) { float vref 2.048f; float gain 16.0f; float idac 0.0005f; // 500uA float vin (code * vref) / (gain * 8388608.0f); float rpt vin / idac; // 解二次方程 R R0*(1 A*T B*T^2) float R0 100.0f, A 3.9083e-3f, B -5.775e-7f; float a R0 * B; float b R0 * A; float c R0 - rpt; float disc b*b - 4*a*c; if (disc 0) return -999.0f; float t (-b sqrtf(disc)) / (2*a); return t; }这段代码里ADS122U04_ReadData发送RDATA命令后读取3个字节拼成24位有符号数。ADS122U04_CodeToTemp先算输入电压再算PT100阻值最后解二次方程得到温度。注意sqrtf需要包含math.h并且工程里要开浮点运算支持。如果不想用浮点可以全部用定点数但STM32F107VC有FPU吗没有Cortex-M3没有硬件浮点但软件浮点也够快20SPS的转换速率下完全来得及。提示实际产品代码里建议加一个校准环节。用精密电阻箱模拟PT100在0°C和100°C的阻值记录ADC码值然后修正增益和偏移。这样可以把系统误差从±0.5°C降到±0.1°C以内。4. 实际调试中遇到的典型问题与排查方法4.1 读数跳动大、噪声高的排查思路这是最常见的问题。ADS122U04IPWR是24位ADC理论上分辨率很高但如果硬件或软件没处理好读数可能跳动几十个码甚至上百个码。排查顺序如下。先看电源。用示波器测AVDD和DVDD的纹波如果超过10mVpp就要加LC滤波或换LDO。特别是如果STM32和ADS122U04IPWR共用一路3.3VSTM32的开关噪声会串过来。建议ADS122U04IPWR的AVDD单独用一路LDO或者至少加一个磁珠隔离。再看地线。模拟地和数字地如果混在一起数字回流会污染模拟信号。检查PCB布局ADS122U04IPWR的AGND和DGND应该分别走线最后在芯片下方单点连接。如果已经打板了可以尝试在AGND和DGND之间飞一个0Ω电阻看噪声是否改善。然后看输入滤波。PT100引线如果很长会像天线一样拾取干扰。在ADS122U04IPWR输入端加RC滤波电阻1kΩ电容100nF截止频率1.6kHz。如果干扰是工频可以把数据速率设成20SPSADS122U04IPWR在这个速率下自带50Hz和60Hz陷波抑制效果很好。最后看配置。PGA增益是不是设得太高增益越高噪声也越大。如果信号本身够大尽量用低增益。IDAC电流是不是太大500μA在PT100上产生50mV到200mV压降如果增益16输出0.8V到3.2V接近参考电压上限。可以试试250μA或100μA降低功耗和自热。4.2 UART通信不上的几种可能ADS122U04IPWR的UART有时候会让人抓狂因为它的协议跟普通串口设备不太一样。常见问题有这几个。第一波特率不匹配。ADS122U04IPWR默认波特率是9600还是115200不同批次可能不同一定要看数据手册。如果STM32设115200芯片是9600那收到的全是乱码。可以用示波器测TX引脚波形算一下位宽反推波特率。第二命令格式错误。ADS122U04IPWR的命令字是8位但有些命令后面要跟数据字节有些不要。比如RESET命令只发一个字节0x06START命令只发0x08但写寄存器命令要发两个字节。如果多发或少发芯片状态机就乱了。建议用逻辑分析仪抓UART波形对照数据手册的时序图逐字节核对。第三电平不匹配。如果ADS122U04IPWR的DVDD是5VSTM32是3.3V直接连可能烧STM32的RX引脚。必须加电平转换比如用分压电阻或专用电平转换芯片。反过来STM32的TX是3.3VADS122U04IPWR的RX如果要求5V高电平可能识别不了。查数据手册的VIH和VIL参数确保电平兼容。第四上电顺序。ADS122U04IPWR要求AVDD和DVDD的上电顺序有讲究吗一般没有严格要求但如果DVDD先上而AVDD后上芯片可能进入异常状态。建议用同一个电源芯片输出两路或者加电源监控芯片确保同时上电。4.3 温度读数偏差大的校准方法如果读数稳定但偏差大比如实际25°C读出来27°C那就是系统误差需要校准。误差来源主要有几个RREF精度、IDAC电流精度、PGA增益误差、PT100本身精度。校准方法一单点校准。用一个已知精度的电阻箱代替PT100比如设成100.00Ω对应0°C。记录ADC码值算出实际增益系数然后修正代码里的增益值。这种方法只能校准增益不能校准偏移。校准方法二两点校准。分别在0°C和100°C或25°C和75°C记录码值算出增益和偏移。代码里加一个线性修正T_corrected (T_raw - offset) * gain。这种方法精度更高推荐在产品出厂时做。校准方法三用精密PT100传感器。如果手头有经过校准的PT100比如Class A级可以直接对比。但要注意PT100本身也有误差Class A在0°C时误差±0.15°C100°C时±0.35°C。如果要求更高需要用更高等级的传感器或标准铂电阻温度计。实操心得校准时的环境温度要稳定最好在恒温箱里做。如果在校准过程中环境温度变化超过1°C校准结果就不可靠。另外校准电阻箱的精度要至少比目标精度高一个数量级比如目标0.1°C电阻箱精度要0.01Ω。4.4 常见问题速查表现象可能原因排查方法解决措施读数跳动大电源噪声、地线干扰、增益过高示波器测电源纹波检查PCB地平面加LDO、单点接地、降低增益UART收不到数据波特率不对、命令格式错、电平不匹配逻辑分析仪抓波形对照数据手册改波特率、核对命令、加电平转换温度偏差大RREF精度低、IDAC漂移、PT100误差用电阻箱替代PT100测实际码值两点校准、换精密电阻、用高等级PT100读数偶尔跳变工频干扰、传感器断线看跳变是否周期性开烧毁检测设20SPS、开50/60Hz抑制、检查接线功耗偏高IDAC电流大、转换速率高测AVDD电流降低IDAC、用单次转换模式5. 工业与HVAC场景下的工程化经验5.1 长期稳定性与漂移控制工业设备要求连续运行几年甚至十几年温度测量的长期漂移必须控制住。ADS122U04IPWR本身的漂移很低但外围元件的漂移会累积。RREF电阻的温漂是最关键的普通厚膜电阻温漂100ppm/°C温度变化20°C就产生0.2%的误差对应PT100约0.5°C。必须用金属箔电阻或精密薄膜电阻温漂低于10ppm/°C。PT100本身也有长期漂移薄膜PT100比绕线PT100漂移小但成本高。HVAC场景如果精度要求0.5°C普通PT100加精密RREF就够了。工业场景要求0.1°C就要用更高等级的元件。PCB布局对长期稳定性也有影响。ADS122U04IPWR和RREF要远离发热元件比如LDO、MCU、电源芯片。如果板子上有继电器或大功率驱动要加隔离槽。走线要对称差分输入的两根线尽量等长减少共模干扰转化成差模。5.2 多路温度采集的扩展方案HVAC系统往往需要采集多个点的温度比如回风温度、送风温度、室外温度、水温等。ADS122U04IPWR只有一路差分输入但可以通过外部多路复用器扩展。比如用CD4051或ADG7088通道模拟开关STM32控制通道切换ADS122U04IPWR分时采集。注意模拟开关的导通电阻会影响精度CD4051导通电阻几百欧姆跟PT100的100Ω可比会引入误差。要用低导通电阻的开关比如ADG1408导通电阻几欧姆或者用继电器。另一种方案是用多个ADS122U04IPWR每个芯片接一路PT100通过UART地址区分。ADS122U04IPWR支持UART多机通信吗它的UART没有地址位但可以通过外部逻辑切换TX线或者用STM32的多个UART分别接。STM32F107VC有5个USART接5片ADS122U04IPWR没问题。如果更多路可以用UART集线器或切换到SPI接口的ADS1220但那就不是UART方案了。5.3 抗干扰与隔离设计工业现场的电磁干扰是温度测量的大敌。变频器、接触器、电机启停都会产生强烈的瞬态干扰。光靠RC滤波不够还要加隔离。模拟前端可以用隔离放大器比如AMC1300但成本高。更常见的做法是数字隔离在ADS122U04IPWR和STM32之间的UART线上加数字隔离器比如ADuM1201。这样传感器侧的干扰不会传到主控侧主控侧的噪声也不会影响ADC。电源隔离也很重要。如果传感器在远端可以用隔离DC-DC给ADS122U04IPWR供电比如B0505S。但隔离电源的纹波通常较大要加后级LDO滤波。实测下来隔离电源加LDO后噪声可以降到跟非隔离方案相当。TVS管和气体放电管用于防雷击和浪涌。PT100引线如果走室外必须加防雷。TVS选低电容的比如SMBJ5.0A结电容几百皮法对温度信号影响不大。气体放电管响应慢但通流大可以跟TVS配合使用。5.4 低功耗设计考虑HVAC控制器有时候用电池供电或者要求低功耗待机。ADS122U04IPWR支持单次转换模式转换完自动进入休眠电流降到微安级。STM32F107VC也有多种低功耗模式比如Stop模式RTC唤醒。工作流程可以是STM32定时唤醒启动ADS122U04IPWR单次转换读取数据处理完再休眠。这样平均功耗可以做到毫安级甚至更低。IDAC电流对功耗影响很大。500μA连续输出一年就是4.38安时对电池供电不友好。可以降低IDAC到100μA但信号变小对PGA增益和噪声要求更高。或者用脉冲式激励只在转换时开IDAC转换完关掉。ADS122U04IPWR支持IDAC在单次转换后自动关闭配置寄存器里可以设。注意降低IDAC电流后PT100自热效应减小但信号也变小要重新计算增益和参考电压。100μA在PT100上产生10mV到38mV压降增益要设到64或128噪声会相应增大。需要在功耗和精度之间做权衡。6. 方案对比与选型建议6.1 ADS122U04IPWR与其他ADC方案的对比方案分辨率接口内置PGA内置IDAC适用场景ADS122U04IPWR24位UART有有工业温度、HVACADS122024位SPI有有高速多路采集ADS111816位SPI有无中精度温度STM32内置ADC12位片内无无低精度、低成本MAX3186515位SPI无有PT100专用ADS122U04IPWR的优势在于UART接口和内置IDAC外围电路简单布线方便。ADS1220是SPI接口速度快但布线多适合板内短距离。MAX31865是PT100专用芯片配置简单但分辨率只有15位精度不如ADS122U04IPWR。如果项目对成本敏感且精度要求不高MAX31865是不错的选择。如果要求高精度且传感器距离远ADS122U04IPWR更合适。6.2 STM32F107VC的替代选择STM32F107VC是STM32F1系列里带以太网的高端型号72MHz256KB Flash64KB RAM。如果项目不需要以太网可以用STM32F103VC便宜不少UART资源也够。如果需要更高性能可以用STM32F4系列带FPU浮点运算更快。但F1系列在工业现场应用广泛资料多供货稳定对于温度测量这种低速应用完全够用。如果要用CAN总线组网STM32F107VC自带CAN控制器很方便。HVAC系统里多个温度节点通过CAN或RS485联网主控再通过以太网上传。STM32F107VC的以太网MAC加外部PHY可以实现这个功能。软件上可以用LwIP协议栈但LwIP配置复杂调试周期长。如果只是上传数据用串口服务器模块更简单。6.3 成本与精度的平衡一个完整的温度测量节点BOM成本大概这样ADS122U04IPWR约20元STM32F107VC约30元PT100约10元精密电阻和电容约5元PCB和连接器约10元总共75元左右。如果换成STM32内置ADC加运放方案可以省掉ADS122U04IPWR的20元但精度和稳定性差很多校准工作量也大。对于工业产品这20元值得花。对于消费级HVAC可以用MAX31865替代省一半成本精度损失在可接受范围内。精度方面ADS122U04IPWR方案配合Class A PT100和精密RREF整体精度可以做到±0.1°C。如果只用普通PT100和普通电阻精度约±0.5°C。校准后可以提升到±0.2°C。实际项目中我一般按±0.3°C设计留足余量。7. 写在最后的一些实操体会这套方案我在几个工业温控项目里用过最深的体会是硬件设计占七成软件占三成。很多人把精力花在写代码上结果硬件没搞好怎么调都达不到精度。电源、地线、滤波、布局这些基础工作做扎实了软件就是简单的配置和换算。反过来硬件有缺陷软件再怎么补偿也有限。另一个体会是ADS122U04IPWR的UART虽然方便但调试时最好先用SPI版本的ADS1220验证算法因为SPI时序更直观逻辑分析仪一抓就明白。算法调通后再换UART版本这样能少走很多弯路。ADS1220和ADS122U04IPWR的寄存器基本兼容代码移植量很小。最后分享一个小技巧ADS122U04IPWR的烧毁检测电流可以设置成0.5μA到10μA用来检测PT100是否断线。但检测电流会在PT100上产生微小压降如果一直开着会影响测量精度。可以在两次转换之间短暂开启烧毁检测检测完立刻关掉。这样既不影响精度又能实现断线报警。具体配置在寄存器3里设置BCS位和烧毁检测电流大小。这个功能在工业现场很实用传感器断线能及时发现避免控制逻辑出错。