ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

STM32F7+ADS122U04:基于UART接口的高精度RTD/热电偶测温方案

STM32F7+ADS122U04:基于UART接口的高精度RTD/热电偶测温方案

在 HVAC 和工业温度采集项目里,最让人头疼的往往不是传感器选型,而是从模拟小信号到数字温度这条路怎么走稳。我最近做的一套方案里,主控用了 STM32F723ZE,ADC 选了 TI 的 ADS122U04IPWR,专门用来做冷冻水、风管和工业管道表面温度测量,实测下来精度和稳定性都达到了预期。这篇文章把这个项目的完整做法拆开来讲,包括为什么挑这两个芯片、硬件怎么接、UART 通信怎么对、温度怎么换算、现场又踩了哪些坑,给正准备做同样事情的朋友做个参考。

如果你做的也是多通道 RTD 或热电偶采集、HVAC 控制器、工业现场仪表这类项目,这套选型思路大概率对你有用。ADS122U04IPWR 这类带 UART 接口的高精度 ADC,能把传感器调理和模数转换统统包掉;STM32F723ZE 负责协议解析、控制逻辑和后续通信。两者配合,既避开了 SPI 的长线困扰,也省掉了大量分立模拟电路,属于一种相当务实的工业测温架构。

1. 从实际需求说起:这套组合能解决什么

1.1 工业与 HVAC 测温的共同痛点

先说场景。HVAC 里要测冷冻水供回水温度、循环水泵进出口温度、新风和回风温度;工业现场则可能是管道表面温度、电机轴承温度、换热器进出口温度。这些工况表面上差别很大,其实对测温电路的挑战非常一致。

首先是信号小。PT100 在 0°C 附近灵敏度只有 0.385Ω/°C,配合 250µA 激励电流,温度每变化 1°C 只产生大约 96µV 的电压变化,这个量级直接进 MCU 的 ADC 根本量不准。热电偶更离谱,K 型热电偶灵敏度大约 41µV/°C,如果没有足够增益和低噪声前端,读出来的数基本没法用。

其次是现场干扰。HVAC 里有变频器、风机、水泵,工业现场还有大电机和开关柜,这些设备一启动,电网里全是毛刺。温度信号变化又慢,如果 ADC 没有内置数字滤波或者没有合理的采样率匹配,50Hz 和更高频干扰很容易叠到信号上,造成读数无规律地跳。

再有就是布线距离。传感器往往不在控制板旁边,一根线拉出去十几米甚至几十米很正常。普通 SPI 接口的 ADC 在这么长的距离下基本没法稳定工作,而 UART 接口天然适合稍长距离的传输,也方便转成 RS-485 差分信号。

1.2 为什么是 UART 接口的 ADC 而不是 SPI

很多工程师习惯用 SPI 接口的 ADC,比如 ADS1220。SPI 确实快,但它的代价是至少四根信号线:SCK、MOSI、MISO、CS。信号是同步传输,SCK 一抖,数据就错位。在工业现场,这么一组时钟线拉到传感器端,要么降速,要么加缓冲器,麻烦得很。

ADS122U04IPWR 从型号上就能看出来,它就是 ADS1220 的 UART 版本。寄存器、内部结构基本同源,但通信物理层从 SPI 换成了两线 UART。我认为这个改动在这个场景下是最大的价值:两线制天然适合点对点远距离,想再接一个 RS-485 收发器就变成差分长线总线,抗干扰能力会再上一个台阶。

主控这边,STM32F723ZE 有大量可用 UART,根本不需要像选 SPI 那样抢引脚。我用一片 STM32 同时带两片 ADS122U04IPWR,分别负责不同区域的温度采集,软件上各自配一个 DMA 通道,互不干扰。这个架构在 HVAC 多测点项目里非常方便。

1.3 方案的目标与适用边界

这套方案我定位在"中等精度、多点位、工业环境可用"这个档位。只做单点、PCB 板载测温的话,用芯片内置 ADC 就够了,没必要外挂这种级别的东西。但如果你要做出能够长期稳定运行、读数可信、现场还能校准的测温节点,那么高精度 ADC 加专用主控的组合就是绕不开的。

我用它做过两种传感器:PT100 铂电阻和 K 型热电偶。PT100 用于 HVAC 水温测量,热电偶用于工业管道表面温度。两种传感器共用同一块硬件和同一个固件框架,区别只在寄存器配置和温度换算算法上。这个"固件分模式、硬件共用"的思路,在小批量项目里能节省大量开发和调试时间。

2. ADS122U04IPWR 真正好用的地方与配置策略

2.1 24 位 Δ-Σ 架构与前端集成带来的便利

ADS122U04IPWR 的核心是 24 位 Δ-Σ ADC。很多人一看到 24 位就觉得精度无敌,其实真正决定有效精度的不是位数,而是噪声和前端设计。这块芯片能把有效噪声压到很低,配合 PGA 增益,放大微弱信号的能力相当能打。

我更看重的是它把一堆模拟电路都集成进去了。芯片内部有可编程增益放大器、两个可编程电流源、内部温度传感器,还支持外部基准输入。这意味着我做 RTD 测量时不用再外接精密恒流源,做热电偶时不用额外挂一颗冷端补偿温度传感器,模拟前端这块电路被极大简化。

内部温度传感器这个功能千万别忽略。做热电偶时冷端补偿是必须的,以前常见做法是在端子附近贴一个 NTC 或者 LM35,再接一路 ADC 采集环境温度。现在直接用 ADC 内置的温度传感器,读出来就是芯片结温,再配合端子处的温度修正,不仅省一路模拟通道,软件也好做。

2.2 我实际使用的寄存器配置模板

这块芯片有四个可写配置寄存器,全部通过 UART 命令进行读写。我不建议从一开始就盯着寄存器表逐个位去拼,那样极容易出错。我的习惯是先在 TI 评估板上跑通,把需要配置的寄存器初值固化到工程里,然后针对项目调整输入通道和增益。

以下是我做 PT100 测温时实际用到的关键配置项:

配置项我的取值说明
输入 MUXAIN0 / AIN1 差分接 PT100 的检测端
PGA 增益8兼顾分辨率和输入量程
激励电流 IDAC250µA给 PT100 提供恒流激励
外部基准电阻 RREF2.0kΩ,0.05%构成比例式测量的参考电压
数据速率20SPS数字滤波效果较好,读数稳定

这套配置算出来的参考电压大约是 250µA × 2kΩ = 0.5V。PT100 在 0°C 到 100°C 范围上,差分电压差不多是 25mV 到 34.6mV,经过 PGA 放大 8 倍后是 200mV 到 277mV,离 0.5V 满量程还有充足裕量。这样既不会饱和,又把整个温度范围分配到了足够多的 ADC 码上。

热电偶模式下我会把 PGA 调到 64 甚至 128,用内部 2.048V 基准,关闭电流源,MUX 接热电偶输入。K 型热电偶在常温范围输出电压只有几毫伏,高增益放大后才好用。

2.3 UART 通信与帧同步细节

ADS122U04IPWR 的 UART 是标准 8N1 格式,波特率默认不高。项目最初我按默认波特率跑,通信非常稳定。它没有像 Modbus 那样复杂的应用层,就是主机发命令、从机回数据,常用命令无非是写寄存器 WREG、读寄存器 RREG、读转换结果 RDATA 这几个。

这里有个很关键的帧同步问题。UART 是字节流,没有片选线,接收端必须自己确认"一条数据帧从哪里开始"。如果上电后第一帧就对不齐,后面读到的三个字节可能整体错位,读出来的 24 位数据完全是乱的。我后来固化了一个流程:每次上电后先发一条 NOP 命令探路,再清一次接收缓冲,最后才发 RDATA。这套流程跑下来基本不再出现首帧错乱。

CRC 我也建议根据现场距离决定。短距离、现场干扰小的时候可以不校验,省一点开销;长线传输或者 RS-485 场景下一定要开。开启 CRC 后每条数据帧末尾会多一个校验字节,为了这一点点开销买来的是整个读数的可信度,很划算。

3. STM32F723ZE 一侧的设计:接口、电源与工程架构

3.1 硬件接线与供电参考设计

STM32F723ZE 是 LQFP144 封装的 Cortex-M7 芯片,主频 216MHz,Flash 512KB,用来跑温度采集逻辑绰绰有余。我和 ADS122U04IPWR 的连接很简单:STM32 的 USART1_TX 接 ADC 的 RXD,USART1_RX 接 ADC 的 TXD,交叉连接,共地。两边都是 3.3V 电平,直连即可,不用加电平转换。

真正决定成败的是电源和参考电压。ADC 是精密模拟器件,最怕的从来不是算力不足,而是电源不干净。我第一版因为偷懒,给 ADC 的 AVDD 和 DVDD 都直接接了板上的 3.3V 开关电源输出,结果零漂非常夸张。后来改成 LDO 供电,AVDD 和 DVDD 之间又加了一级 RC 隔离,才把数据稳住。

模拟地 AGND 和数字地 DGND 也要特别处理。正确的做法是在 ADC 下方做单点连接,然后整个模拟地独立走线,不要在数字电路里绕一圈再回来。参考电压那边我最开始用的内部基准,精度其实也够,但后来为了做比例式 RTD 测量,改成了外部精密电阻 RREF,实测温漂明显小于内部基准方案。

3.2 UART 驱动与 ADC 数据读取代码骨架

主控这边我代码框架非常清晰:一个底层 UART 驱动,一个 ADC 命令封装层,再往上就是具体的温度传感器逻辑。UART 初始化无非是 8N1、对应波特率、使能接收中断或者 DMA。温度采集这种慢速传感器,用轮询其实都能扛住,但我在 DMA 模式下实现确实会更省心,MCU 不用一直等字节。

读一次温度的流程可以概括成下面这段逻辑:

void ads122u04_read_temp(float *temperature) { uint8_t cmd_rdata = 0x1D; // 示例命令,具体值查手册 uint8_t buf[4]; int32_t raw = 0; uart_clear_rx(); // 清空接收缓冲,防止旧帧残留 uart_send(&cmd_rdata, 1); // 发送 RDATA 命令 uart_receive(buf, 4); // 接收转换结果(加上 CRC 是 4 字节) raw = ((int32_t)buf[0] << 16) | ((int32_t)buf[1] << 8) | ((int32_t)buf[2] << 0); if (raw & 0x800000) raw -= 0x1000000; // 转成有符号 24 位 *temperature = convert_raw_to_celsius(raw); }

这段代码只展示了读取和符号处理,真正干活的是 convert_raw_to_celsius 这个函数。温度换算的完整逻辑放在下一节详细说。要注意接收缓冲区大小必须和 CRC 选项匹配,否则少读一个字节,下一次收发时序全乱。

3.3 多片 ADC 的扩展思路

我后来为了接更多测点,在两块板之间并联了第二片 ADS122U04IPWR。最简单可靠的办法是给每片 ADC 分配一路 UART,互不干扰;如果引脚不够,可以考虑用 RS-485 做半双工总线,但这种情况下需要认真处理总线冲突和应用层寻址,开发量会大不少。

对大多数 HVAC 项目来说,单板上带两三片小数量的 ADC 就已经能覆盖整栋楼的主要温度测点了。我的建议是先用独立 UART 把功能做稳,再把总线化作为后期优化项。工程上最怕的就是一开始就上复杂架构,结果连基础通信都调不通。

4. 温度换算链路:从原始码到真实摄氏度

4.1 比例式 RTD 测量与电阻计算

RTD 测温最推荐的做法是比例式测量,这也是 ADS122U04IPWR 这类带电流源和外部基准输入的电信号 ADC 最能发挥优势的地方。原理很简单:同一路电流源驱动 RREF 产生参考电压,另一路电流源驱动 RTD 产生测量电压,因为两条支路电流同源,ADC 的输出比例就等于两个电阻的比例。

换算成公式是这样:

RRTD = (ADC_Code / 8388607.0f) * RREF;

这个式子里,参考电阻的精度和温漂直接决定最终精度。我用的是 2kΩ、0.05% 精度、温漂 10ppm/°C 的金属箔电阻,这个级别在工业温度测量里已经相当可靠。如果还想更高,可以选 5ppm 甚至更低温漂的型号,代价是价格翻倍,大多数 HVAC 场景没必要。

比例式测量带来的好处是激励电流的温漂和电压基准的漂移都被抵消了。不管电流源实际输出是 250µA 还是 255µA,只要 RREF 和 RTD 流过的是同一路电流,ADC 采到的始终是电阻比值,最终换算成温度的误差就只剩下 RREF 本身的漂移。

4.2 PT100/PT1000 线性化

拿到 RRTD 之后,还要把电阻值换算成温度。PT100 的电阻-温度特性不是完全线性的,0°C 到 100°C 之间大约有 10°C 量级的非线性误差,直接按线性公式算会有偏差,HVAC 上可以接受,工业上通常不行。

我做工程时很少上完整的 Callendar-Van Dusen 公式,那个多项式算起来有点重,更适合写论文。实际项目里我用的方法是:在需要的温度范围内查标准分度表,然后用分段线性插值。比如把 0°C 到 300°C 每 10°C 一个表项,单片机的 Flash 大得很,多存几十个 float 根本不心疼。这个方法实现简单、排查容易,精度也足够,是我比较推荐的做法。

如果你还是想用公式,可以把 CVD 公式简化之后只保留前两项,然后在代码里做个判断,高于 0°C 时用双项式,低于 0°C 时补一个三次修正项。这个方案比查表稍微难调一点,但胜在连续、不占 Flash。

4.3 热电偶冷端补偿

热电偶测的是热端和冷端的电势差,但冷端一般不可能一直保持在 0°C,所以必须做冷端补偿。ADS122U04IPWR 内置温度传感器就是我处理这个问题的利器。

软件流程是:先用内部温度传感器读出芯片附近的绝对温度,再根据这个温度查热电偶分度表,查出一个对应的热电势修正值。这个修正值加上实际测得的热电势,才是真正代表热端温度的热电势,接着再查一次分度表,得到热端温度。

听起来绕,但写熟了也就二三十行代码。这里有个容易忽略的坑:内置温度传感器测的是芯片结温,不是热电偶接线端子的温度。如果端子离芯片远,中间有空气对流或者发热源,结温和端子温度会有差别,导致补偿不准。我的做法是让热电偶冷端尽量贴近 ADC 的安装位置,再在整机校准时把这个系统偏差一起校准掉。

4.4 软件滤波与工频干扰

就算 ADC 本身底子好,也不建议直接把单次采样结果拿来用。温度信号是慢变量,多采几次再处理几乎不影响响应速度。我在固件里做了两级滤波:第一级是中值滤波,连续采 7 次,取中间值,用来挡掉偶发的毛刺;第二级是一阶低通,把滤波后的小波动再平滑一下,最终读数很稳。

工频干扰是行业里的永久话题。ADS122U04IPWR 提供多档数据速率,数字滤波器在每个速率下都有对应的陷波频率。想压低 50Hz 和它的谐波,就要把数据速率选在合适的档位上。我实际用的是 20SPS,在这个档位下芯片对工频干扰的抑制效果已经足够。如果你的系统里 60Hz 干扰更明显,则需要重新对照手册选速率,不能想当然。

5. 现场调试的踩坑与排查过程

5.1 UART 帧错位导致的读数漂移

第一个坑,也是我折腾最久的:读数在某个稳定温度附近小幅跳动,偶尔还会出现一个大跳变。一开始我怀疑是传感器接触不良,换了新 PT100 也没解决,后来用逻辑分析仪抓了 UART 波形才发现问题不在硬件,而在帧同步。

我的接收流程犯了一个典型错误:上电后立刻发 RDATA,但此时 ADC 可能刚完成上电复位,还没有准备好,回过来的数据只有两三个字节不完整。MCU 又从这一帧的开始位置收了四个字节,整条数据就整体错位了。

解决办法是上面提到的流程:上电后发 NOP 命令确认链路正常,把接收缓冲清空,等 ADC 完成一次完整转换后再启动正式读取。从那以后这套板子再也没出现过帧错位问题。这个坑的核心教训就是:异步串口通信里,帧开始位置的确定性比数据内容本身更优先。

5.2 电源噪声引发的零漂

另一个典型问题表现在零漂上。我把 ADC 的两个输入端短接,理论上应该读到接近 0 的稳定值,但实测数据能以每秒几十个 LSB 的幅度缓慢漂移,而且毫无规律。这个现象一看就是电源和地的锅。

排查过程是从简单到复杂:先换了一块干净的独立 LDO 给模拟电源,再在 AVDD 引脚附近加了 10µF 和 0.1µF 的去耦电容,最后把模拟地和数字地割开,只在 ADC 的散热焊盘下方做单点汇接。每做一步就测一次零漂,最终把漂移从几十 LSB 压到只有一两个 LSB。

这种问题最怕的不是难解决,而是你没有系统的排查方法。零漂测试应该是所有 ADC 板子的出厂必测项,把输入短路看底噪,比什么花哨指标都直接。我后来做新板子样板,第一件事就是测通道短路的零漂曲线,这条线稳了再谈精度。

5.3 长距离布线与隔离

传感器距离拉到十几米以后,直接 TTL UART 已经不行了,我在第二版硬件里给 ADC 侧和主控侧都加了 RS-485 收发器。A/B 线用屏蔽双绞线,屏蔽层单端接地,总线两端各接一个 120Ω 终端电阻。改完之后,50 米距离下通信依然稳定。

如果要进一步抗干扰,可以考虑在 UART 和 RS-485 收发器之间加数字隔离器。工业现场地电位差大的时候,隔离不是可选项而是必选项。我因为前期没隔离,已经吃过一次地环路烧模拟芯片的亏。现在凡是外接长线的板子,隔离器都直接做成标配。

6. 校准方法与长期运行维护

6.1 零点与增益校准步骤

芯片再准,系统也有装偏差。上电出厂的标称参数只能当参考,实际装到产品里必须做校准。我的校准流程分两步,全部在固件里完成,靠串口命令行触发。

第一步是零点校准。把 ADC 输入短接,或者说用内部短接功能,读出一个偏移码。这个偏移会反映在所有后续读数里,把它记录下来,在每次计算电阻值之前先减掉。

第二步是增益校准。用一只高精度电阻替代传感器,放在已知的阻值点,读到的码和理论码一比,就得到增益校正系数。如果要求更高,就做多点校准,比如在 0°C、100°C、300°C 三个温度点上分别标定,做二次多项式拟合。对 HVAC 来说两点校准已经绰绰有余。

校准系数我直接存在 STM32 内部 Flash 的末尾扇区,每次上电加载。注意千万别存在程序区里,否则一升级固件校准数据全没了,那会让人很难受。

6.2 影响长期精度的隐藏因素

长期运行中,影响精度的往往不是 ADC 芯片本身,而是外围三个环节。

第一个是参考电阻。它决定比例式测量的基准,温度系数差一点就直接换算到温度偏差。我在前文说过选 0.05% 和 10ppm/°C 起步,如果是长期不校准的现场设备,建议往 5ppm 去选。

第二个是接线端子的氧化和接触电阻。PT100 的激励电流只有 250µA,接触电阻引入的误差并不大,但氧化带来的热电势却是隐形杀手。接线端子尽量选抗氧化的弹簧端子或者镀金端子,每年巡检时重新拧一遍是必须的。

第三个是冷端补偿的长期漂移。结构件应力释放、胶体老化都会让热电偶端子周围的温度场发生偏移。项目里如果对温度绝对值要求严格,建议在整机层面保留一个环境温度校准周期,半年或者一年校准一次。

6.3 可以继续扩展的方向

这套方案做完了以后,我顺手给它加了一个 Modbus RTU 从站功能。STM32F723ZE 跑 Modbus 固件完全没压力,把温度测量结果和状态寄存器全部映射成标准 Modbus 寄存器,直接对接 PLC 和楼宇自控系统。HVAC 项目几乎都喜欢用 Modbus RTU 通信,这一步做完,整套测温节点的工程价值立刻上了一个台阶。

再往下扩展就是做成多节点系统:每块板带两片 ADS122U04IPWR,每个节点上报四路温度,通过 RS-485 总线串起来,上位机统一读取。这样的架构在中小型楼宇和工业车间里已经足够覆盖大多数需求。

最后说一句老实话:这套方案里,真正决定精度的不是我列的寄存器表,而是电源、参考电压和接地。UART 通信只要帧同步做好就不太会出问题,温度换算只要公式系数对就准了,但现场跑久了读数是漂的还是稳的,大部分还得看模拟前端基本功。我现在做样板时都会先测"通道短路输入"的零漂曲线,这条线稳了再谈精度。以后再扩展的话,可以挂 Modbus,也可以加第二片甚至第三片 ADC 做更多通道,路子已经铺开了。

返回列表