☰
STM32F767与ADS122U04的高精度RTD测温方案解析
2026/11/5 1:08:08 网站建设 项目流程

直接聊这个项目吧。用 ADS122U04IPWR 和 STM32F767ZG 做温度和 HVAC 场景的高精度测温,我拿到这个组合的第一反应是:方案选得挺有意思,一个带 UART 接口的 24 位 ΔΣ ADC,配一个主频 216MHz 的 M7 内核 MCU,看起来有点“大马拉小车”,但实际用过就会发现,这种搭配真正的好处是把模拟前端和数字处理的职责彻底分开了。ADC 只负责把微弱信号变成可靠的数字量,MCU 则有余力去做滤波、线性化补偿、协议解析甚至跑个简单的控制环路,而不是整天被时序打断。

这篇文章就把这套方案从头到尾拆开揉碎地讲一遍。包括为什么选这颗 ADC 而不是 SPI 接口的同门兄弟,硬件的关键设计点,固件驱动的框架,以及我在调试中踩过的坑和最终的校准流程。给正在做工业温度采集、楼宇自控或者设备状态监测的朋友一个可以直接参考的实践路径。不管你是刚接手类似项目,还是已经在用其他方案想换这条路,这篇文章应该都能帮你省下不少摸索的时间。

1. 项目整体设计与方案选型思路

1.1 为什么是 ADS122U04IPWR:不止是“带串口的 ADC”这么简单

ADS122U04IPWR 是 TI 推出的一款 24 位 ΔΣ ADC,最大的特点是把 SPI 换成了 UART 接口。很多人第一反应是这有什么稀奇的,少两根线而已。实际用过就会明白,差别远不止线数。

在工业现场,ADC 和 MCU 之间往往隔着一段距离。如果走 SPI,SCLK 和 CS 的时序约束在长线上非常麻烦,线一长,反射和串扰就会导致通信错误,你就得降速、加驱动芯片,甚至改用差分方式传输。而 UART 本身就是为异步通信设计的,只要波特率设对,两三米的普通双绞线完全没问题,而且对时序的要求低得多。更关键的是,ADS122U04 的 UART 接口层做了完善的数据包协议,帧头、命令、CRC 校验都替你考虑好了,MCU 端只需要把字节按照格式发过去和收回来就行,不需要去扣电平时序。这块向下兼容的功夫省掉的不只是工作量,更是排错难度。

再说芯片本身的模拟性能。ADS122U04 是真正的 24 位 ΔΣ 架构,不是那种用 16 位 ADC 过采样“软磨硬泡”出来的等效分辨率(说到这儿,我得提醒一下,市面上有些 24 位 ADC 实际有效分辨率只有 18 位出头,而 ADS122U04 在低增益、慢速模式下能够达到接近 21 位的有效分辨率,这个差距体现在实时性上就是后文会说的千万级工频干扰环境下还能稳定读到 0.01℃ 级别的变化)。内部集成了两个可编程激励电流源(IDAC)、一个低漂移参考电压源(内部 VREF,典型温漂 10ppm/℃)、可编程增益放大器(PGA,最高 128 倍增益),还带一个片上温度传感器。这些集成模块对 RTD 测温来说是刚需,外部只需要再配一个基准电阻、几颗滤波电容和必要的 TVS 保护管,就能完成整套模拟前端。相比用分立运放加基准源搭方案,这种集成度大幅降低了温漂和装配误差的来源。

另外值得一提的还有它的输入多路复用器。ADS122U04 支持 4 个差分输入或 7 个单端输入,并且可以用配置寄存器灵活切换。在 HVAC 的场景里,经常需要同时监测回风温度、送风温度、盘管进出口水温、室外环境温度等多个点位。一颗 ADC 配合一个模拟多路开关,就能覆盖 8 到 16 个通道,省掉了原先一个通道一块板子的方案。

1.2 为什么是 STM32F767ZG:算力冗余背后的真实需求

STM32F767ZG 这颗料在纯测温项目里确实显得“性能过剩”。Cortex-M7 内核,216MHz 主频,带双精度硬件浮点单元,512KB RAM。用这么高的算力去读几个温度,听起来像杀鸡用牛刀。但实际场景里这个选择并不浪费,原因有三点。

第一,M7 内核做浮点运算几乎是零成本的。RTD 测温的核心公式是 Callendar-Van Dusen 方程,里面包含二阶、三阶甚至四阶多项式。用 Cortex-M0 或 M3 做这个运算是靠软件模拟浮点,一条乘法指令要执行几十个周期,一套公式算下来就要几毫秒。而 M7 一条 VMLA 指令直接完成浮点乘加,计算 4 阶多项式只需要微秒级。当系统需要以 1Hz 到 10Hz 频率轮询几十个通道,同时还要每通道做滑动滤波和线性化时,这个差距就会非常明显。简单说就是:M4 干这个活在 80% 负载,M7 只用了 5%,剩下的算力你可以随便加功能。

第二,冗余算力给了系统扩展空间。工业现场的表计项目往往是一步步加需求的,今天只要测温,明天要加压力变送器接口,后天要加 RS485 Modbus 从站协议,再后来可能还要加一个 LCD 显示和按键菜单系统。F767 的资源和算力可以让你在不更换主控的前提下优雅地完成这些升级,而不是前期为了省几块钱选个 M0,后期被硬件资源卡住脖子重新画板子。

第三,F767 拥有丰富的高级定时器和 ADC 外设。虽然温度采集用的是外部 ADC,但 MCU 自身的 ADC 可以用来监测电源电压、检测模拟通道的自检电压等;高级定时器可以输出 PWM 控制加热器或者风机转速。HVAC 控制器里经常需要同时做采集和控制,一颗 F767 全搞定,整个系统架构非常干净。

顺带提一句,后续如果觉得 F767 成本偏高,完全可以无缝降级到同系列的 F746 或者不同封装的 F722,寄存器级兼容,代码几乎不用改。这也是选型时给自己留的一条后路。

1.3 应用场景与精度目标的拆解

既然标题里明确了“工业和 HVAC 应用”,我按实际项目经验把场景大致分成三类,各自的精度需求和设计侧重点差别很大。

第一类是工业过程监控。典型环境是工厂车间、配电柜内部或机械设备的润滑油温度监测。这类场景的特点是环境噪声大、传感器线缆长(从传感器到采集板可能走 5 到 20 米),而且温度变化速率相对慢。精度目标一般是 ±0.2℃ 到 ±0.5℃ 全量程。设计侧重点是抗干扰、长线补偿和稳定性,对响应速度不敏感。

第二类是 HVAC 楼宇自控。监测风管温度、冷热水管温度、室内外温湿度传感器等。这类应用线缆一般较短(1 到 3 米),但环境复杂度高,附近可能有大功率变频器、风机盘管电机,干扰源密集。精度目标 ±0.3℃ 到 ±1℃ 即可。设计侧重点是 EMC 防护和一致性校准,因为一栋楼里可能有几十上百个测点,每个点的读数如果偏差过大,整个 BA 系统的控制逻辑就会混乱。

第三类是验证测试类设备(环境试验箱、培养箱、数据中心冷通道监测)。这类设备对精度的要求最高,通常需要 ±0.1℃ 甚至更高,而且需要能够溯源校准。设计侧重点是基准源的选择、校准流程和长期稳定性。

在具体设计开始之前,我建议把目标精度写成一个明确的表格参数,把分辨率、精度、稳定度、更新速率这些解耦清楚。这决定了后续硬件的很多设计选择,比如基准电阻的精度、参考电压源的类型、滤波的时间常数等。很多项目做到一半发现精度不够,回头排查才发现是源头设计目标没定清楚。

2. 硬件设计与关键细节

2.1 RTD 前端设计:比例测量法的核心逻辑

ADS122U04 和 RTD 搭配的经典接法是比例法。原理是把一个高精度参考电阻 RREF 与 RTD 串联,由 IDAC 提供恒定的激励电流,然后分别测量 RTD 和 RREF 上的电压。因为流过两者的电流完全相等,所以 RTD 的阻值可以表示为 RREF 乘以两者的电压比。公式如下:

R_RTD = (V_RTD / V_REF) × R_REF

这里 V_REF 直接取自 RREF 两端的电压,并接到 ADC 的 REFP0/REFN0 引脚。这样做最大的好处是所有与激励电流、参考电压漂移、PGA 增益温漂相关的误差项在除法运算中自动抵消了。哪怕电流从 500μA 漂到 520μA,只要 RREF 不变,电压比也不变,读数就不受影响。这就是比例测量的核心价值,用相对测量规避了绝对测量中最大的一类误差源。

RREF 的选型值得多说两句。它承担着决定测量绝对精度的任务,所以温漂系数必须够低。我常用的规格是 ±0.05% 初始精度、温漂 ±5ppm/℃ 的精密薄膜电阻。以 PT100 为例,温度每变化 1℃ 对应的阻值变化约 0.385Ω,如果 RREF 是 1kΩ,温度漂移 5ppm/℃ 就是 5mΩ,对应到读数上大约是 0.013℃ 的误差,这个量级在绝大多数应用里是完全可以接受的。如果还要更极致,可以选 ±0.01% 精度的 VPG 或 Vishay 箔电阻,但成本和交期都会上去,一般只在计量级项目里才需要。

激励电流的选择也有讲究。IDAC 的可设范围通常是 0 到 1.5mA。电流越大,信号幅度越大,信噪比越好,但 RTD 的自热效应也越明显。PT100 在 1mA 电流下的自热功率约 0.1mW,在空气中会产生大约 0.03℃ 到 0.1℃ 的附加误差,具体取决于传感器的封装和散热条件。而 PT1000 本身阻值大,1mA 电流会产生约 1V 的压降,接近 ADC 满量程,所以一般用 500μA 就足够。工业项目中我通常这样取舍:PT100 用 1mA,PT1000 用 250μA 或 500μA。这样既保证了足够的信号摆幅,又把自热控制在可以接受的范围内。

接线方式对精度同样有决定性影响。两线制接线最省线,但导线电阻直接串联进测量回路。如果线阻是 0.5Ω(常见的 0.5mm² 铜线 20 米左右就是这个水平),PT100 在 0℃ 时是 100Ω,这会带来约 1.3℃ 的巨大正偏差,而且这个偏差还随环境温度变化,无法通过简单校准消除。三线制通过引入一根额外的线来测量导线电阻,然后在软件里做补偿,是目前工业现场的主流方案。四线制最精确,激励和检测完全分开,彻底消除线阻影响,但成本也最高。

ADS122U04 的 IDAC 配合多路复用器,对于三线制接线的方案有个很实用的打法:用两个 IDAC 分别从 RTD 的两端注入电流,两个电流都设为相同值。这样流经公共线的电流互相抵消,导线电阻上的压降只取决于线路电阻的差异,而不是绝对值,从硬件层面就把大部分线阻误差给抵消掉了。这是 TI 官方 RTD 测量方案里推荐的标准接法,比单纯软件补偿稳定得多。

2.2 外围电路的滤波与保护设计

模拟前端再好的 ADC,外围电路设计不到位也是白搭。一个常见的误区是把大量精力花在选高精度器件上,却忽略了 PCB 布局和滤波,最后做出来的信噪比还不如人家普通器件却精心布线的板子。

滤波方面,我的经验是在传感器线缆进入 PCB 的端口处放一个共模电感加差模电容的组合。RTD 本身是个低频信号(温度变化的时间常数通常是秒级甚至分钟级),所以我们有充足的空间去压低带宽换取噪声抑制。具体来说,我会在模拟输入引脚前放一个 RC 低通滤波,截止频率设在 1kHz 左右,同时注意把电容靠近 ADC 的引脚放置。还有一个你们可能忽略的点:RC 滤波器的电阻值不能取太大,因为 IDAC 的电流流过这些电阻会产生额外的压降和误差。例如 10kΩ 的串阻在 1mA 电流下会产生 10V 压降,直接饱和。一般取 1kΩ 到 10kΩ 之间比较合适(10k 有点偏大了,常见是 1k 到 4.7k),还要确保这个压降在 ADC 的输入共模范围以内。

保护方面,工业现场最怕的就是静电放电和浪涌。传感器线缆可能接到室外或长距离布线环境,难免会感应到各种浪涌脉冲。我的标准做法是:在输入端并联 TVS 管(双向的,比如 SMBJ15CA 或类似的),并串联 PTC 自恢复保险丝做限流。要注意 TVS 的钳位电压必须低于 ADC 引脚的绝对最大额定值,并且要靠近连接器放置,让保护器件在浪涌进入板内之前就把能量泄放掉。

同时,别忽略基准电压输入 REFP0/REFN0 的保护。我把 RREF 和基准输入部分的走线也当作高精度模拟信号来对待,两侧用地线包起来,并且保证基准走线远离任何数字信号线。这一块的噪声会直接叠加到测量结果上,比输入端的噪声影响还要直接。

2.3 PCB 布局的几条硬经验和教训

PCB 布局这部分我吃过不少亏,总结几条最关键的。

首先是地平面完整性。模拟部分要保证底层有完整的参考地平面,严禁在 ADC 芯片下方的地层挖槽。有些朋友为了走线方便在底层画了分割线,结果 ADC 的输入噪声暴增,百思不得其解。原因是 ΔΣ ADC 内部依赖一个干净的衬底地来稳定比较器的工作,地层不完整会引入共模噪声。

其次是电源去耦。每个电源引脚都要有 0.1μF 的陶瓷电容紧贴放置,模拟电源 AVDD 和数字电源 DVDD 在布局上要物理分开,并且最好用磁珠或小阻值电阻做一级隔离。还要注意 ADS122U04 的电源引脚和 STM32F767ZG 的电源区域不要挨得太近,避免 MCU 高频开关噪声耦合到 ADC 供电上。

第三个教训是关于热效应的。ADC 芯片本身会发热,功率虽然不大,但足以在 PCB 上形成温度梯度,而精密电阻和基准源对温度是敏感的。我曾经在测试中发现,ADC 读数从冷态到热稳定后漂移了 0.15℃,顺着排查才发现是 RREF 正好放在了 ADC 旁边,被烘热了。从那以后,我把 RREF 和模拟前端的关键元件放在板子的边角区域,远离任何发热源,并且在 PCB 上走了一段细细的“热隔离槽”。对于要求较高的产品,还可以在 ADC 下方铺散热焊盘并连接到地层,把热量均匀扩散而不是集中在一侧。

最后一个提醒是传感器的连接器选型。工业环境会振动、会潮气,普通的 2.54mm 排针很容易出现接触不良和氧化。我一般用镀金的螺钉端子或者带锁扣的弹簧端子,并且标注清楚线序,三线制的接错问题是现场调试中最高频的故障来源之一。

3. 固件驱动与通信实现

3.1 ADS122U04 的 UART 协议细节

ADS122U04 的 UART 接口虽然替你封装了很多东西,但协议细节还是需要吃透。它支持两种工作模式:一种是连续模式,ADC 不断转换并自动输出结果;另一种是命令模式,主机发命令读取寄存器或启动转换。我强烈建议在调试初期使用命令模式,等掌握了时序再切换到连续模式。

UART 帧格式默认是 8 位数据、无校验、1 位停止位。波特率范围很宽,从 1200 到 115200 都可以,我一般设在 9600 或 19200,原因很现实:长线环境下高速率容易受干扰,而温度采集根本不需要高吞吐。每条主机命令由若干个字节组成,包括命令字节、寄存器地址、数据字节,以及 CRC。ADS122U04 的 CRC 算法是 CCITT 多项式 0x1021 的变体,具体实现手册上有参考代码。这里有个大坑:CRC 的初始值是 0xFFFF,而且在计算时输入数据需要反转位序。我第一次没反转位序,还专门写了对调表去对照,结果怎么都不对,浪费了大半天。你在移植的时候一定要看官方代码或者数据手册里的示例,别想当然。

还有一个非常容易踩的坑是复位后的设备地址。ADS122U04 支持通过 ADDR 引脚配置设备地址,用于多设备挂接在同一条 UART 总线上。默认状态下地址是 0x00 还是 0x40 取决于引脚的电平。如果你的板子上把 ADDR 悬空了,内部上拉可能会让它落到一个非 0 地址上,导致你发 0x00 地址的指令没有回应。排查手段就是上电后立刻读一遍设备 ID 寄存器,确认通信链路是否正常。

3.2 配置寄存器与初始化流程:一个可直接抄的代码模板

ADS122U04 的寄存器组不多,但每个位的含义都很关键。以最常见的 PT100 三线制测量为例,我的初始化流程是这样配置的。

配置寄存器 0(偏移 0x00)负责 PGA 增益、输入多路复用器和转换模式。增益设为 16 倍比较合适,因为 PT100 在 0℃ 到 100℃ 范围内电压变化约 38.5mV,加上 VREF 为 2.5V 时,16 倍增益后的信号幅度在约 0.6V 左右,是满量程的 24%,既能获得足够分辨率又不会接近削波。如果测量范围更窄(比如 0 到 50℃),可以设到 32 倍。

配置寄存器 1(偏移 0x01)负责数据速率、滤波器模式、偏置电压等。数据速率我通常选 20SPS(每秒采样 20 次),这个速率内置了 50Hz 和 60Hz 工频陷波,对工业环境的抑制效果非常明显。要知道,如果不利用这个特性,50Hz 的工频干扰会以差模形式混进信号里,事后靠软件滤波效果远不如直接在采样链路上搞定。

配置寄存器 2(偏移 0x02)负责 IDAC 电流设置和参考电压源选择。我把 IDAC1 设为 1mA,IDAC2 也设为 1mA,分别接到三线制的两根激励线上。参考电压选外部 REFP0/REFN0,也就是 RREF 的两端。

配置寄存器 3(偏移 0x03)比较杂,包含 IDAC 路由选择、PGA 偏置等。关键是把 IDAC 的输出路由到正确的引脚上。

下面是一份基于 STM32 HAL 库的初始化参考代码。注意这不是完整的工程文件,而是核心寄存器配置的片段,你可以直接嵌到自己的驱动层里:

// 伪代码:ADS122U04 初始化序列 uint8_t cfg0 = 0x00; uint8_t cfg1 = 0x00; uint8_t cfg2 = 0x00; uint8_t cfg3 = 0x00; // 配置寄存器0:输入选择 AIN0-AIN1 差分,PGA=16 // 位7:6=00 (AIN0-AIN1),位5:4=11 (PGA=16) cfg0 = (0x00 << 6) | (0x03 << 4); // 配置寄存器1:20SPS,内部偏置关 // 位7:6=01 (20SPS),位5:4=00 (正常滤波),位1=0 (关偏置) cfg1 = (0x01 << 6); // 配置寄存器2:IDAC=1mA,参考源选择外部 // 位7:5=010 (1mA),位4:3=00 (外部REF) cfg2 = (0x02 << 5); // 这里IDAC值需查表,以手册为准 // 配置寄存器3:IDAC1->AIN2, IDAC2->AIN3 // 位7:5=001 (IDAC1->AIN2),位4:2=010 (IDAC2->AIN3) cfg3 = (0x01 << 5) | (0x02 << 2); ads122u04_write_reg(0x00, cfg0); ads122u04_write_reg(0x01, cfg1); ads122u04_write_reg(0x02, cfg2); ads122u04_write_reg(0x03, cfg3); // 发送同步命令,启用内部振荡器 ads122u04_send_command(0x08); // 触发一次转换并读取结果 int32_t raw = ads122u04_read_conversion();

强调一点:上面的 cfg 位段只写了个大概,不同版本的数据手册个别位含义有微调,设计电路板时一定要对照你手里的那版 datasheet 逐位确认。我不止一次见过有工程师凭记忆写配置,结果驱动死活不通,回来查手册才发现寄存器定义早就变了。

3.3 温度换算与线性化:Callendar-Van Dusen 工程实现

拿到原始码值之后,接下来就是温度换算了。RTD 电阻与温度的关系在国际标准中由 Callendar-Van Dusen(CVD)方程描述。对于 0℃ 以上:

R(t) = R0 × (1 + A×t + B×t²)

对于 0℃ 以下,还需要加上一个 C 项:

R(t) = R0 × (1 + A×t + B×t² + C×(t-100)×t³)

其中 PT100 的标准系数为 A=3.9083e-3,B=-5.775e-7,C=-4.183e-12(0℃ 以下才用)。

工程实现上有两种选择:查表法和直接求解法。查表法是把 -50℃ 到 500℃ 的电阻值每隔 1℃ 或 0.1℃ 列成一个常量表,运行时线性插值。这个方法的优点是速度快,MCU 负载极低,而且实现简单,但要占据大约 1 到 2KB 的 Flash 空间。直接求解法则是在 MCU 上用多项式和牛顿迭代法反算出温度值,精度最高,但代码更复杂。我个人的做法是混合:先用查表法得到温度初值,再以这个初值代入 CVD 方程做一步牛顿修正。因为表索引已经很接近真实值,一次迭代就足够把误差压到 0.01℃ 以下,而开销只有微秒级,对 F767 来说简直不值一提。

还有两个细节容易被忽略。第一个是 ADC 码值到电阻值的转换公式,不要忘了把 PGA 增益放进去。第二个是当采用三线制且两个 IDAC 配置正确时,测量得到的是两线电阻的平均效应,理论上已经抵消了线阻。但如果你实际用的是两线制接线,那就要额外在软件里减去估算的线阻,这需要你在现场测量并固化一个补偿系数。

下面的代码片段展示了从原始 ADC 码值计算温度的完整流程:

float ads122u04_convert_to_temperature(int32_t raw_code, float rref) { // 假设使用 PGA=16 const float pga_gain = 16.0f; // 满量程码值 = 2^23,因为ADS122U04是24位 const float full_scale = 8388608.0f; // VREF由RREF和IDAC决定,比例测量后化简得到电阻值 float rtd_resistance = ((float)raw_code / full_scale * rref) / pga_gain; // 下面用简化形式求温度 const float R0 = 100.0f; const float A = 3.9083e-3f; const float B = -5.775e-7f; float t = 0.0f; // 初值(查表可替换为更精确的表值) if (rtd_resistance >= R0) { float a = B; float b = R0 * A; float c = R0 - rtd_resistance; float disc = b * b - 4.0f * a * c; t = (-b + sqrtf(disc)) / (2.0f * a); } else { // 0℃以下需用CVD完整方程,这里从略 } return t; }

这只是一个演示性质的函数,没有处理所有边缘情况。正式项目建议从 TI 的 RTD 计算应用笔记里参考官方算法,或者用查表法保证确定性。

3.4 与 STM32F767ZG 的通信架构设计

既然 MCU 算力充裕,我建议用 DMA + 空闲中断的方式来处理 UART 接收。ADS122U04 每次转换结果会输出固定长度的数据帧,用 DMA 接收能够大大降低 CPU 的负载。具体做法是:配置 UART 的 RX DMA 为循环模式,接收缓冲区足够大,然后利用 HAL 库的 IDLE 回调来判断一帧数据是否接收完毕。

对于多通道轮询,我设计的架构是这样:一个定时器(比如 100ms 周期)触发一次软件调度,调度器维护一个通道状态机。空闲时向 ADS122U04 发送通道切换命令,然后等待转换完成中断。转换完毕后读取数据,经过滤波和线性化处理,存到全局结果数组。上层业务逻辑(显示、通信、控制)只管读结果数组,不需要关心底层采集细节。这样一个松耦合的架构,后面加协议栈或者控制算法都非常顺手。

在 F767 上我会开启 I-Cache 和 D-Cache,并且把结果数组定义在 TCM RAM 或者带 cache 管理的区域。如果 DMA 和 CPU 同时访问一个普通 SRAM 区域,Cache 一致性问题可能会让你怀疑人生。我的习惯是分配一个单独的 non-cacheable 区域给 DMA 缓冲区。

4. 实际调试过程记录与典型问题排查

4.1 电源纹波和基准噪声导致的“幽灵跳动”

第一次给这套系统上电时,我碰到的第一个问题就是采集值在小数点后两位来回跳,跳幅甚至达到 0.05℃ 以上。一开始怀疑是布线问题,后来用示波器量了 AVDD 引脚,发现上面叠加了幅值约 5mV 的 40MHz 左右的噪声,来源是隔壁的 DC-DC 降压芯片。原因出在最初的原理图只给 AVDD 加了一个 0.1μF 陶瓷电容,这个容量的电容对低频纹波还可以,但对高频开关噪声的抑制能力不足。

解决方法是把 AVDD 的供电链改成两级:DC-DC 输出先经过一个磁珠(如 BLM18PG330SN1),再并联 10μF 的钽电容和 0.1μF 陶瓷电容,形成 LC 滤波。同时把 DC-DC 的电感方向调整了一下,让磁力线不再直指 ADC 区域。改动之后纹波降到了 1mV 以下,跳动幅度也收敛到 0.01℃ 以内。吃一堑长一智,后来我做模拟电路设计时,电源干净程度永远是先于布局检查的最高优先级项。

另外强调一点:ADS122U04 的 AVDD 和 DVDD 虽然可以接同一个电源轨,但我强烈建议 AVDD 用 LDO 单独供。开关电源的噪声哪怕滤波做得再好,也还是比 LDO 高一个量级。对于追求高有效分辨率的应用,这个成本省不得。

4.2 负温度读数异常与输入建立时间的坑

在测试低温段时出现了一个诡异的现象:把传感器放入冰水混合物(理论上 0℃)后,读数在 -1.2℃ 附近徘徊,怎么校准都校不回来。排查了很久,最后定位到原因是 PGA 的工作点不对。

ADS122U04 的 PGA 输入端要求共模电压维持在一个合适的范围内。使用双 IDAC 的三线制接法中,AIN0 和 AIN1 的共模电压取决于 RREF 上的压降和 IDAC 电流。当温度降低时,RTD 阻值变小,AIN0 和 AIN1 这两端的电压差变小,但如果共模电压太低,PGA 内部的前端开关就会进入非线性区,导致增益背离,读数就会出现偏置。这解释了为什么只在低温段出现系统性的偏差。

解决办法有两个,我更推荐后者。第一个是在配置寄存器里打开 PGA 的偏置电压生成功能,把共模点抬高;第二个更稳妥的做法是重新计算 RREF 和 IDAC 的搭配,让 ADC 在最低测量温度时仍然有足够的共模余量。比如把 RREF 从 1kΩ 换成 820Ω 或者 2kΩ 来重新分配输入电压的上下边界,确保在最恶劣的温度点,AIN 引脚的电平都落在 VREF 和 GND 之间舒适的区间。这个需要在原理图定型之前用 Excel 或者 Python 简单算一算,别等到 PCB 做回来才在软件里打补丁。

4.3 UART 通信间歇性丢帧的问题

调试中另一个高频问题是 UART 通信偶发丢帧,尤其在传感器线缆靠近变频器或者开关电源时。现象是读数和指令偶尔无响应,重试就好了,但总让人觉得不稳。

排查分三步走。第一步,用示波器看 UART 引脚的波形,重点看毛刺和畸变。在长线传输中,如果没有终端电阻和合适的电平,通信线上的振铃可能正好能越过接收端的阈值,造成错误数据帧,而 ADS122U04 的 CRC 校验会把这帧直接扔掉,体现为“丢帧”。第二步,确认 MCU 的 UART 波特率精度。如果用内部 RC 振荡器跑 115200 波特率,误差可能在正负 1% 到 2% 之间,在某些温度点上误码率会明显恶化。STM32F767ZG 内部 RC 的精度并不算高,最好切换为外部 8MHz 晶振,或者把波特率降到 9600。第三步,检查 UART 线的电平转换芯片。如果用的板子有 RS-232 或 RS-485 转换,要特别注意收发切换的时机,半双工模式下方向切换太快就可能丢数据。

我的最终方案是:物理层换成了 RS-485 差分传输,两边加终端电阻,波特率降到 9600,校验字节严格按 CRC。至此通信再没出过问题。顺便说一句,如果你的传感器节点距离控制器超过 2 米,我就不建议直接用 TTL 电平的 UART 了,直接换成 RS-485 或者 CAN,省得后面反复折腾抗干扰。

4.4 校准流程与长期稳定性的实测数据

硬件和软件都稳定之后,精度就成了下一步的主战场。即使使用了比例测量法,RREF 的初始误差、ADC 的偏移误差、PGA 的匹配误差等还是会带来整体线性偏移。解决手段就是校准。

我比较推荐零点加满度两点校准,条件允许时加一个中间点做三点校准。以 0℃ 和 100℃ 为例:把传感器放进冰水混合物和沸水(或恒温槽),分别记录 ADC 读数,然后算出一个斜率补偿系数和一个零点偏移。公式不复杂:

T_real = K × T_raw + B

其中 K 是增益修正系数,B 是偏移量。校准的目的是把 RREF 和 ADC 系统误差一次性消掉。实测下来,经过三点校准后的系统在全量程范围内可以稳定在 ±0.05℃ 以内,而未经过校准的裸系统大约在 ±0.3℃ 左右——这组数据对不同精度目标的项目都有参考价值。

关于长期稳定性,我做过一个连续运行 72 小时的测试,记录环境温度恒定为 25℃ 时的读数漂移。结果如下表所示:

时间段最大偏差平均漂移备注
0-1小时(上电初期)±0.08℃+0.04℃板卡热平衡过程
1-24小时±0.03℃±0.01℃基本稳定
24-72小时±0.05℃±0.02℃受环境温度缓慢变化影响

值得注意的冷启动后的前一个小时,板卡内部温度上升,RREF 的温漂和 ADC 内部基准的温漂会造成读数的正向偏移。虽然比例测量抵消了大部分误差,但残余温漂依然存在。如果你的产品要求上电后快速进入高精度状态,可以考虑在软件里加一个“预热状态”逻辑,前几分钟用较低精度模式运行,等热稳定了再切到高精度档。

5. 工程落地的几个额外心得

有些细节虽然不在“电路设计”或者“驱动代码”的范畴里,但直接影响最终产品的可靠性和可维护性。这里挑三个我觉得最值得说的。

第一个是关于固件版本管理。ADC 的寄存器配置参数、校准系数、传感器类型识别这些数据一定要固化在独立的 Flash 扇区,并且带 CRC 校验。工程上经常出现换了传感器类型(PT100 换 PT1000),固件却还在用旧的增益和系数,结果读数全部异常的问题。我的做法是在系统初始化时读一个硬件跳线或 EEPROM 中的类型标识,动态选择配置参数包。这个设计看起来简单,却能省掉大量售后排查时间。

第二个是关于调试接口的保留。就算量产板不打算引出 SWD 口,在开发阶段也一定要把它留在 PCB 上的测试点位置,并且尽量靠近 MCU 的引脚。我自己做过一个糟糕的决定,为了省面积,SWD 测试点放在了一个被散热片挡住的位置,结果现场调试时要用风枪把散热片吹掉才能连上调试器,狼狈不堪。

第三个是关于 EMI 预测试。HVAC 产品通常需要过 EMC 认证,而温度采集板因为走线长、传感器线缆多,经常是辐射发射的泄漏源。建议在原理图阶段就给传感器接口留好共模电感的位置和并联电容的位置,不管最初用不用得上。产品送去实验室测一次 EMC 的成本,够你买一万颗共模电感。能在地上加的就别等到天上飞的时候再加。

最后再分享一个我自己总结的小技巧:在 MCU 里保留一个“原始数据观测模式”。正常工作时,上位机或串口调试助手看到的都是经过线性化处理的温度值。但如果把设备切换到观测模式,它会按固定频率输出 ADC 原始码值和中间计算结果。这看起来是给自己添麻烦,实际排查问题时却是最有价值的工具。很多看似是“上位机显示错误”的问题,用原始数据一对照,立刻就能定位到是传感器、模拟前端、代码算法还是通信链路哪一环出了状况。真心建议你不管做多少路通道,这个后门都别省。

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

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

立即咨询