☰
基于ADS122U04与STM32F767的高精度温度测量方案:RTD与热电偶信号链设计
2026/11/5 8:38:51 网站建设 项目流程

工业现场和暖通空调系统里的温度测量,看着是个“基础功能”,但真正做起来就会发现:风管里那根PT100的阻值变化可能只有零点几欧姆,热电偶的输出甚至是微伏级的,而旁边就是变频器、压缩机和电磁阀带来的强干扰。我最近用TI的ADS122U04IPWR这颗24位ADC,搭配STM32F767BI,做了一套能同时测RTD和热电偶的测温单元,在这里把这套方案的选型、接线、通信和校准过程完整拆一遍,给正在搞温控仪表、HVAC控制器或者工业数据采集的朋友做个参考。

1. 选型逻辑:为什么用UART接口的24位ADC搭配F767

先说结论:ADS122U04IPWR并不是市面上最热门的温度ADC,SPI接口的ADS1220、ADS124S08可能更多人用,但我这套项目里特意选了UART版本。原因很实在——STM32F767BI作为主控时,UART资源很富裕,而且一根TX一根RX就能和ADC通信,在隔离设计时也比SPI简单。

1.1 温度信号的特点决定了ADC的底线

PT100在0℃时电阻100Ω,温度每变化1℃电阻只变化约0.385Ω。如果整个测量回路里流过1mA激励电流,那么1℃对应的电压变化只有0.385mV。K型热电偶更夸张,输出大约40μV/℃。这意味着ADC的分辨率必须到微伏级才有实际意义。

用MCU自带的12位ADC来做,哪怕参考电压是3.3V,最低有效位(LSB)也有3.3V/4096≈0.8mV,根本没法直接分辨0.1℃的温度变化。所以外挂一个高精度ADC不是可选动作,而是必需品。ADS122U04IPWR的24位无失码分辨率,加上内置可编程增益放大器(PGA),正好把微伏级信号放大到ADC能“看清楚”的范围。

1.2 ADS122U04省掉的不是一颗芯片,而是一堆外围

ADS122U04这个型号,最吸引我的三点:

  • 内置两个匹配良好的激励电流源:给PT100或者NTC提供恒流激励,电流大小可配,省掉外置恒流源或精密电阻网络。
  • 内置PGA和24位Δ-Σ调制器:不需要额外搭仪表放大器,信号进来直接放大、直接转换。
  • UART接口:例如MCU侧一个波特率115200的串口,直接用命令字配置ADC、读取转换结果。

对比传统的“传感器+仪表放大器+独立ADC+SPI隔离”方案,ADS122U04把整个模拟前端压缩成了一颗TSSOP-16封装的芯片。而且这颗芯片支持多通道输入,可以通过内部多路开关在不同传感器之间切换,做多路测温时外围非常清爽。

1.3 STM32F767BI在这里更像“计算大脑”而非“控制大脑”

STM32F767BI(LQFP208封装、2MB Flash)在这套系统里的角色,一开始我把它定义成“读ADC然后上报”,后来发现远远不够。Cortex-M7内核带FPU和DSP指令,主频216MHz,用来跑温度线性化算法非常轻松。尤其是热电偶的冷端补偿和PT100的ITS-90多项式拟合,涉及大量浮点运算,如果用便宜的M0/M3芯片,算起来虽然也能跑,但要想在几百毫秒内完成多通道平滑滤波、断线检测和协议封装,F767的余量会大得多。

更重要的是F767的UART外设足够多,除了和ADS122U04通信那一路,还能留出好几路给RS485、Wi-Fi模块或者调试串口。我的板子上就是F767的一个UART接ADS122U04,另一个UART通过RS485往PLC上报温度值,互不干扰。

2. 信号链设计:前端传感器与模拟电路的实际接法

选型定了,接下来就是画原理图。这个环节最容易出问题的地方不在ADC本身,而在传感器怎么接入。很多人以为把传感器信号随便接上就行,结果读出来的数据满屏乱跳,然后怪ADC不行——其实多半是前端没处理好。

2.1 PT100的三线制接法和恒流源配置

PT100测温最经典的是三线制:一根线接激励电流,一根线接电压采样,还有一根公用线。目的很明确:消除导线电阻的影响。ADS122U04内置两个激励电流源,可以配置成IDAC1和IDAC2分别输出到不同引脚。我的接法是这样:

  • IDAC1输出电流经PT100的激励线到传感器,再从PT100另一端经过公用线回到AGND。
  • 电压采样引脚AIN0和AIN1分别接PT100的两根测量线。

注意一个细节:激励电流不要开太大。1mA电流在250Ω的PT100上产生250mV压降,这个电压在PGA增益小于8时不会超量程。但如果电流开2mA,低温段压降更大,PGA增益就得调小,反而影响分辨率。所以我推荐PT100用1mA,如果传感器线很长,可以适当减小到0.5mA,代价是信号幅度减半,需要把PGA增益调高一档。

2.2 热电偶的冷端补偿与单端转换

热电偶输出的是热端和冷端的电势差,所以必须要知道冷端温度。ADS122U04内部有一个温度传感器,可以用来检测芯片附近(也就是冷端)的温度。这里有个容易搞错的点:热电偶信号是“单端”的,因为参考端接地,但热电势很小,最好把热电偶负端接到ADC的AINn,正端接AINp,同时将输入配置为伪差分,避免地线上的噪声窜进来。

冷端温度传感器数据读出来后,通过查表或多项式计算出对应毫伏值,加到热电偶的测量毫伏上,再反查热端温度。这一步在后面第4节详细说。

2.3 电源、滤波和PCB布局对24位分辨率的直接影响

24位ADC对电源噪声极其敏感。ADS122U04的AVDD和DVDD最好分开供电,或者说至少用LDO单独给模拟部分。我在这块板子上用的是3.3V LDO,输入端加了一个10μF钽电容和0.1μF瓷片电容并联,模拟地和数字地在ADC芯片下方单点连接,最小限度减少数字噪声回流到模拟地的路径。

PCB布局上,传感器输入引脚要避免和串口、电源走线平行。我第一版PCB就是吃了这个亏:ADC的AIN0走线贴着UART的TX线,结果串口发送数据时,温度读数会周期性跳变几十个LSB。后来把传感器走线移到板子边缘,并且加了300Ω串联电阻和1nF对地电容做RC滤波,问题才消失。

3. STM32F767BI与ADS122U04的UART通信实现

ADS122U04和普通SPI ADC最大的不同,就是通过UART来控制。这套通信方式不复杂,但有几个小坑值得写出来。

3.1 硬件连接:从电平到共享地

ADC的UART引脚和STM32F767BI的UART直接连就行,因为都是3.3V电平。如果为了抗干扰要做电气隔离,那就在MCU和ADC之间加数字隔离器,比如ISO7721,这样ADC前端模拟部分还能和系统完全隔离开。

唯一要重点确认的是波特率不要设太高。ADS122U04的UART最高支持多少我没有刻意跑极限,稳定起见用了115200bps。实际测试中,115200bps下连续读寄存器没有出现过误码。如果布线距离超过10cm,建议降到57600或38400,毕竟这是数据采集不是传文件,慢一点换稳定性完全值得。

3.2 寄存器配置与命令字:只写必要的几个配置项

ADS122U04的寄存器不多,主要控制输入多路开关、PGA增益、数据速率、激励电流源等。初始化时我这样配:

  • 设置输入通道为AIN0/AIN1差分输入
  • PGA增益设为8(配合1mA激励,PT100满量程时内部ADC输入不超过2V)
  • 数据速率设为100SPS(工频50Hz环境,用100SPS时内置50/60Hz抑制滤波器能发挥一定作用)
  • 激励电流源1设为1mA,连接到AIN0通道

这些配置通过UART发送命令字完成。具体命令字格式,数据手册里有表格,但实践中最容易错的是“命令字+数据”的先后顺序,少发一个字节可能导致配置全乱。我的建议是配置完后读一遍所有寄存器回读验证,千万别只发不看。

3.3 一次典型读取时序与代码骨架

ADS122U04的转换结果读取逻辑是:切换通道、启动转换、等待DRDY变低(或者读状态)、读取数据。我用的是查询DRDY引脚的方式,这个引脚在ADS122U04上可以配置为中断输出。F767这边把DRDY接到一个GPIO的外部中断上,来中断后才去UART读数据,这样可以避免轮询浪费CPU时间。

代码骨架大致是这个样子:

// 初始化UART1,波特率115200 // 配置ADS122U04寄存器0,选择AIN0/AIN1差分输入,PGA=8 adc_write_reg(0x01, 0x30); // 配置寄存器2,激励电流1mA,使能内部温度传感器 adc_write_reg(0x02, 0x10); // 启动连续转换 adc_start(); while (1) { if (DRDY_InterruptFlag) { DRDY_InterruptFlag = 0; raw_value = adc_read_data(); // 读取24位原始数据 temperature = rtd_linearization(raw_value); } }

这里有一点要注意:读数据命令返回的是3字节24位数据,需要自己拼接成int32。ADS122U04是二进制补码输出,负温度时读回的值是负的,所以拼接时要用带符号扩展,不然负温度会变成一个大正数,导致后面的换算全错。

4. 温度换算数学与校准流程

拿到原始码只是第一步,把原始码变成准确温度才是真正体现水平的地方。

4.1 RTD线性化:从电阻到温度的ITS-90查表

PT100的电阻-温度特性是非线性的,0℃到100℃之间还好,超过100℃偏差会明显增大。我用的查表法结合线性插值:

  • 先把原始码换算成电阻值:R = (raw_value - offset) / (code_per_ohm)
  • 然后查PT100分度表,在电阻值所在的两个温度点之间做线性插值。

这个方法在-50℃到400℃范围内误差可以做到±0.2℃以内,前提是分度表足够密。如果你连分度表都不想查,也可以用Callendar-Van Dusen方程拟合,但那个公式处理0℃以下时要分段,容易出现拟合误差。

4.2 热电偶查表与冷端补偿计算

热电偶比RTD麻烦,因为需要两步查表。以K型热电偶为例:

  1. 读取ADS122U04内部温度传感器数值,得到冷端温度T_cold(单位℃),通过K型分度表查表得到冷端对应的毫伏值E_cold。
  2. 实际测量的热电势为E_measure,那么热端总毫伏E_total = E_measure + E_cold。
  3. 用E_total再查表反推出热端温度。

这里要特别提醒:冷端温度传感器读出来的是ADC芯片自身温度,它需要尽可能靠近热电偶的接线端子。如果板子上ADC离接线端子太远,中间又有电源芯片发热,冷端补偿会有好几度的偏差。我的板子上在接线端子附近放了一颗LM60温度传感器,但最后还是直接用ADS122U04内部温度传感器做补偿,因为它的读数稳定,只要保证板子整体温度均匀即可。

4.3 两点校准和自动补偿的实操

硬件总有误差,ADC的偏移误差和增益误差可以通过校准来补偿。我的校准方法是:

  • 零点校准:把PT100换成一个精密100Ω电阻(或者直接把输入短接),记录ADC输出码值,记为code_zero。
  • 满度校准:用一个精密300Ω电阻(模拟100℃附近的PT100阻值),记录ADC输出码值,记为code_span。
  • 那么实际电阻值R = 100Ω + (raw_code - code_zero) / (code_span - code_zero) * 200Ω。

这套两点校准能消除大部分偏移和增益误差。校准之后,我拿标准铂电阻温度计做了对比,在0℃到200℃范围内,系统误差基本在±0.15℃以内。

5. 工业与HVAC现场最常见的四个坑

实验室里数据好好的,一到现场就出问题,这是温控系统的常态。我把实际项目里遇到最多的四类问题列出来,每一个都交过学费。

5.1 工频干扰与共模电压

HVAC现场有压缩机、大功率风机,工频干扰非常严重。ADS122U04内部有数字滤波器,但在50Hz环境下,数据速率最好选择100SPS或者100SPS的分频模式,这样滤波器的陷波点正好落在50Hz及其谐波上。

如果读数仍然波动严重,检查一下传感器线是不是采用了屏蔽线,屏蔽层是否单端接地。我的经验是:屏蔽层在ADC板子这端接地,另一端悬空,这样能有效避免地环路电流。

5.2 长线压降和激励电流选择

当传感器离采集板超过30米时,激励电流在导线上的压降会直接影响测量。三线制PT100好一些,因为电压采样线不流电流。但激励电流源那条线的压降可能让电流源无法正常工作。解决办法是提高激励电流源输出电压范围?实际上ADS122U04的电流源是靠内部稳压,如果导线电阻太大导致电流源端口电压不够,激励精度会下降。

我的处理方式:现场布线尽可能用0.5mm²以上的导线,同时将激励电流降到0.5mA,减小导线上压降。如果距离超过50米,我倾向直接改用4-20mA变送器,把温度转成电流信号远传,本地不再做电阻测量。

5.3 传感器断线诊断

工业现场传感器线断开是家常便饭,如果不能及时发现,系统会把满量程电压当成高温,引发误动作。ADS122U04支持输入开路检测?这个特性我记得在ADS1220上可以通过寄存器配置实现,但我没有依赖它。更好的方法是软件诊断:

  • 持续监测原始码,如果长时间(比如20秒)异常偏高且不变化,判定为断线。
  • 或者在传感器回路串联一个已知电阻,通过检测有无电流流过来判断通断。

我的项目里用的方案是:周期性地关掉激励电流源,然后读一次ADC值。如果传感器正常,关掉激励后读数会归零;如果断线,读数可能依然是一个很大的值。这样就能实现低成本断线检测。

5.4 看门狗与通信超时恢复

STM32F767BI和ADS122U04之间是UART通信,偶尔会出现总线上的毛刺导致ADC状态机卡死。这种时候如果程序还在死等DRDY,系统就“假死”了。所以我给F767开了独立看门狗(IWDG),同时UART采用超时重发机制:如果500ms内没有收到有效数据,就发送一次ADC复位命令(通过UART命令字),重新初始化寄存器。这个机制上线后,整个系统在三个月无人值守运行中,没有出现一次需要人工重启的情况。

6. 一点实测体会

这套“ADS122U04IPWR + STM32F767BI”的组合,我前前后后改了三版PCB,从最早的双面板手工焊接,到后来的四层板批量测试,目前已经稳定跑在两条HVAC生产线的温度采集节点上。

如果你也要做类似项目,我最想强调的是:别急着写代码,先把模拟前端和PCB布局搞定。24位ADC对布线、电源和地的敏感性远超想象。我第一版PCB之所以数据跳,并不是芯片问题,而是走线太随意。另外,温度换算的查表表项要预先在Excel里生成好,烧进MCU时用const数组存着,不要在运行时实时做多项式计算——虽然有F767的FPU,但查表永远是最快最稳的。

这套方案目前用于测量风管温度、冷水供回水温度和几个关键设备表面的温度,整体误差控制在±0.2℃以内,满足暖通行业对舒适度控制和能耗计量的要求。如果后续要扩展更多通道,ADS122U04的4个输入通道可以级联使用,或者用F767的另一个UART再接一颗ADC,两条总线并行读取,灵活度很高。

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

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

立即咨询