去年调一套空调箱控制器的时候我被一个现象卡了很久控制板上PCB的温度才四十多度功率管的壳体却已经将近九十度了而系统里显示的温度还总是慢半拍。问题很简单板上那颗NTC热敏电阻测到的是“板温”热源却在电路板的另一侧、隔着铜箔和变压器。后来我把测温方案换成了带远程二极管通道的PJ85718DM配STM32L4A6RG一颗芯片同时读本地板温和几米外的远端结温才把温度监测这事真正理顺。这篇文章把我的选型思路、原理理解、硬件连接、软件驱动到实测校准和踩坑记录完整写出来给正在做HVAC控制器或嵌入式板级温度监测的朋友一个可直接抄作业的参考。1. 本地加远程的温度监测不是多此一举1.1 HVAC和嵌入式场景里温度测点到底在哪儿做HVAC控制的人应该都有同感一个空调箱或者风机盘管控制器上真正关心的温度往往不在控制板附近。回风温度要伸进风道里去测盘管防冻要贴在翅片或者管壁上压缩机排气温度则可能在金属管路上。这些测点距离主控板少则半米多则好几米。如果只用板载热敏电阻测的是板子自己发热后的温度跟风道里的实际空气温度完全是两回事。嵌入式场景其实更苛刻。CPU、GPU、功率MOSFET这些热源都在封装内部常规做法是把热敏电阻贴在散热器上测外壳温度但外壳温度跟芯片结温之间有明显的滞后和温差。想直接测芯片内部温度只能靠芯片自带的温度传感器或者利用芯片内部二极管的温度特性用一颗外部的远程温度传感器芯片去读取。而大多数功率器件和高端处理器并不会把测温二极管引到外部来。1.2 一颗PJ85718DM同时解决板温和远端测温PJ85718DM这颗芯片的核心价值就是在一个小封装里集成了一路本地温度测量和一路远程温度测量。本地通道测的是芯片自身所在的PCB环境温度远程通道通过两根引脚接一个外部二极管或三极管就能把测温点延伸到任意需要的位置。这样主控板上只需要一个小探头就能把风道温度、盘管温度、功率器件结温这些远端温度读回来。跟传统的NTC方案相比这种做法的优势非常明显。NTC的阻值-温度关系非线性需要查表或者用Steinhart-Hart公式拟合而且导线越长引线电阻带来的误差就越大四线制接法成本又高。PJ85718DM的远程测温用的是二极管正向压降随温度变化的特性信号是毫伏级的电压差对引线电阻不敏感线长一些影响也小。再加上它本身就是I2C/SMBus接口的数字输出直接连STM32L4A6RG不需要额外接调理电路PCB面积和物料成本都能压下来。1.3 远程测温的底层原理用ΔVBE换温度远程通道能测温度靠的是半导体PN结的正向压降VBE与温度之间的近似线性关系。不过单个PN结的VBE绝对值和工艺参数关系很大直接测绝对压降很容易引入器件误差。所以PJ85718DM实际用的是ΔVBE方法用两个不同的电流I1和I2分别流过外部二极管测出两次的压降变化量ΔVBE再根据物理公式算温度。这个公式写出来就是ΔVBE (kT/q) × ln(I2/I1)其中k是玻尔兹曼常数q是电子电荷T就是绝对温度。由于ln(I2/I1)里两个电流都是芯片自己设定的固定值所以整个表达式里唯一的变量就是温度T二极管本身的饱和电流、串联电阻、工艺偏差都做了差分消除。这也就是为什么要用外部二极管或二极管接法的三极管而不是随便一个稳压管。实际项目中我用的是小信号三极管把基极和集电极短接基极接D发射极接D-这样等效成了一个纯正的PN结测量一致性非常好。理解了这层原理后面所有硬件设计和故障排查都有了依据D和D-引脚上任何影响微小电压测量的因素比如走线电阻、寄生电容、外部噪声都可能直接干扰温度读数。2. 硬件电路设计从PJ85718DM到STM32L4A6RG的完整链路2.1 传感器端的最小电路与引脚说明PJ85718DM的外围电路非常简单供电脚加一个0.1μF和1μF的陶瓷电容做去耦I2C的SCL和SDA各接一个上拉电阻到3.3V地址选择脚接高或接低确定从机地址报警输出引脚ALRT接MCU的一个EXTI输入D和D-两个引脚单独引出去接远程探头。我实际用的上拉电阻是4.7kΩI2C总线速率配置成100kHz标准模式跟传感器的手册要求兼容。这里特别提醒一下供电问题。大多数这类SMBus温度传感器的工作电压范围是3.0V到5.5VSTM32L4A6RG的GPIO和I2C接口是3.3V逻辑如果传感器也供电3.3V接口电平自然匹配。如果系统里已经有5V电源想直接给传感器供电那就需要确认传感器引脚是否兼容3.3V逻辑或者做电平匹配否则I2C总线高电平可能会对MCU引脚造成不安全的应力。我习惯统一用3.3V供电省事。ALRT引脚值得多说一句。这个引脚是开漏输出所以也必须外接一个上拉电阻否则MCU读不到电平变化。ALRT可以配置成比较器模式或事件模式温度超过上限或低于下限时触发低电平脉冲或锁存信号非常适合在低功耗系统里把MCU从停止模式唤醒。2.2 远程二极管的接法与关键滤波细节远程测温探头的接法是整个硬件设计里最容易被忽视的部分。我推荐使用MMBT3904这种小信号NPN三极管把基极和集电极直接短接基极接到D发射极接到D-。注意一定用的是基极-发射极的PN结不是基极-集电极那个结因为发射结的VBE特性更理想离散性更小。探头的物理位置决定了温度测量的意义。做HVAC应用时可以把探头封装在一个细小的金属套管里插入风道做功率器件监测时把贴片三极管贴在散热器上用导热硅脂填充间隙引脚引回D和D-。这根两芯线的走线要成对、贴近尽量远离开关电源的MOSFET驱动走线、PWM风扇线这类强干扰源。我在PCB上留了一个可选的1nF电容位置放在靠近D/D-端子处跨接在两条线之间用来滤掉高频共模噪声。这个电容太小会影响信号建立时间太大会导致温度读数误差1nF是个比较均衡的值。还有一个常见问题是D和D-引脚的极性。接反之后芯片不会烧但读出来的远程温度要么是无效值要么明显异常比如显示-128℃或者127℃这类满偏值。我调试时花了不少时间排查最后拿起万用表二极管档一测才发现是探头那边焊反了。2.3 与STM32L4A6RG的连接STM32L4A6RG的I2C外设资源很富裕有好几路独立的I2C控制器。我用了I2C1SCL配置在PB6SDA配置在PB7。这两条线在STM32L4系列上有5V容忍能力配合3.3V上拉到VCC电平上没有问题。如果希望抗干扰更强也可以在SCL和SDA对地各加一个几十皮法的电容但注意总线电容太大会拖慢上升沿影响通信。一般我只有在探头线特别长或者现场干扰严重时才加容量从22pF开始试。MCU的配置很简单I2C标准模式、时钟100kHz、7位地址、软复位关闭、模拟噪声滤波开启。需要确认传感器的从机地址和I2C总线上其他设备不冲突。PJ85718DM的地址一般由ADD引脚的接法决定接GND、接VDD或者悬空会对应不同的地址具体查手册。我这条总线上还挂了一个EEPROM和一个RTC地址都不相同所以没有冲突问题。2.4 电源完整性和地平面处理温度传感器的模拟前端信噪比直接取决于供电和地的质量。不要为了让走线简洁就把传感器放在靠近开关管的地方。PJ85718DM的VDD引脚去耦电容要靠近电源引脚放置地引脚通过短走线直接接到PCB的模拟地或者主地平面。如果板上同时有继电器驱动或可控硅建议传感器区域和驱动区域之间做一点隔离至少不要让高温端子的强电流回流路径穿过传感器的地。另外PJ85718DM本身就是一颗低功耗器件待机模式下电流只有微安级别。STM32L4A6RG在STOP2模式下的静态电流同样非常低这个组合做电池供电的温控器也完全可行。不过低功耗设计有个细节远程通道如果不需要一直测量可以配置成单次转换模式MCU唤醒后发命令触发一次测量读完寄存器再睡这样能省不少电。3. STM32L4侧的软件驱动与温度换算3.1 I2C初始化与传感器寄存器读写用HAL库初始化I2C1非常快关键是正确设置I2C时钟频率。我用的时钟树是MSI或者PLL倍频到80MHz然后给I2C分频到100kHzHAL的初始化结构体里填好时序参数即可。初始化完成后第一步不是直接读温度而是读一个固定寄存器确认通信正常。比如设备的ID或版本寄存器读出来的值如果符合手册预期再继续往下配置。读写PJ85718DM这类SMBus器件建议用HAL_I2C_Master_Transmit和HAL_I2C_Mem_Read这类函数。写配置时先发从机地址再发寄存器地址和配置数据读温度时可以把寄存器地址设为温度数据寄存器的高字节然后连续读取两个字节。连续读的好处是能保证高字节能和低字节在时间上足够接近减小采样间隔内的波动影响。SMBus有PEC校验功能可选HVAC控制器里总线距离不长现场干扰不严重时我一般不开但如果是工业现场开上PEC能避免不少偶发错值。3.2 温度寄存器格式与补码换算这个环节是新手翻车重灾区。PJ85718DM这类传感器的温度寄存器通常是12位或13位的二进制补码格式高字节是符号位和整数部分低字节是小数部分。不同分辨率模式下LSB权重不一样常见的是0.0625℃/LSB也有0.0078125℃/LSB的高精度模式。我用的配置是12位分辨率0.0625℃/LSB。读回两个字节后先拼成一个16位整数然后做符号扩展。假如读到的原始值是0x0190符号位是0直接乘以0.0625就是400×0.062525.0℃。如果读到的值是0xFF30符号位是1需要先扩展成带符号的16位值也就是减掉0x10000得到-208再乘以0.0625就是-13.0℃。写成代码就是int16_t raw (int16_t)((uint16_t)(reg_hi 8) | reg_lo); float temp_c (float)raw * 0.0625f;关键在于raw要定义为有符号16位左移操作时reg_hi要先转成uint16_t再移位避免符号位被扩展到int类型里产生难以察觉的错值。这个坑我换了好几种写法才确认低字节虽然只有高4位有效但读取时多余的位要直接忽略不要去做什么四舍五入不然反而会引入误差。远程通道的读取流程和本地通道完全一样只是寄存器地址不同。我在程序中把本地温度和远程温度分别封装成独立的读取函数返回float类型温度值。上层逻辑做滤波和应用时只跟这两个函数打交道方便后续替换其他型号的传感器。3.3 报警阈值配置与MCU主动唤醒PJ85718DM支持设置高低温报警阈值温度超过设定值时ALRT引脚会产生有效电平。这个功能对实时性要求高的温度保护场景特别有用。普通轮询方式下MCU需要不停读取温度寄存器既浪费CPU又不能在两次读取间隔内第一时间捕捉到温度突变。报警方式下MCU可以长时间待在低功耗模式温度超标时传感器主动拉低ALRT引脚把MCU从STOP模式唤醒MCU再读取具体温度值做处置。配置报警的流程是先设置本地和远程通道各自的THIGH和TLOW寄存器再设置ALRT引脚的工作模式。锁存模式需要MCU读状态寄存器来清除报警比较器模式则在温度回到回差范围后自动恢复。HVAC应用里我一般用锁存模式避免温度在阈值附近抖动时ALRT反复跳变。回差大小可以根据控制精度要求设定比如高温报警设到75℃回差5℃这样温度降到70℃以下才会解除报警现场人员能明显感知保护和恢复的过程。3.4 软件滤波与迟滞处理即使传感器精度够高现场环境的瞬时扰动还是会让读数出现小幅跳变。我做了两层处理。第一层是一次采样内做多次转换求平均PJ85718DM本身支持平均模式设置成连续转换加上平均硬件上就能滤掉一部分噪声。第二层是在MCU侧做一个滑动平均滤波器队列长度取了8次权重均分效果相当于把采样周期内的毛刺平滑掉。但滤波也不是越重越好。HVAC温度对象本身变化很慢滤波重一点影响不大而嵌入式散热保护场景里结温可能在几秒内上升十几度滤波太深会把过温信号淹没保护动作严重滞后。我最后的做法是双路判据滤波后的平均值用于控制逻辑比如风扇PWM占空比调节原始读取值用于快速保护一旦超过硬阈值立即触发中断响应不经过滤波。这样既保持了温度曲线平滑又不牺牲保护响应的实时性。4. 从-20℃到90℃的实测标定与误差分析4.1 标定平台怎么搭标定工作不能省尤其是远程通道。我把PJ85718DM的本地通道部分和远程探头同时放进恒温槽里以恒温槽的实测温度作为参考值。恒温槽用的是油浴式温度范围覆盖-20℃到90℃最小步进5℃。每个设定点让系统稳定至少15分钟等待探头和槽体内温度完全平衡再记录MCU通过I2C读到的本地温度、远程温度以及参考温度计读数。远程探头的固定方式很关键。探头悬空浸在油浴里和直接贴在槽体金属壁上的读数会有差异。我选择的是把探头封装在一个铜套管里浸入油浴模拟HVAC现场把探头插入金属测温套管的场景。这样做出来的标定结果更接近实际。4.2 实测结果整理测试数据大致如下取几个典型点位的均值展示恒温槽参考温度本地通道读数远程通道读数本地误差远程误差-19.8℃-19.6℃-20.1℃0.2℃-0.3℃4.9℃5.1℃5.2℃0.2℃0.3℃25.0℃25.2℃24.9℃0.2℃-0.1℃49.8℃49.9℃50.2℃0.1℃0.4℃70.1℃70.0℃70.5℃-0.1℃0.4℃89.9℃89.5℃89.7℃-0.4℃-0.2℃这个结果在0℃到70℃区间内非常理想本地和远程都控制在±0.5℃以内。低温段误差略大但仍然可以接受。考虑到传感器本身的标称精度通常在±1℃左右这个实测表现说明整个硬件链路没有引入明显的系统性误差。要注意的是这套数据是在探头线只有30厘米、远离干扰源的前提下测出来的。如果现场把探头线延长到两米以上或者走线贴近变频器输出线误差和跳变都会变大。因此标定最好在接近最终安装形态的状态下进行而不是在干净的工作台上测完就认为万事大吉。4.3 误差来源逐项拆解测出来的误差不是随便就能忽略的我把主要误差来源列一下方便排查远程二极管的VBE离散性。不同批次的三极管基极-发射极电压会有几个毫伏差异等效成温度可能就是一两度。解决方法是尽量采购同一品牌同一批次的管子或者在软件里对每个探头做单点偏置修正。D/D-线上的串联电阻。虽然ΔVBE方法对串联电阻有抑制作用但电阻过大时仍然会引入误差尤其是电流切换瞬间造成的压降。我用的是0.25平方毫米左右的细导线长度控制在两米以内。并联电容过大会改变信号建立时间。曾经试过在探头端并了0.1μF的电容结果远程读数普遍偏高好几度换成1nF后恢复正常。这一点原理上跟远端二极管在高频激励下的充放电不平衡有关实际中只能靠实验确定。PCB自身发热对本地通道的影响。本地温度本来就是板温如果板上有大功率发热元件贴着传感器读到的温度自然比环境温度高。这是物理事实不算故障但系统设计时要明确这个读数的含义。5. HVAC与嵌入式落地过程中的实操细节与避坑记录5.1 HVAC场景回风温度和盘管温度怎么布在HVAC应用里我把PJ85718DM的本地通道用作控制器内部的机箱温度监测主要防止控制箱内部过热远程通道则接了一只套管式探头插在回风风道里测回风温度。这个布置的好处是回风温度直接参与PID运算和启停控制而机箱温度用来做设备保护的辅助判断两者互不干扰。很多暖通控制器的回路温度测量以前用的是热敏电阻接到长线上引线电阻在冬夏季温差大的时候会带来不小的误差。换成远程二极管探头后这个问题基本消失而且探头响应速度更快。因为二极管的体积比NTC热敏电阻小得多热容小温度变化时达到平衡的时间更短。5.2 嵌入式场景结温监测与风扇联动另一块应用是把远程探头贴在功率MOSFET的散热片上MCU根据读取的结温来调节风扇PWM占空比。传统做法是固定风扇转速或者根据环境温度粗略调速噪声大、能耗高。用这个方案后风扇转速和真实结温强相关温度40℃时风扇几乎不转温度70℃时缓慢爬升超过85℃才全速运转。整个散热系统的噪声和功耗都明显改善。这里有个细节散热片表面最好做一个非常小的凹槽或者使用导热胶固定三极管保证三极管尽量贴近热源同时又不至于短路到带电的散热片。我用的办法是先把MMBT3904焊在一小块覆铜板上再通过导热硅脂粘到散热片中间用云母片绝缘。引脚引回D/D-时尽量短远离风扇的PWM线和电源线。5.3 我踩过的几个坑和对应的处理办法第一个坑是D/D-接反导致远程温度报出异常值。那天现场温度显示直接从正常值跳到-127℃我没想到是极性接反先是怀疑驱动代码符号扩展写错了反复查程序查了两个小时。后来用万用表二极管档测远程端子才发现探头的D和D-在接线端子处被工人对调了。这个问题在采用可插拔端子连接的系统中特别容易犯建议在设计时把端子的1脚定义为D2脚定义为D-并在丝印上标清楚。第二个坑是I2C偶发超时。现象是系统运行几天后偶尔读不到温度复位后一切正常。最终定位到上拉电阻用了1kΩ而总线上挂着三四个器件低电平灌电流偏大把传感器的I2C输出级压得很厉害。换成4.7kΩ之后连续跑了一个月再没出现过通信错误。第三个坑是ALRT引脚悬空。开始设计时认为不用报警功能就没接这个引脚。结果传感器正常工作时该引脚因为没有上拉电阻而呈现不确定电平恰好又跟旁边一个GPIO产生串扰导致MCU莫名其妙进中断。后来哪怕不用报警功能也把ALRT通过10kΩ电阻上拉到3.3V问题消失。第四个坑关于SMBus和I2C的时序差异。传感器的SMBus接口有数据保持时间的要求而STM32的I2C外设在某些配置下释放总线的时机偏快读写密集时偶尔会出问题。解决的办法是把I2C时钟降到100kHz并且开启I2C的模拟噪声滤波和数字噪声滤波读操作之间加一个微秒级延时。5.4 低功耗模式的联动策略这套方案如果要跑电池或者需要低功耗运行PJ85718DM和STM32L4A6RG的配合可以设计成完全事件驱动的方式。正常运行时MCU进入STOP2模式所有不用的外设时钟关闭I2C也关闭只有ALRT引脚对应的EXTI保持使能。PJ85718DM保持连续转换状态本地或远程温度一旦超出阈值ALRT拉低MCU被唤醒后重新初始化I2C读取状态寄存器和温度值完成控制动作后再进睡眠。实测下来系统平均功耗可以压到非常低休眠期间整机电流主要由传感器的静态电流和上拉电阻漏电流贡献。这种事件驱动设计的关键是报警阈值的设置要合理不能太灵敏频繁唤醒MCU也不能太迟钝漏报问题。我通常在室温基础上加8℃作为告警阈值回差设为4℃这样正常工作时MCU基本处于睡着的状态温度出问题才能及时醒。最后分享一个我调试这套方案时最管用的细节远程探头那两根引线在靠近传感器的位置并联一颗1nF的高频陶瓷电容能明显改善温度读数的稳定性而几乎不影响精度。当时现场有变频器干扰远程读数每秒跳0.3℃加上这个电容之后读数的跳动降到了0.0625℃以内。这个做法成本几乎为零却解决了最头疼的现场干扰问题强烈建议大家在设计阶段就预留这个电容的位置。