
1. 工业与HVAC温度测量方案的整体设计思路工业现场和HVAC系统里的温度测量跟我们在实验室拿个万用表测室温完全是两码事。工业场景往往要求-40℃到125℃甚至更宽的温度范围、长距离传感器走线、强电磁干扰环境、还要保证0.1℃级别的长期稳定性。我做过好几个HVAC机组和工业烘箱的温度采集项目踩过的坑足够写一本小册子。这次拿ADS122U04IPWR搭配STM32F303VE这套组合来聊是因为它在24位精度、四路差分输入、内置PGA和IDAC电流源这几个关键点上几乎是为RTD和热电偶量身定做的。先说这套方案能干什么。ADS122U04IPWR是TI的一款24位ΔΣ型ADC内置低噪声PGA增益1到128、两个可编程激励电流源IDAC10μA到1.5mA、还有一路内部温度传感器。STM32F303VE是ST的Cortex-M4F内核MCU带FPU和DSP指令主频72MHz片上有多路ADC、DAC、比较器最关键的是它有丰富的定时器资源和灵活的SPI/I2C接口。两者配合可以搭出一套四通道RTD或热电偶温度采集系统精度做到±0.1℃完全可行。为什么选这套组合而不是直接用STM32内部的12位ADC原因很直接。STM32F303的12位ADC在测量PT100这种小信号时分辨率根本不够看。PT100在0℃时是100Ω每℃变化约0.385Ω配合1mA激励电流每℃产生的电压变化只有385μV。12位ADC在3.3V参考下1LSB约等于806μV连1℃的分辨率都达不到更别提0.1℃了。ADS122U04的24位分辨率配合PGA增益可以把385μV/℃的信号放大到ADC满量程的合适区间有效分辨率轻松做到18位以上。这套方案适合谁做工业仪表、HVAC控制器、环境试验箱、食品冷链监控的嵌入式工程师或者想从12位ADC升级到高精度采集的DIY玩家。前提是你得会画四层板、懂一点模拟布局、能写SPI驱动。如果只是测个室温做个风扇调速那大可不必上这套成本划不来。提示ADS122U04IPWR的IPWR后缀代表TSSOP-16封装工业级温度范围-40℃到125℃别买成商业级的ADS122U04IPW两者温度等级不同。2. ADS122U04IPWR的核心特性与RTD测量原理拆解2.1 为什么RTD测量必须用比率式架构RTD电阻温度检测器的阻值随温度变化要测温度就得先测电阻。最直接的办法是给RTD通一个已知电流测它两端的电压然后除以电流得到电阻。但这里有个致命问题激励电流的精度直接影响测量结果。如果你用一颗普通的LDO或者电阻分压产生1mA温漂可能达到几十ppm/℃换算到温度上就是零点几度的误差前面ADC精度再高也白搭。比率式测量就是来解决这个问题的。具体做法是让同一个激励电流先流过一颗高精度参考电阻Rref再流过RTD。ADC分别测量Rref两端电压Vref和RTD两端电压Vrtd最终电阻值Rrtd Rref × (Vrtd / Vref)。注意这个公式里电流I被消掉了也就是说激励电流的绝对精度和温漂完全不影响结果只要在两次测量之间保持稳定就行。ADS122U04的IDAC电流源短期稳定性很好配合比率式架构温漂可以压到几个ppm级别。ADS122U04支持两种比率式接法一种是外部参考电阻接在REFP/REFN引脚上另一种是用内部参考。我一般推荐外部参考电阻方案选一颗0.1%精度、10ppm/℃温漂的金属箔电阻比如Vishay的Y1630100R000T9L100Ω、0.01%精度、2ppm/℃。虽然贵但它是整个系统的精度基准省不得。2.2 PGA增益和IDAC电流该怎么选ADS122U04的PGA增益有1、2、4、8、16、32、64、128八档IDAC电流有10μA、50μA、100μA、250μA、500μA、1000μA、1500μA七档。这两个参数不是随便选的得根据RTD的阻值和参考电阻来算。以PT100为例0℃时100Ω100℃时138.51Ω-40℃时84.27Ω。假设用1mA激励电流100℃时RTD两端电压138.51mV-40℃时84.27mV。如果参考电阻也是100Ω参考电压就是100mV。ADC的满量程输入范围取决于PGA增益和参考电压公式是±Vref/Gain。当Gain1时满量程±100mVRTD信号138.51mV就超了。所以Gain至少得选2满量程变成±50mV但138.51mV还是超。等等这里我算错了ADS122U04的输入范围是±Vref/Gain但Vref是参考电压不是满量程。实际上ADC的满量程输入是±Vref/Gain当Vref100mV、Gain1时输入范围是±100mV138.51mV确实超了。所以要么降低激励电流要么提高参考电阻。我一般用500μA激励电流这样100℃时RTD电压69.25mV-40℃时42.14mV参考电阻用100Ω时参考电压50mVGain1时满量程±50mV69.25mV还是超。那就Gain2满量程±25mV更超了。这里我搞反了Gain越大满量程越小。正确的逻辑是Gain1时满量程±Vref要覆盖69.25mVVref至少得69.25mV。如果Vref100mVGain1满量程±100mV69.25mV在范围内没问题。所以选型逻辑是先确定RTD最大电压Vrtd_max再选参考电阻使Vref略大于Vrtd_max然后Gain1或2。但为了充分利用ADC的动态范围最好让Vrtd_max接近满量程的80%左右。比如Vref100mVVrtd_max69.25mV占69%可以接受。如果想更充分利用可以选Vref75mV但参考电阻得是75Ω不是标准值。所以实际工程中参考电阻选100Ω、激励电流500μA是比较平衡的方案。参数数值说明RTD类型PT1000℃时100Ω激励电流500μAIDAC档位参考电阻100Ω0.01%精度2ppm/℃参考电压50mV500μA × 100ΩRTD最大电压69.25mV100℃时PGA增益1满量程±50mV不够PGA增益2满量程±25mV更不够等等这里我把自己绕进去了。ADS122U04的满量程输入范围是±Vref/GainGain1时是±50mV69.25mV超了。所以要么提高Vref要么降低激励电流。如果激励电流降到250μARTD最大电压34.63mV参考电压25mVGain1时满量程±25mV34.63mV还是超。那就Gain1、Vref50mV、激励电流250μARTD最大电压34.63mV占满量程69%可以。但250μA激励电流下RTD自热效应更小这是好事。PT100在250μA下的自热功率是I²R 250μA² × 138.51Ω ≈ 8.66μW引起的温升可以忽略不计。所以最终推荐激励电流250μA参考电阻200Ω参考电压50mVGain1满量程±50mVRTD最大电压34.63mV。这样配置简单不需要PGA放大噪声也低。但如果你要测更宽的温度范围比如-200℃到600℃PT100在600℃时约313.71Ω250μA下电压78.43mV超了。那就得换方案比如用100μA激励电流参考电阻500Ω参考电压50mV600℃时电压31.37mV没问题。2.3 四路RTD的接线方式与IDAC路由ADS122U04有两路IDAC可以分别路由到不同的引脚。四路RTD测量时有两种接法一种是两路IDAC分别激励两组RTD每组两个RTD串联然后分别测量另一种是用一路IDAC轮流激励四路RTD配合多路复用器。ADS122U04内部有输入多路复用器可以切换四路差分输入但IDAC的路由是独立的。我一般用两路IDAC每路激励两个RTD。具体接法是IDAC1从AIN0流出经过RTD1到AIN1再经过RTD2到AIN2然后回到IDAC1的汇点。这样RTD1和RTD2串联同一个电流流过它们。测量时ADC先测AIN0-AIN1得到RTD1电压再测AIN1-AIN2得到RTD2电压。参考电阻接在IDAC1的汇点和地之间这样参考电压就是IDAC1电流乘以参考电阻。同理IDAC2激励RTD3和RTD4。这种接法的好处是只需要两个参考电阻而且两路IDAC可以独立配置电流大小。坏处是串联的RTD必须共地如果RTD是远端接地的就得用隔离或者差分接法。工业现场RTD通常是三线制或四线制三线制可以消除引线电阻四线制精度最高但接线多。ADS122U04支持三线制和四线制RTD测量具体接法可以参考数据手册的典型应用电路。注意三线制RTD测量时需要两次测量来消除引线电阻。第一次测量RTD电压第二次测量引线电阻电压然后相减。ADS122U04的内部多路复用器可以自动完成这个切换但需要配置寄存器。3. STM32F303VE的SPI驱动与数据采集实现3.1 硬件连接与SPI时序配置ADS122U04和STM32F303VE之间通过SPI通信ADS122U04只支持SPI模式1CPOL0CPHA1最高SCLK频率4MHz。STM32F303VE的SPI1挂载在APB2总线上最高36MHz分频后可以轻松做到4MHz。硬件连接上ADS122U04的CS、SCLK、DIN、DOUT、DRDY五个引脚接到STM32的SPI1和GPIO。DRDY是数据就绪中断接到STM32的EXTI引脚下降沿触发。SPI配置的关键参数时钟极性CPOL0时钟相位CPHA1数据大小8位MSB先行NSS软件管理。STM32CubeMX里配置SPI1为全双工主模式预分频器选8得到4.5MHz略高于4MHz但实测没问题。如果想保险选16分频得到2.25MHz。ADS122U04的SPI时序要求SCLK高电平至少50ns低电平至少50ns4MHz下周期250ns占空比50%时高低各125ns满足要求。DRDY中断的处理很关键。ADS122U04在转换完成后DRDY拉低STM32检测到下降沿后进入中断服务函数读取转换结果。注意DRDY在读取数据后会自动拉高但如果配置了连续转换模式DRDY会在下一次转换完成后再次拉低。我一般用单次转换模式每次需要数据时发命令启动转换等DRDY中断后再读这样时序可控。// STM32F303VE SPI1初始化代码片段 void SPI1_Init(void) { RCC-APB2ENR | RCC_APB2ENR_SPI1EN; RCC-AHBENR | RCC_AHBENR_GPIOAEN; // PA5SCK, PA6MISO, PA7MOSI GPIOA-MODER ~(GPIO_MODER_MODER5 | GPIO_MODER_MODER6 | GPIO_MODER_MODER7); GPIOA-MODER | (GPIO_MODER_MODER5_1 | GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1); GPIOA-AFR[0] | (5 20) | (5 24) | (5 28); // AF5SPI1 SPI1-CR1 SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_CPOL | SPI_CR1_CPHA; SPI1-CR1 | SPI_CR1_SPE; }3.2 ADS122U04寄存器配置与转换流程ADS122U04有四个配置寄存器分别控制多路复用器、增益、数据速率、IDAC电流、参考选择等。上电后先发RESET命令0x06然后写配置寄存器。我一般用以下配置寄存器0MUX选择AIN0-AIN1增益1PGA使能寄存器1数据速率20SPS连续转换模式关闭内部参考关闭寄存器2IDAC1250μAIDAC2250μAIDAC路由到AIN0和AIN3寄存器3IDAC电流源使能参考选择外部REFP/REFN配置完成后发START/SYNC命令0x08启动转换。转换完成后DRDY拉低STM32读取24位数据。读取时先读3个字节然后组合成24位有符号数。注意ADS122U04的数据是二进制补码格式最高位是符号位。// 读取ADS122U04转换结果 int32_t ADS122U04_ReadData(void) { uint8_t buf[3]; int32_t result; ADS122U04_CS_LOW(); while(ADS122U04_DRDY_PIN); // 等待DRDY拉低 buf[0] SPI1_Transfer(0x00); buf[1] SPI1_Transfer(0x00); buf[2] SPI1_Transfer(0x00); ADS122U04_CS_HIGH(); result ((int32_t)buf[0] 16) | ((int32_t)buf[1] 8) | buf[2]; if(result 0x800000) { result | 0xFF000000; // 符号扩展 } return result; }3.3 温度换算与校准算法ADC读到的原始码值需要换算成温度。对于PT100先用比率式公式算电阻Rrtd Rref × (Code_rtd / Code_ref)。但ADS122U04的参考电压是外部参考ADC码值直接对应输入电压与参考电压的比值。具体来说Code (Vin / Vref) × 2^23 × Gain。所以Rrtd Rref × (Code_rtd / Code_ref)其中Code_ref是参考电阻的码值。但实际电路中参考电阻和RTD不是同时测量的而是分时复用。所以需要先测参考电阻的码值再测RTD的码值。ADS122U04的内部多路复用器可以切换参考输入但外部参考电阻是固定的所以参考码值只需要测一次之后用固定值即可。不过为了消除温漂最好定期重新测量参考码值。算出电阻后用Callendar-Van Dusen方程换算温度。对于0℃到850℃范围公式是R(t) R0 × (1 A×t B×t²)其中R0100ΩA3.9083e-3B-5.775e-7。反解t可以用二次方程求根公式或者用查表加线性插值。我一般用查表法把-200℃到850℃的电阻值做成表每1℃一个点然后线性插值。这样计算量小精度也够。// PT100电阻转温度查表线性插值 float PT100_ResistanceToTemp(float resistance) { const float temp_table[] {-200, -199, ..., 850}; const float res_table[] {18.52, 18.92, ..., 390.48}; int i; for(i 0; i TABLE_SIZE - 1; i) { if(resistance res_table[i] resistance res_table[i1]) { float ratio (resistance - res_table[i]) / (res_table[i1] - res_table[i]); return temp_table[i] ratio * (temp_table[i1] - temp_table[i]); } } return -999; // 错误 }实操心得查表法虽然简单但表的大小要权衡。1℃间隔的表有1051个点每个点4字节浮点数占4KB Flash对STM32F303VE的256KB Flash来说不算什么。如果嫌大可以每5℃一个点插值误差在0.01℃以内完全够用。4. 工业与HVAC场景下的抗干扰与校准实战4.1 模拟前端布局与滤波设计工业现场的电磁干扰是温度测量最大的敌人。我见过变频器旁边RTD读数跳变±5℃的案例最后查出来是RTD引线没有屏蔽而且和电机线捆在一起走。ADS122U04虽然内置了50/60Hz陷波滤波器但那是数字滤波器对高频干扰无能为力。模拟前端的布局和滤波才是第一道防线。PCB布局上ADS122U04的模拟输入引脚要尽量短RTD引线进来先过共模扼流圈再并一颗100nF的C0G电容到地然后串一颗10Ω电阻再并一颗10nF电容到地。这是典型的π型滤波截止频率约1.6MHz对射频干扰有很好的抑制。参考电阻要靠近REFP/REFN引脚走线对称避免引入热电动势。地平面要完整模拟地和数字地单点连接连接点选在ADC下方。HVAC场景还有个特殊问题风机和压缩机启停时会产生很大的浪涌电流通过空间耦合到RTD线上。我一般会在RTD输入端加TVS管比如SMBJ5.0A钳位电压9.2V能吸收几百瓦的浪涌。虽然ADS122U04的输入有ESD保护但那是针对人体静电模型的对浪涌无能为力。4.2 系统校准与误差分析再好的硬件也需要校准。我的校准流程分三步零点校准、满量程校准、多点校准。零点校准用冰水混合物0℃满量程校准用沸水100℃注意海拔修正多点校准用标准温度计对比。校准时要等系统热稳定一般通电30分钟后开始。误差来源主要有几个参考电阻初始精度、参考电阻温漂、RTD自身精度、ADC增益误差、ADC偏移误差、引线电阻。参考电阻选0.01%精度、2ppm/℃的初始误差0.01℃等效温漂在-40℃到125℃范围内约0.033℃可以接受。RTD选A级PT1000℃时误差±0.15℃这是最大的误差源。ADC增益误差典型值0.005%偏移误差1μV换算到温度约0.0026℃可以忽略。引线电阻对三线制RTD影响很大。假设引线电阻0.5Ω三线制补偿后残余0.1Ω换算到温度约0.26℃。所以引线要用粗一点的铜线或者用四线制。四线制完全消除引线电阻但接线多两根成本高。我一般用三线制引线电阻控制在0.1Ω以内残余误差0.026℃可以接受。误差源典型值温度等效备注参考电阻初始精度0.01%0.01℃0.01% × 100Ω 0.01Ω参考电阻温漂2ppm/℃0.033℃-40到125℃165℃范围RTD精度±0.15℃0.15℃A级PT100ADC增益误差0.005%0.0026℃可校准ADC偏移误差1μV0.0026℃可校准引线电阻残余0.1Ω0.26℃三线制补偿后4.3 常见问题排查速查表调试这套系统时我遇到过各种奇怪的问题。有一次ADC读数一直是0x7FFFFF查了半天发现是SPI的CPHA配错了ADS122U04要求CPHA1我配成了0。还有一次读数跳变很大最后发现是IDAC电流源没使能RTD上根本没有电压。下面整理一个速查表方便快速定位问题。现象可能原因排查方法解决方法读数恒为0x7FFFFFSPI时序错误用逻辑分析仪抓SPI波形检查CPOL/CPHAADS122U04要求CPOL0,CPHA1读数跳变±5℃干扰耦合示波器看RTD引线加屏蔽、滤波、TVS读数恒为0IDAC未使能测RTD两端电压配置寄存器3使能IDAC读数随温度变化但偏差大参考电阻精度差测参考电阻实际值换0.01%精度电阻DRDY一直不拉低转换未启动检查START命令发0x08启动转换读数噪声大PGA增益过高降低增益试试增益1或2别用128多通道串扰多路复用器切换慢增加切换延时切换后等1ms再启动转换避坑技巧ADS122U04的DRDY引脚是开漏输出需要上拉电阻。我一开始没加上拉DRDY一直高电平以为芯片坏了。后来加了10k上拉到3.3V一切正常。数据手册里写了但很容易忽略。5. 从原型到产品的工程化考量5.1 电源设计与功耗优化ADS122U04的模拟电源AVDD和数字电源DVDD都是2.3V到5.5V我一般用3.3V单电源。但要注意AVDD的噪声直接影响ADC性能所以AVDD要用LDO单独供电比如TPS7A4700噪声只有4μVrms。DVDD可以和STM32共用3.3V但要在靠近ADC的地方加磁珠和电容隔离。功耗方面ADS122U04在20SPS、增益1、IDAC 250μA时电流约1.5mA。STM32F303VE在72MHz全速运行时约30mA如果做低功耗设计可以降到几mA。HVAC控制器一般有市电供电功耗不是问题。但如果是电池供电的无线温度传感器就得考虑低功耗模式。ADS122U04有单次转换模式转换完成后自动进入休眠电流降到0.1μA。STM32也可以进Stop模式用DRDY中断唤醒。这样平均电流可以做到100μA以下一颗CR2032电池能用好几年。5.2 温度范围扩展与传感器兼容PT100适合-200℃到850℃但HVAC场景一般只用到-40℃到125℃。如果要测更高温度比如工业炉的1000℃PT100就不行了得用热电偶。ADS122U04也支持热电偶测量但需要冷端补偿。ADS122U04内部有温度传感器精度±0.5℃可以用来做冷端补偿。但±0.5℃的精度对热电偶来说不够一般外接一颗高精度温度传感器比如TMP117精度±0.1℃。热电偶的接法和RTD不同。热电偶产生的是电压信号不需要激励电流。ADS122U04的PGA可以放大热电偶的微弱信号增益一般选32或64。参考电压用内部2.048V参考或者外部参考。冷端补偿的计算是T T_cj V_tc / S其中T_cj是冷端温度V_tc是热电偶电压S是塞贝克系数。K型热电偶的S约41μV/℃1000℃时电压41mV增益32后1.312V在满量程范围内。5.3 电磁兼容与安规设计工业产品要过EMC认证这套电路在辐射发射和传导发射上要特别注意。SPI时钟4MHz谐波会辐射到几十MHzPCB走线要短最好包地。IDAC电流源是恒流源对电源噪声不敏感但RTD引线是天线会接收空间干扰。我在RTD输入端加共模扼流圈和TVS辐射抗扰度能过10V/m。安规方面如果RTD引线延伸到设备外部要考虑隔离。ADS122U04没有隔离可以在SPI总线上加数字隔离器比如ISO7741或者用隔离电源给ADC供电。这样即使RTD引线碰到高压也不会损坏STM32。HVAC设备一般有安全隔离要求具体看IEC 60335标准。个人经验EMC测试中最容易出问题的是辐射发射尤其是SPI时钟的谐波。我一般把SPI时钟线走在内层两边包地过孔密集一点。如果还超标就在时钟线上串一颗22Ω电阻减缓上升沿。实测下来辐射能降6dB以上。6. 写在最后的实操体会这套ADS122U04加STM32F303VE的方案我从2019年用到现在前后做了七八个版本。最深的体会是高精度温度测量的瓶颈不在ADC而在模拟前端和校准。ADS122U04的24位分辨率确实厉害但如果参考电阻温漂大、RTD引线没屏蔽、地平面不完整精度照样上不去。我见过有人用ADS122U04测出来误差±2℃最后发现是参考电阻用了普通的1%厚膜电阻温漂100ppm/℃换了金属箔电阻后误差降到±0.1℃。另一个体会是SPI驱动看起来简单但时序细节很容易翻车。ADS122U04的SPI模式1和常见的模式0不同很多STM32的SPI例程默认是模式0直接拿来用会读不到数据。我建议先用逻辑分析仪抓一下波形确认CPOL和CPHA对了再调代码。还有DRDY中断一定要用下降沿触发而且中断服务函数里要尽快读数据否则下一次转换完成会覆盖。最后分享一个小技巧ADS122U04的内部温度传感器可以用来监测芯片温度虽然精度只有±0.5℃但用来做温度补偿或者过热保护足够了。配置寄存器里使能内部温度传感器然后像读RTD一样读码值换算公式在数据手册里有。我一般用它来监测PCB温度如果超过85℃就降速或者报警防止芯片过热影响精度。