☰
基于STM32与PJ85718DM的双通道温度监测系统设计
2026/10/22 1:06:37 网站建设 项目流程

1. 项目思路:为什么要用双通道温度监测方案

接了一个测温相关的活儿,要在同一块控制板上同时监测两处温度:一是板卡自身环境温度,二是远处一个功率模块的壳体温度。前者用来判断设备工作环境是否过热,后者用来保护功率器件防止结温超限。最初考虑过用两颗单通道传感器分开测,后来综合布线、成本和代码量,最后选了 PJ85718DM 这颗本地/远程双通道数字温度传感器,搭配 STM32F411RE 主控来做整个温度采样与上报逻辑。

这个场景不是个例。嵌入式设备里经常出现"既要测板内又要测板外"的需求,比如服务器主板既要感知机箱进风温度,又要测 CPU 附近的电压调节器温度;再比如 HVAC 的楼宇控制器,既要测回风管道温度,又要把传感器探头拉到室外测新风温度。如果每个测点都用一颗完整的数字传感器,物料成本、PCB 面积和 I2C 总线占用都会翻倍。而 PJ85718DM 这类双通道器件,一颗芯片就能同时处理两个测点——本地通道用内部集成传感器,远程通道通过外部接口接一个配套的温度敏感元件,结构上非常紧凑。

STM32F411RE 在这里的角色是主控:负责通过 I2C 接口轮询传感器寄存器、做温度数值换算、执行滤波与阈值告警判断,再把数据推送到显示终端或更高一级的控制器。这颗 MCU 本身是 Cortex-M4F 内核,主频 96MHz,片上有 512KB Flash 和 128KB SRAM,I2C 外设最高支持 1MHz 快速模式,对于温度采样这种低频轮询任务来说绰绰有余。选它的原因很直接:项目里还需要顺便跑一些浮点运算和通信协议栈,算力比普通 Cortex-M0 系列宽裕,而且功耗控制更灵活,能够满足设备长期通电运行的需求。

整个项目的价值点,我认为不是"把 I2C 读通"这么简单。真正决定系统稳不稳的,是远程通道的信号完整性和温度校准。远程测温通道本质上是在测量一个外部 PN 结正向压降随温度的变化,这个电压信号非常微弱,受布线长度、干扰源、焊接电阻甚至元件型号的影响都很大。如果硬件上没处理好,后续软件再怎么滤波也是白搭。这篇文章把我踩过的坑、验证过的做法和最后的工程参数都整理出来,适合正在做嵌入式测温、HVAC 控制器或者带功率模块散热管理的开发者参考。

2. 硬件设计:PJ85718DM 接线与 PCB 布局

2.1 供电、I2C 总线和地址配置

PJ85718DM 的供电电压范围较宽,常见的 3.3V 系统可以直接使用,功耗也很低,典型工作电流在微安到毫安级别,不会对被测对象造成明显的自发热干扰。它的 I2C 接口支持标准模式(100kHz)和快速模式(400kHz),直接和 STM32F411RE 的 I2C1 外设相连即可。SDA 和 SCL 两根线上需要接上拉电阻,取值根据总线负载而定,我这块板上挂了包括一颗外部 EEPROM 在内共三个设备,总线电容不大,用 4.7kΩ 上拉到 3.3V 实测波形干净,边沿时间完全满足 400kHz 的时序要求。如果板上设备多、走线长,可以考虑降到 2.2kΩ。

器件地址是靠地址引脚的电平组合决定的,它有一个引脚用于选择地址位。不同的电平接法会得到不同的 7 位 I2C 地址。我这个板上把地址引脚直接接地,得到默认地址,配合 STM32 的 HAL 库,写地址时需要将 7 位地址左移一位,这一点和不少 MCU 的寄存器描述一致。如果因为总线上有其他设备占用默认地址,可以把地址引脚拉高改成另一个地址,设计初期最好在 PCB 上预留 0Ω 电阻位用于切换,免得改版。

注意:I2C 非常害怕总线无上拉和地址冲突。调试时遇到通信失败,优先用示波器确认 SDA/SCL 的静态电平是否为高,而不是先去怀疑代码的时序参数。

2.2 远程测温通道的电气连接

远程通道是这颗芯片最有特点的部分,也是整个项目里最容易翻车的地方。PJ85718DM 的远端通道有两个引脚,分别对应外接感温元件的正极和负极连接。这个外接元件实际上是一个 PN 结,工程上最常见的做法是选用标准小信号三极管,把基极和集电极短接,利用发射极-基极结作为感温端。为什么选这种结而不是普通二极管?因为三极管的 VBE 特性在小电流下更接近理想二极管方程,温度线性度更好,而且标准型号之间的工艺一致性好,传感器芯片内部有专门的电流翻转技术和校准参数来抵消串阻影响,用通用三极管能得到比较稳定的结果。

远程通道的连线要尽量控制寄生电感和电阻。我这里遇到过两种情况:一种是探针短距离直连 PCB,走线约两厘米,效果很好;另一种是需要外延线缆接到远处被测设备,线长接近半米,这种情况下就不得不考虑串扰和串联电阻了。我的处理方式是把线缆换成双绞线或者带屏蔽层的排线,并且把走线频率控制在低频,避免与板上的开关电源走线平行。还有一点非常容易被忽视:要限制元器件端到传感器的距离,通常不要超过 1 米,如果必须超过,建议在器件选择阶段咨询厂家推荐的最大线缆长度,或者改用电流环类的温度变送器方案。

为了抑制高频耦合噪声,工程上通常会在远程通道引脚间并一个小电容,但取值极有讲究。电容太大,会把微弱电压信号的低通特性破坏掉,导致温度读数偏慢、动态响应失真;电容太小又起不到滤波效果。结合实测,我最后用了 1nF 的电容,普通贴片 0402 封装,直接就近放在传感器的远程引脚旁边。如果通道走线非常短且远离干扰源,不并电容也可以,但并了之后系统更稳定。

2.3 PCB 布线与抗干扰设计补充

除了远程通道的注意事项,整板布局也影响最终精度。首先是传感器的供电脚必须加去耦电容,典型配置是 0.1μF 陶瓷电容紧贴供电引脚放置,必要时并联一个 1μF 电容用于抑制低频电源纹波。PJ85718DM 的模拟被测对象比较敏感,给它供电的线路不要在板上跨越高频数字走线,最好用单独的模拟电源走线或者从电源树中引一个干净的 LDO 输出。

其次是地平面设计。我在这个项目里做了完整的底层地平面,尽量保证传感器的地引脚、远程通道的地、去耦电容的地都在同一块连续的地区域里,避免数字地模拟地分割造成的共地阻抗抬升。对于 HVAC 控制器这种可能需要接入交流市电的设备,还要留意隔离区的爬电距离和安全间距,传感器这部分属于低压弱电区域,与强电区域之间留足间距,并通过过孔和割槽做隔离。

整板 I2C 信号布线也要注意:SDA、SCL 最好等长且远离高频 PWM 输出和时钟线,如果板上有大电流继电器或感性负载驱动,吸合瞬间会有较强的 dV/dt 干扰,I2C 线远离这些区域的同时可以考虑在 MCU 端加 RC 滤波或施密特缓冲,但这属于极端场景了。常规做法下,规范的布局已经能保证温度数据稳定。

3. 软件驱动:寄存器读写与温度换算

3.1 I2C 通信初始化与自检流程

固件部分我基于 STM32F411RE 的 HAL 库展开,I2C1 挂在 APB1 总线上,时钟配置为 42MHz,经过分频得到 400kHz 的快速模式通信频率。初始化代码的核心是设置 I2C 时序参数,HAL 库会根据传入的时钟频率自动计算。

I2C_HandleTypeDef hi2c1; static void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 400000; /* 400kHz Fast Mode */ hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; /* MCU 作为主机不需要自己的地址 */ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } }

上电后不要立刻读温度,我会先让主控延时,等待传感器内部完成复位和自检,再读取一个出厂 ID 寄存器来确认 I2C 通信链路是通的。这一步非常有必要,它的成本只是一次寄存器读操作,但能省下后面大量排查通信问题的时间。如果 ID 读出来全 FF 或者全 00,基本可以断定硬件连接有问题;如果 ID 正确,下一步再把配置寄存器写一遍,包括转换速率、告警使能以及温标选择(摄氏度/华氏度),随后才正式开始温度轮询。

3.2 温度寄存器解析与换算公式

PJ85718DM 的温度寄存器是 16 位读取形式,其中 12 位有效数据,左侧对齐。读取顺序是先读高字节地址,再读低字节地址,底层 I2C 协议上通过一次突发读把两个字节连续取出。把两个字节组合成 16 位整数后,温度值需要通过固定的数据格式换算。

它本质上是将 12 位有符号数左移 4 位存储,所以换算时要把原始 16 位数值右移 4 位,然后将结果乘以 LSB 对应的温度步进 0.0625°C。用一段代码来表达更直观:

float read_temperature(uint8_t reg_high, uint8_t reg_low) { uint16_t raw = ((uint16_t)reg_high << 8) | reg_low; int16_t signed_raw = (int16_t)(raw & 0xF000) ? raw - 0x10000 : raw; return (float)(signed_raw >> 4) * 0.0625f; }

这里必须处理负数温度的情况。如果只把 16 位数据当无符号数来移位,零下温度会完全错乱。HVAC 场景里室外新风温度经常跌破零度,嵌入式功率模块也可能工作在零下环境,所以有符号处理是必须的。我的做法是先把组合后的 16 位数据转成 int16_t,然后判断高 4 位是否为符号扩展位,再用减法还原真实的正负量。实际测试时把传感器放到冰水槽里,读取到的数值在 0.2°C 附近波动,验证了换算逻辑的正确性。

远程通道和本地通道的寄存器布局不同,但换算公式完全一致。芯片内部已经把远程通道的非线性特性做了校正,我们读到的数值就是直接可用的温度结果,不需要再做分段查表之类的复杂补偿。这也是这类专用温度芯片相比用 ADC 直接采集外部热敏电阻的优势——软件省事太多了。

3.3 数据滤波与告警逻辑设计

直接读取的温度值如果布线不佳,会有一定程度的高频跳动。我在软件层面加了两个滤波:先做一次滑动中值滤波,缓存最近五个采样值,取中间值作为当前输出;再做一阶低通滤波,相当于对平滑后的数据进一步抑制随机噪声。中值滤波能有效剔除偶发的野值,低通滤波则负责消除持续性的仪表级抖动,两者结合,实测数据从原来最多 ±0.5°C 的毛刺降到了 ±0.1°C 以内。

一阶低通的系数选择不需要太激进。如果采样周期固定为 500ms,时间常数可以取 3~5 秒左右,这个量级的低通滤波对 HVAC 中温度缓变过程几乎没有感知延迟,但又能显著稳定读数。过度的滤波反而会导致系统对真实的温度突变响应迟钝,当告警阈值恰好处于临界点时,有可能会错过保护窗口。

告警逻辑我采用了传感器自身的阈值比较功能,同时也让主控做二次判断。传感器内部有本地高温阈值寄存器和远程高温阈值寄存器,把阈值写入后,当对应通道温度超过阈值,它的告警输出引脚会被拉低,STM32 端把该引脚配置为外部中断输入,这样即使主控忙于通信栈、没有及时轮询,也能响应过热状态。此时中断回调里会执行突发事件处理,比如切断功率模块的驱动信号、置位告警标志、在显示屏上弹出提示。双保险设计下面是值得的,毕竟一旦功率模块因为热失控损坏,返厂维修的成本远超一粒传感器的钱。

临界告警的判定数值也不是拍脑袋定的。功率模块的允许壳温通常由规格书定义,把规格书中的上限温度减去 15°C 作为告警阈值,预留出传感器本身的温度滞后和被测件到感温点的传热温差余量。

4. 工程化实用技巧与常见问题排查

4.1 校准和精度实测记录

硬件组装完成后,我先做了一次简单的精度校准。方法很土,但非常有效:把传感器本地测温部分和远程感温探头同时贴在一个小型恒温铝块上,铝块放置在稳定的室温环境里,然后用一台精度 0.1°C 的参考温度计贴近铝块记录真实温度。每隔一段时间读一次 PJ85718DM 的输出,对比之后发现本地通道误差在 +0.3°C 左右,远程通道误差在 -0.2°C 左右,都在规格书给出的误差带内,不需要单独做软件偏移修正。

把环境温度从 20°C 逐步降到 5°C 的条件下再测,远程通道数据始终跟随参考温度计的变化,且差值没有明显扩大。这说明远程通道的半导体 PN 结测温方法在整个工作温度范围内具备良好的线性度,不像热敏电阻那样需要额外创新高次多项式来进行拟合。

需要再次强调的是,不要轻易相信用热风枪吹一下或者用手捂一下来验证测温功能的做法。那种验证只能证明数据在变,不能证明数据是准的。有条件的还是搭个小恒温环境,没有恒温源至少也要用冰水混合物提供一个 0°C 的标准参考点,这样才能确认零度附近的换算逻辑和一阶滤波算法没有把误差带跑偏。

4.2 通信不稳定的排查方法

最典型的故障是 I2C 总线挂死:传感器正常响应几次之后总线占用状态一直拉低,MCU 侧 HAL_I2C_Master_Transmit 返回超时。第一次遇到时我以为是 PJ85718DM 坏了,后来发现是主机在错误时序下发送了停止信号,导致从机状态机卡死。解决办法是给 I2C 通信加超时和错误恢复机制:在长时间通信超时后,对 SCL 线手动翻转几个时钟周期,让从机释放 SDA,然后重新初始化总线。虽然 HAL 库内部有忙检测,但实际的释放操作仍然给出了更好的恢复效果。

第二个常见问题是读到的温度数值突然跳变为大正数或大负数。这种情况往往不是传感器坏了,而是读取过程中总线出现干扰。跳变到全 1 的状态通常预示着 I2C 多字节读取的下一个字节被时钟延展或位错误影响。我后来把 I2C 外设的模拟噪声滤波打开、在通信过程中关闭全局中断保证传输原子性之后,这类跳变基本消失,中值滤波再把偶尔残留的野值拉掉了。

还有一点很琐碎但很关键:代码里读写寄存器时地址一定要做左移一位处理,因为 HAL 库 I2C 地址接口接收的是 8 位地址,即 7 位地址左移一位后,最低位作为读写标志。我最早从寄存器手册直接搬运地址值,没左移,结果通信时好时坏,这种地址错位还很难一眼看出来。如果读到的 ID 值是预期值的一半或者倍数关系,先检查这一下再谈别的。

4.3 远程通道读数异常的排查实录

远程通道数据比本地通道更容易出怪问题。我在调试过程中遇到过一次非常典型的故障:远程温度显示比真实值高出近 10°C,且波动幅度很大。排查过程从软件一路做到硬件,最终发现是远程感温元件焊接时把引脚间残留了助焊剂,引入了微小的漏电通道,相当于给 PN 结并联了一个泄漏电阻,破坏了传感器内部对串阻的补偿算法。

把这根远程探头拆下来,用酒精彻底清洗器件表面和焊盘,重新焊接后在显微镜下确认两引脚间无残留物,再上电测试,读数恢复到了正常范围。这个经验让我后续做所有带远程通道测温的板卡都增加了一个强制流程:远程感温元件焊接后必须做一次"两引脚之间的绝缘电阻测量",至少在 100MΩ 以上才算合格。

另一个容易踩的坑是感温元件选型不对。项目初期我随手从库里找了一个普通信号二极管接上去,结果远程通道读数虽然也有温度响应,但误差带明显变大,线性度也不好。查阅手册发现,这颗芯片的远程通道是专门为小信号三极管的 PN 结特性设计的,普通开关二极管的伏安特性曲线不完全匹配。换成标准规格的小信号三极管作为感温探头之后,远程通道读数立即符合预期。批量生产中也遇到过不同封装批次的三极管因电流增益差异造成轻微误差,最后统一采购同一批次解决了。

远程通道走线长度也限制得非常严格。有一次为了结构方便,把探头线延长到约 1.5 米,虽然用了双绞线,读数还是出现无规律的上下漂移。分析下来,一是线间电容增大,影响了芯片内部的 delta 电压测量过程;二是线缆长度带来的天线效应把环境中的工频干扰耦合了进来。后来把信号调理参数调整、线缆缩短到 0.8 米内,问题才彻底解决。

提示:如果你的系统实现强约束的远程线缆长度,务必提前确认传感器型号的线缆补偿能力,否则后期改机械结构会非常被动。

还有一次故障是某个批次板卡在上电后远程通道读数异常偏小,排查发现某个采样电阻封装焊接时连锡,导致内部偏置电流路径改变。这类问题要靠目检和 X-ray 抽检来防止,固件层面能做的只是在自检逻辑里加一个远程通道开路/短路检测位判断,一旦状态位异常直接报错,不让系统带着错误的温度数据继续运行。

5. 一些总结之外的小建议

这套 PJ85718DM + STM32F411RE 的方案做完之后,最大的体会是:"远端测温"的价值在硬件而不是软件。只要芯片选对了,软件只是做螺丝刀的活——读寄存器、换算、滤波。真正的功夫在于如何把那一对远程引脚接好,如何处理好布线和器件选择。我最开始走弯路就是因为轻视了远程通道的信号完整性,想着传感器芯片自带补偿就万事大吉,结果被现实好好上了一课。

如果后续要把这个方案扩展到更多通道,可以考虑一个 I2C 总线上挂多颗 PJ85718DM 的方式,每颗用不同的地址引脚配置加以区分。又或者把 STM32F411RE 的 DMA 功能用起来,在轮询周期内直接通过 DMA 搬运 I2C 数据,减轻 CPU 占用——这个方法对于同时采集多通道并要实时上报数据的系统很有价值。温度监测的项目往往是系统中最基础、最不显眼但最关键的一环,希望这篇分享能让你在设计和调试时少走点弯路。

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

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

立即咨询