ARTICLE DETAIL

资讯详情

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

工业测温方案解析:ADS122U04与STM32F042K6的UART高精度RTD采集设计

工业测温方案解析:ADS122U04与STM32F042K6的UART高精度RTD采集设计

1. 为什么工业测温场景偏偏选中了 ADS122U04 加 STM32F042K6 这套组合

工业现场和 HVAC 系统里的温度测量,跟实验室里拿个万用表戳两下完全是两码事。实验室里环境恒定、干扰小、对成本不敏感,而工业现场要考虑的是:传感器离主控可能十几米远、现场有变频器和大功率继电器在疯狂开关、环境温度从零下几十度到零上一百多度、设备要连续跑好几年不能停。这些约束条件叠加在一起,就决定了测温方案不能随便选。

PT100 和 PT1000 这类 RTD 传感器之所以在工业测温里占据主导地位,核心原因是线性度好、长期稳定性强、互换性好。你拿一个 A 级 PT100,在零度的时候阻值就是 100 欧姆,一百度的时候大约 138.51 欧姆,这个关系非常稳定,不会像热敏电阻那样用两年就飘了。但 RTD 有个天然的麻烦:它的电阻变化量太小了。PT100 在零度附近,温度每变化一度,阻值只变化大约 0.385 欧姆。你要测到 0.1 度的分辨率,就得分辨出大约 0.0385 欧姆的阻值变化。这个量级放在有电磁干扰的工业现场,用普通的 ADC 根本搞不定。

ADS122U04IPWR 这颗芯片就是冲着这个痛点来的。它是 24 位 delta-sigma 架构的 ADC,内置 PGA,支持两路差分输入或者四路单端输入,最关键的是它自带 UART 接口。注意,是 UART,不是 SPI 也不是 I2C。这个选择在工业场景里非常讲究。SPI 和 I2C 适合板级通信,走线短、速率高,但一旦传感器和主控之间拉开距离,SPI 的时钟线就容易受干扰,I2C 的总线电容限制也让人头疼。UART 是异步通信,只需要 TX 和 RX 两根线,对时钟同步没有要求,配合 RS485 收发器可以轻松拉到上千米,这在 HVAC 系统里太常见了——楼宇自控的传感器分布在各个楼层,走线动辄几十米。

STM32F042K6 作为主控,定位很清晰:ARM Cortex-M0 内核,48MHz 主频,32KB Flash,6KB SRAM,封装小巧,成本低廉,但外设该有的都有——UART、SPI、I2C、ADC、定时器一应俱全。它不需要跑操作系统,裸机就能把 ADS122U04 的数据读回来、做线性化计算、通过 UART 上报给上位机或者网关。这套组合的精髓在于:ADS122U04 负责把微弱的 RTD 电阻变化转换成高精度数字量,STM32F042K6 负责数据处理和通信调度,两者通过 UART 连接,物理层可以用 RS485 或者直接 TTL 短距离传输。

我见过不少项目在选型阶段纠结要不要用集成式测温芯片,比如 MAX31865 这类专用 RTD 前端。MAX31865 确实方便,SPI 接口,内置 15 位 ADC,但它的分辨率在需要 0.01 度精度的场合就不够看了。ADS122U04 的 24 位分辨率,配合外部基准电阻和合理的 PGA 增益,做到 0.01 度甚至更高完全可行。而且 ADS122U04 的输入多路复用器可以轮流采集多个通道,一个芯片管好几路温度点,在 HVAC 的多区域温度监测里很实用。

还有一个容易被忽略的点:ADS122U04 内置了激励电流源。RTD 测量需要恒流激励,这个电流源直接集成在 ADC 里,省掉了外部恒流源电路。你可以通过寄存器配置激励电流的大小,比如 10 微安、50 微安、100 微安、250 微安、500 微安、1 毫安、1.5 毫安。这个灵活性很重要,因为激励电流太大会导致 RTD 自热,太小则信号太弱容易被噪声淹没。PT100 在 1 毫安激励下的功耗大约是 0.1 毫瓦,自热误差可以控制在 0.01 度以内,这个平衡点需要根据具体封装和散热条件来调。

2. 硬件链路怎么搭:从 PT100 到 STM32 的完整信号路径

2.1 RTD 接口电路的设计细节与参数计算

PT100 的接法有讲究。两线制最简单,但导线电阻直接叠加在测量结果里,每米铜线大约 0.02 欧姆,十米来回就是 0.4 欧姆,折算成温度误差接近 1 度,这在工业场合不可接受。三线制能补偿导线电阻,前提是三根线材质长度一致,ADS122U04 配合外部多路开关或者直接利用其内部多路复用器可以实现三线制测量。四线制最准,完全消除导线电阻影响,但多一根线,成本高一些。HVAC 里三线制用得最多,性价比和精度平衡得比较好。

具体到 ADS122U04 的电路,我一般这样设计:PT100 一端接激励电流源输出引脚,另一端接 ADC 的差分输入正端,同时通过一个基准电阻接地。基准电阻的精度直接决定测量精度,必须用低温漂的金属箔电阻或者高精度薄膜电阻,温漂控制在 5ppm/度以内,阻值选 1.65 千欧或者 3.3 千欧这种常见值。为什么选这个值?因为 ADS122U04 的基准电压来自外部基准电阻两端的压降,激励电流乘以基准电阻就是基准电压。如果激励电流是 500 微安,基准电阻 3.3 千欧,基准电压就是 1.65 伏,这个值在 ADC 的推荐工作范围内。

差分输入负端接在 PT100 和基准电阻的连接点,这样 ADC 读到的差分电压就是 PT100 两端的压降。PGA 增益设置要算一下:PT100 在最高测量温度时的阻值乘以激励电流,不能超过 ADC 的满量程输入范围。假设测到 200 度,PT100 阻值约 175.86 欧姆,激励电流 500 微安,压降是 87.93 毫伏。ADS122U04 在增益为 1 时满量程是正负基准电压,也就是正负 1.65 伏,87.93 毫伏只占很小一部分,分辨率浪费了。所以要把 PGA 增益调高,比如增益 16,满量程变成正负 103 毫伏,87.93 毫伏刚好在范围内,分辨率提升了 16 倍。这个计算过程在实际调试时一定要做,增益选小了精度不够,选大了信号超量程直接饱和。

滤波电路也不能省。RTD 到 ADC 之间要加 RC 低通滤波,截止频率根据采样率来定。ADS122U04 的采样率可以配置,从 5SPS 到 2000SPS。工业测温不需要太快,20SPS 足够了,对应的截止频率设在 10Hz 左右。电阻选 1 千欧,电容选 10 微法,截止频率是 1/(2π×1000×10^-5)≈15.9Hz,差不多。差分输入之间还要加一个 100 纳法的电容,抑制共模干扰。这些电容要用 C0G 或者 X7R 材质的,温度稳定性好。

2.2 STM32F042K6 的外设配置与 UART 通信参数

STM32F042K6 这边,UART 的配置要和 ADS122U04 匹配。ADS122U04 的 UART 接口默认波特率是 115200,数据位 8 位,停止位 1 位,无校验。STM32 的 HAL 库初始化代码大概长这样:

huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart1);

注意 ADS122U04 的 UART 模式需要先通过 SPI 或者硬件引脚配置进入。芯片上电后默认是 SPI 模式,要发特定的命令序列切换到 UART 模式。这个切换命令是 0x55 加上一些配置字节,具体看数据手册的时序图。我踩过的坑是:切换命令发完之后要等至少 100 微秒再发下一条命令,否则芯片内部状态机还没切换完,命令会被忽略。

STM32F042K6 的 UART 接收用中断或者 DMA 都行。数据量不大,中断就够了。但要注意 ADS122U04 的数据就绪引脚 DRDY 要接到 STM32 的某个 GPIO 上,配置成外部中断下降沿触发。DRDY 拉低表示转换完成,STM32 在中断里通过 UART 发读取命令,然后接收数据。这个流程比轮询效率高得多,也不会丢数据。

电源部分也要留意。ADS122U04 的模拟电源和数字电源要分开滤波,模拟电源用 LDO 单独供,数字电源可以和 STM32 共用但也要加磁珠隔离。基准电阻的供电要从模拟电源取,不能从数字电源取,否则数字开关噪声会串进来。PCB 布局上,模拟部分和数字部分要分区,地平面要完整,不要被走线割裂。这些细节在低速高精度场合特别重要,我见过太多因为地平面处理不好导致读数跳动的案例。

3. 固件实现:从寄存器配置到温度换算的完整流程

3.1 ADS122U04 的寄存器配置与初始化序列

ADS122U04 有四个配置寄存器,分别控制多路复用器、增益、数据速率、工作模式、激励电流等。初始化的时候要按顺序写。第一个寄存器是配置寄存器 0,高四位是 MUX 选择,比如 0x00 表示 AIN0 和 AIN1 差分输入,0x01 表示 AIN0 和 AIN2,以此类推。接下来两位是增益设置,00 是增益 1,01 是增益 2,10 是增益 4,11 是增益 8,再往后是 PGA 使能位。配置寄存器 1 控制数据速率和转换模式,配置寄存器 2 控制基准选择和激励电流,配置寄存器 3 控制 IDAC 路由和 DRDY 模式。

写寄存器的命令格式是:先发 0x40 加上寄存器地址,然后跟一个字节的数据。比如要写配置寄存器 0,命令是 0x40,地址是 0x00,合起来就是 0x40,然后跟数据字节。读寄存器是 0x20 加地址。这些命令通过 UART 发出去,注意 UART 是异步的,命令字节之间要有足够的间隔,ADS122U04 的处理时间大概在几十微秒量级,保险起见每条命令之间延时 200 微秒。

初始化流程我一般这样写:

// 切换到 UART 模式 uint8_t cmd_switch[] = {0x55, 0x00, 0x00}; HAL_UART_Transmit(&huart1, cmd_switch, 3, 100); HAL_Delay(1); // 写配置寄存器 0:MUX=AIN0/AIN1,增益=16,PGA 使能 uint8_t cmd_reg0[] = {0x40, 0x00, 0x0C}; HAL_UART_Transmit(&huart1, cmd_reg0, 3, 100); HAL_Delay(1); // 写配置寄存器 1:数据速率=20SPS,连续转换模式 uint8_t cmd_reg1[] = {0x40, 0x01, 0x04}; HAL_UART_Transmit(&huart1, cmd_reg1, 3, 100); HAL_Delay(1); // 写配置寄存器 2:基准=外部,激励电流=500uA uint8_t cmd_reg2[] = {0x40, 0x02, 0x10}; HAL_UART_Transmit(&huart1, cmd_reg2, 3, 100); HAL_Delay(1); // 启动转换 uint8_t cmd_start[] = {0x08}; HAL_UART_Transmit(&huart1, cmd_start, 1, 100);

这段代码里每个命令后面的延时不能省。我试过把延时去掉,结果寄存器写入失败,读回来的数据全是乱的。后来用逻辑分析仪抓波形才发现,ADS122U04 在 UART 模式下处理命令需要时间,连续发太快它会丢命令。

3.2 温度换算的数学过程与校准方法

ADS122U04 读回来的是 24 位有符号整数,表示差分电压与基准电压的比值。换算成电阻的公式是:R_RTD = (Code × R_ref) / (Gain × 2^23)。其中 Code 是 ADC 读数,R_ref 是基准电阻,Gain 是 PGA 增益。比如 Code 读回来是 8388608(也就是 2^23),增益 16,基准电阻 3.3 千欧,那么 R_RTD = (8388608 × 3300) / (16 × 8388608) = 206.25 欧姆。这个值对应 PT100 大约 275 度,合理。

拿到电阻之后要换算成温度。PT100 的阻温关系在负五十度到零度之间和零度到八百五十度之间公式不同。工业上常用 Callendar-Van Dusen 方程:

  • 零度以上:R(t) = R0 × (1 + A×t + B×t²)
  • 零度以下:R(t) = R0 × (1 + A×t + B×t² + C×(t-100)×t³)

其中 R0 是零度时的阻值,PT100 就是 100 欧姆。A、B、C 是常数,A=3.9083×10^-3,B=-5.775×10^-7,C=-4.183×10^-12。实际在单片机里算这个方程,零度以上可以直接解二次方程求 t,零度以下要用迭代法。STM32F042K6 没有硬件浮点单元,浮点运算是软件模拟的,速度慢一些但 20SPS 的采样率完全够用。如果嫌浮点慢,可以用查表加线性插值,把负五十度到两百度的阻值表存到 Flash 里,每度一个点,中间线性插值,精度也能到 0.01 度。

校准是绕不开的环节。理论计算再准,实际电路总有偏差。我一般做两点校准:把 PT100 放到冰水混合物里(零度)读一个值,再放到沸水里(一百度,注意当地大气压修正)读一个值,然后算增益误差和偏移误差。校准系数存在 STM32 的 Flash 里,每次上电读出来用。这个做法比单点校准靠谱得多,因为增益误差和偏移误差是两回事,单点只能修一个。

注意:校准用的冰水混合物要等温度稳定,一般需要搅拌并等待五分钟以上。沸水校准要考虑海拔,海拔每升高三百米沸点大约降低一度,这个误差在精密测量里不能忽略。

4. 现场调试中那些让人头疼的问题和解决思路

4.1 读数跳动与噪声抑制的实战经验

读数跳动是工业测温最常见的投诉。表现是温度值在小数点后两位来回跳,有时候能跳零点几度。原因通常有三个:电源噪声、地环路、电磁干扰。排查的时候先看电源纹波,用示波器交流耦合档测 ADS122U04 的模拟电源引脚,如果纹波超过一毫伏,就要加强滤波。我一般会在 LDO 输出后面再加一级 RC 滤波,电阻 10 欧姆,电容 100 微法,截止频率很低,对低频噪声有效。

地环路问题更隐蔽。如果传感器和主控分别接地,两个接地点之间存在电位差,这个电位差会叠加到信号上。解决办法是传感器端不接地,只用差分信号传输,或者用隔离器把两边地分开。ADS122U04 本身没有隔离,但可以在 UART 侧加数字隔离芯片,比如 ADuM1201 这类,把模拟地和数字地彻底分开。成本增加不多,但效果立竿见影。

电磁干扰在变频器附近特别严重。我遇到过一案例,测温模块装在变频柜旁边,读数每隔几秒就跳一次,跟变频器载波频率对上了。解决办法是给 RTD 输入加共模扼流圈,同时把采样率降到 5SPS,利用 ADC 内部的数字滤波器把工频和载波频率的干扰滤掉。ADS122U04 在低采样率下内置的 sinc 滤波器抑制能力很强,50Hz 和 60Hz 抑制可以做到 100dB 以上。这个技巧在 HVAC 场合特别管用,因为风机水泵的变频器无处不在。

4.2 UART 通信异常与数据丢包的排查方法

UART 通信出问题,先看波特率对不对。ADS122U04 的 UART 波特率是固定的 115200,但有些批次的芯片内部振荡器有偏差,实际波特率可能偏百分之二左右。STM32 这边如果也用内部振荡器,两边偏差叠加可能超过百分之三,通信就不可靠了。所以 STM32F042K6 最好用外部晶振,8MHz 或者 16MHz 都行,PLL 倍频到 48MHz,这样 UART 波特率精度能到千分之一以内。

数据丢包另一个原因是 DRDY 中断处理太慢。如果 STM32 在中断里做太多事情,比如浮点运算、查表、串口打印,中断服务程序执行时间过长,下一次 DRDY 来了还没处理完,数据就丢了。正确的做法是中断里只做一件事:把 ADC 数据读回来存到缓冲区,置一个标志位,主循环看到标志位再做换算和上报。这样中断执行时间可以控制在几微秒以内。

还有一点容易忽略:ADS122U04 的 UART 是半双工的还是全双工的?实际上它的 TX 和 RX 是分开的引脚,可以全双工。但如果你用 RS485 收发器,那就是半双工,发送和接收要切换方向。切换时机很关键,发完命令要等最后一个字节的停止位发完才能切到接收,否则会把命令的回显当成数据收进来。我一般用 UART 的 TC 中断来判断发送完成,在 TC 中断里切换 RS485 方向引脚。

4.3 常见问题速查表

现象可能原因排查方法解决措施
读数始终为零激励电流未开启测基准电阻两端电压检查配置寄存器 2 的 IDAC 位
读数满量程饱和PGA 增益过大计算信号幅度与满量程关系降低增益或减小激励电流
温度值跳变超过 0.5 度电源纹波大或地环路示波器测电源纹波加强滤波或加隔离
UART 无响应未切换到 UART 模式逻辑分析仪抓 TX 波形重新发切换命令并加延时
数据偶尔丢包DRDY 中断处理超时示波器测中断执行时间中断只做数据搬运
校准后仍有偏差基准电阻温漂大测量不同温度下基准电阻更换低温漂电阻
多点测量串扰多路复用器切换未稳定切换后延时不足增加切换后延时

这个表是我从实际项目里总结出来的,每一条都对应着至少一次熬夜调试的经历。特别是基准电阻温漂这一条,一开始用普通 1% 精度的电阻,常温校准好了,放到五十度的环境里跑两个小时,读数偏了 0.3 度。后来换成 5ppm 的金属箔电阻,问题消失。这个教训告诉我,高精度测量里,无源器件的选择跟有源器件一样重要。

5. 这套方案在 HVAC 和工业场景里的扩展玩法

5.1 多路温度采集与 RS485 总线组网

单个测温点用一套 ADS122U04 加 STM32F042K6 有点浪费,ADS122U04 本身有四路单端输入或者两路差分输入,可以轮流采集多个 PT100。配置多路复用器依次切换通道,每个通道采集完切换下一个,循环往复。STM32 这边维护一个通道计数器,DRDY 中断里根据当前通道号把数据存到对应的缓冲区。这样一套硬件可以管两到四个温度点,在 HVAC 的空调箱里,送风、回风、盘管、室外温度四个点刚好够用。

组网方面,STM32F042K6 的 UART 接一个 RS485 收发器,比如 MAX485 或者 SP3485,就可以挂到 RS485 总线上。RS485 是半双工,总线上的设备要分时发送。我一般用 Modbus RTU 协议,STM32 做从站,上位机或者 PLC 做主站。Modbus 的寄存器映射把温度值放到保持寄存器里,主站轮询读取。这个方案在楼宇自控里非常成熟,兼容性好,组态软件都支持。

RS485 总线的终端电阻不能忘。总线两端各接一个 120 欧姆电阻,中间设备不接。如果总线长度超过一百米或者波特率高于 19200,终端电阻必须加,否则信号反射会导致通信误码。我见过一个项目,总线拉了三百米没加终端电阻,白天通信正常,晚上开灯之后干扰大了就频繁掉线。后来在两端补上电阻,问题解决。

5.2 低功耗设计与电池供电的可行性分析

HVAC 里有些测温点不方便拉电源线,比如屋顶的室外温度传感器,或者管道井里的水温传感器。这时候要考虑电池供电。STM32F042K6 的低功耗模式做得不错,Stop 模式下电流可以降到微安级。ADS122U04 也有单次转换模式,转换完自动进入休眠,电流降到纳安级。两者配合,可以做到平均电流几十微安。

具体做法是:STM32 定时唤醒,通过 UART 命令启动 ADS122U04 单次转换,等 DRDY 中断,读数据,处理完通过无线模块或者 RS485 上报,然后两者都进休眠。唤醒周期根据需求定,温度变化慢,一分钟一次足够了。两节 18650 锂电池,容量 3000 毫安时,平均电流 50 微安,理论续航 60000 小时,也就是将近七年。当然实际有自放电和温度影响,打个对折也有三年以上。

不过低功耗设计有个坑:ADS122U04 从休眠唤醒到转换稳定需要时间,基准电压建立、PGA 稳定都需要几百微秒。如果唤醒后立刻启动转换,前几次读数是不准的。我一般唤醒后先发一个空转换命令,丢弃结果,再发正式转换命令。这样多花一点时间,但数据可靠。

5.3 固件升级与参数配置的现场维护方案

工业设备装到现场之后,改参数或者升级固件是个麻烦事。如果每次都要拆机接调试器,维护成本太高。我的做法是在 STM32F042K6 的 Flash 里划一块区域存参数,包括校准系数、Modbus 从站地址、波特率、上报周期等。通过 Modbus 的写寄存器命令可以远程修改这些参数,改完存 Flash,重启生效。这样现场调试人员用组态软件就能改,不需要拆机。

固件升级可以用 UART 的 Bootloader。STM32F042K6 出厂自带系统 Bootloader,通过 BOOT0 引脚拉高进入。但现场设备封装好了,BOOT0 引脚不一定引出来。所以我在应用里写了一个自定义 Bootloader,通过 Modbus 或者自定义协议接收固件数据,写到 Flash 的应用区,写完跳转。这个方案需要仔细设计 Flash 分区和跳转逻辑,但一旦做好,现场升级就方便了。

提示:自定义 Bootloader 一定要加固件校验,比如 CRC32 或者 SHA256,防止传输过程中数据出错导致设备变砖。校验不通过就不跳转,留在 Bootloader 里等待重新传输。

6. 个人实操中的几点体会

这套 ADS122U04 加 STM32F042K6 的方案,我从第一个原型到现在批量出货,前后改了五版硬件、三版固件。最大的体会是:高精度测量里,硬件和软件各占一半,谁也离不开谁。硬件设计得再好,固件里寄存器配错一个位,读数就是垃圾;固件写得再漂亮,硬件地平面没处理好,噪声照样让你崩溃。

另一个体会是不要迷信数据手册的典型电路。数据手册上的电路是理想条件下的,实际现场有各种意想不到的干扰源。我现在的习惯是每个项目都留出滤波器的位置,调试的时候根据实际情况决定焊不焊、焊多大。PCB 上多留几个 0603 的焊盘不花什么钱,但调试的时候能救命。

最后说一个关于 PT100 选型的小技巧。市面上 PT100 有薄膜式和绕线式两种。薄膜式便宜、体积小,但长期稳定性稍差,适合消费级和商用 HVAC。绕线式贵一些、体积大,但抗振动和长期稳定性好,适合工业现场。如果你的应用环境温度经常超过一百五十度,或者有强烈振动,多花点钱选绕线式,后期维护成本会低很多。这个账要算长远,不能只看采购成本。

返回列表