基于PJ85718DM与PIC24EP的本地远程温度监测方案
入行这些年我做过的测温板子两只手数不过来一开始是板卡上CPU、FPGA的结温后来是机房空调的风机盘管、送回风温度。测温这件事听着没技术含量真正落地却很磨人——探头离得远线阻和噪声就找上门NTC要一颗一颗标定单总线传感器排成链坏一个后面全瞎。后来在一套嵌入式和HVAC控制器共存的系统里我把本地与远程温度监测的方案统一成PJ85718DM加PIC24EP512GU814前端芯片管温度采集主控芯片管总线调度、报警和控制算是把这套组合彻底跑顺了。这篇文章把我从选型、原理图、固件到实测调坑的完整过程写出来。想看结论的可以直接跳到最后一段想自己复现的建议按章节顺序过一遍里面有几个坑是我反复踩过之后才找到根因的。1. 为什么把本地与远程温度交给 PJ85718DM1.1 你面对的温度点从来不是一个做嵌入式系统的人一开始往往只关心一颗芯片的结温真到整机调试就会发现电源模块、PCIe转接卡、机箱进风口、散热片背面全是需要看温度的地方。HVAC控制器更夸张送风温度、回风温度、盘管进出口温度、室外冷凝器温度一个机组少的五六个点多的十几二十个。这些点有一个共同特征——不可能全部放在主控板附近。于是测温方案就变成了“传感器探头放在远处信号拉回主控”。模拟信号拉远了线阻、共模噪声、分压误差都会找上来数字信号拉远了就得考虑协议抗干扰能力和总线拓扑。PJ85718DM这类前端温度传感器最适合的恰恰是这个位置它把远程的PN结探头信号变成I2C数字量只靠两根差分线就能拉到一两米外中间即使穿一点干扰也是数字信号回传不会因为线长而直接改变温度读数。我选PJ85718DM的核心原因是它一个芯片就能覆盖两个测温方向本地通道芯片自身附近的PCB温度、模块温度远程通道外部二极管或三极管的PN结温度也就是真正贴在发热元件上的那个“远方探头”。一片PJ85718DM最多能管两路远程加一路本地三片五片挂到同一条I2C总线上一个机柜的测温点就齐了。1.2 PIC24EP512GU814 在系统里的角色传感器只是眼睛真正干活的是主控。PIC24EP512GU814这颗16位MCU在这个方案里干四件事通过I2C轮询所有PJ85718DM读取并处理温度数据用PWM输出控制风机转速或水阀开度碰到超温或传感器故障时拉高报警通过USB或UART把数据上报给上位机或者楼宇自控系统。选它而不是几块钱的小单片机主要原因有三个。第一程序空间够大512KB Flash让我可以放心地跑温度滤波、故障诊断、控制状态机这一整套逻辑不用天天抠ROM。第二外设齐全I2C、UART、USB、多路PWM都能同时工作不用为“哪个外设优先”去做冲突处理。第三这颗芯片的I/O非常灵活远程探针线和ALERT中断线可以映射到顺手的位置布板时不至于为了一个引脚绕一大圈。更重要的一点是可靠性。HVAC环境里有大功率电机、电磁阀、变频器干扰源密集成堆。PIC24EP系列的工作电压范围宽抗干扰能力在16位MCU里算稳的工业级的温度范围也覆盖了室外机可能遇到的零下温度和机柜内的高温。1.3 和NTC、单总线的取舍方案选型阶段我拿PJ85718DM和最常见的几种做法逐一做了对比。不是要分出绝对高下而是要看清“哪个方案在哪类场景最合适”。我自己的对比逻辑很简单NTC便宜但每一路都需要ADC通道、分压电阻和查表校准长线还要做线阻补偿单总线方案成本低、布线简单但对时序比较敏感长线容易受干扰而且在强电环境里一旦有器件损坏一整条总线都要检查PT100精度高可模拟前端调理电路的复杂度和成本直接劝退。PJ85718DM走的是另一条路——用I2C总线天然支持多片挂载远程通道接的是PN结而不是电阻测的是Vbe差值而不是绝对阻值从原理上就不怕串联电阻和线缆电容带来的一堆麻烦。单看物料成本PJ85718DM加三极管的组合要比NTC方案贵但省下的ADC通道、校准工时、布线屏蔽和Debug时间在项目里远比几毛钱差价值钱。对于“温度点分散、距离远、电磁环境复杂、后续还想扩点”的嵌入式和HVAC系统这套方案的性价比是明显更高的。2. PJ85718DM 的测量路径与关键寄存器2.1 远程通道测的其实是晶体管的Vbe很多人第一次看到“远程二极管测温”会愣一下一个三极管怎么能当温度传感器其实原理并不神秘。PN结的正向压降Vbe本身随温度漂移大约每升高1°C会掉2mV左右。直接测这个绝对压降误差会很大因为每颗三极管的饱和电流Is不同Vbe的绝对值差异就能顶掉好几度的精度。所以PJ85718DM这类芯片都采用“不同电流比值法”先给小电流I1测一次Vbe1再给大电流I2通常是小电流的十倍测一次Vbe2。两个压降相减Is的影响被消掉剩下的是与温度严格相关的ΔVbe。根据物理公式ΔVbe (kT/q)×ln(N)其中N是两个偏置电流的比值。芯片只要把ΔVbe测准温度就出来了。这也是远程通道一定要用三极管或二极管的原因——PN结是天然的温敏探针不需要额外的传感器。我用得最多的是PNP三极管比如常见的小信号管2N3906或者贴片封装MMBT3906发射极接“正”端基极和集电极并在一起接地。一颗几分钱的三极管导热胶粘在散热器或者功率器件外壳上就是一个稳定的温度探头。2.2 本地通道和寄存器地图本地通道则简单得多芯片内部自带一个带隙基准测量PJ85718DM自身封装附近的温度。它反映的是PCB表面的环境温度适合监测模块进风口温度、控制柜内部温度这类“局部环境”变化。我手头这颗PJ85718DM的寄存器结构和市面上主流的多通道温度传感器很相似核心寄存器包括本地温度高字节和低字节、远程温度1高字节和低字节、远程温度2高字节和低字节、配置寄存器、状态寄存器、阈值上限/下限/热限寄存器和迟滞寄存器。配置寄存器里能选连续转换还是单次转换、转换速率、数字滤波开关、远程探针偏置电流极性等。状态寄存器则用来判断远程探头是否开路、是否短路、有没有触发阈值。温度数据保存格式一般是11位有符号数据加0.125°C的分辨率不同芯片也可能扩展到0.0625°C。读取时把高字节和低字节拼起来做符号扩展再乘上分辨率就是实际温度。小数部分通常只有0.125的倍数对HVAC控制来说已经绰绰有余。2.3 ALERT中断机制别浪费PJ85718DM的ALERT引脚是开漏输出默认低有效。当任意一路温度越过阈值上限或下限时状态寄存器对应标志置位ALERT被拉低。PIC24EP的任意I/O都可以配置成中断输入把ALERT接到一个外部中断引脚上MCU就可以做到“平时不打扰、出事立刻响应”。ALERT有两种模式值得注意比较模式和事件模式。比较模式下只要温度保持在阈值边界内、哪怕状态没清除ALERT也会自动恢复事件模式则是“锁存”的温度已经正常但必须通过I2C清状态位ALERT才会拉高。我用事件模式更多因为它不容易漏报——锁存住代表“管过出问题”直到维护人员确认过才清除天然自带报警记录功能。远程探针开路或短路状态寄存器里也有专门的故障位。这一点在工程上特别重要否则探头坏了温度读数会漂到离谱的数值控制逻辑很可能误判成“过热停机”或者“过冷保护”比不测温还危险。3. 原理图到PCB远程探针和I2C总线的落地方案3.1 I2C地址分配、上拉电阻和级联数量PJ85718DM的I2C地址是靠引脚电平决定的。常见的地址脚有A0和A1两根分别接低或接高就能得到四个不同地址。一根I2C总线上直接挂四片PJ85718DM也就是4个本地通道加8个远程通道总共12个测温点。地址规划建议给每个传感器贴上物理丝印编号比如J1/J2/J3/J4固件初始化时也按同一顺序扫描后面调试会省很多事。上拉电阻的选择要按总线上挂的芯片数量和总线长度具体算。一片两颗芯片的情况下400kHz I2C用4.7kΩ上拉没有压力挂满四片、线长超过半米总线电容上去了上拉电阻可以降到2.2kΩ甚至1kΩ否则上升沿太慢会导致时钟拉伸超时。主控侧的I2C引脚必须配置成开漏模式我在第一版原理图里漏了这一步结果总线直接拉不低排查了半天。3.2 远程探针布线抑制噪声才是关键远程通道的DP和DN两根线是整个设计里最需要花心思的地方。PN结测量信号是毫伏级别虽然芯片已经做了差分测量和滤波但如果线缆和布局处理不好变频器的共模干扰随时会让读数跳好几度。我总结了一套比较稳的布线方法两根信号线尽量并行走保持相同距离最好是双绞不要在DP和DN之间走开关电源的返回路径那样会把di/dt噪声直接耦合进去。在三极管探头那一端放一个100pF到1nF的低ESR陶瓷电容跨接在信号线和地之间把高频毛刺就地泄放。如果探头要从PCB引到机外加一排滤波电容加TVS二极管TVS放在接口端子内侧防止静电感应打坏芯片。远程探针到芯片的走线尽量短这个“短”指的是物理距离不是电气连接。真要拉到两米外一是要选带串联电阻补偿的芯片功能二是避免经过强电区域。我在实验室拉到两米读数只偏差零点几度但一靠近变频器输出端就飘了1到2度这就是噪声耦合打进来的结果不是芯片精度不行。3.3 PIC24EP512GU814 这侧的电源与地PIC24EP512GU814的电源引脚要配套放100nF陶瓷电容每颗电源脚就近一颗总电源入口放一颗10μF钽电容或者大容量的X7R陶瓷电容做储能。如果板上有大功率风扇电机电机驱动部分要和MCU、传感器部分做电源分区地线单点汇合避免电机电流在地网络上拉开电位差把传感器总线上的信号搞得乱七八糟。还有就是隔离问题。HVAC系统里传感器往往跨在强电和弱电之间I2C总线如果要从主板引到强电区域的传感器板上中间加I2C隔离器件是必要的。隔离器件选择双向I2C电容隔离或者磁隔离芯片都可以关键是隔离后的电源和地都要各自独立不能只隔离信号不隔离电源。我见过有人只串两个光耦想省事结果I2C时钟和数据两根线的方向逻辑根本没有处理好总线不是卡死就是漏数据。3.4 冷端和试产测试点设计阶段还要想着生产测试。每一片PJ85718DM的本地通道、远程通道、ALERT输出都要留出测试点方便产线用治具直接测开路短路和温度精度。远程探针插座选带锁扣的比直插式的牢固得多。HVAC产品装进机组之后免不了震动插头松脱导致的温度异常排查起来相当浪费时间。4. 固件栈轮询、中断与温度滤波的平衡4.1 初始化流程不能省PIC24EP512GU814上电后第一步先配置时钟然后初始化I2C外设为主模式频率目标400kHz。I2C外设初始化之后给PJ85718DM一个小的上电延时待传感器稳定后再逐片扫描地址读到预期的设备ID再往下走。初始化顺序很重要——如果PIC一侧I/O还没配好就先把I2C使能总线上可能因为某个引脚是低电平而让别人误以为有起始条件造成传感器状态错乱。我建议的初始化流程是配置I2C引脚为开漏输出和输入模式等待总线空闲检测完成逐片发送设备地址不回ACK就标记为“未找到”对找到的传感器写入配置寄存器、阈值寄存器和迟滞寄存器最后使能PIC的外部中断脚去接ALERT线。配置寄存器里如果开了连续转换传感器会自己周期性更新温度寄存器MCU不需要在采集前发转换命令如果是单次转换模式每次读取前都要触发一次转换读完了还要等一小段时间。在HVAC这种系统里温度变化本来就是分钟级的连续转换模式开8Hz或者16Hz已经非常够用。4.2 读温度与转摄氏度读取温度时我习惯先读状态寄存器再读温度数据。具体代码示意如下int16_t sensor_read_temperature(uint8_t dev_addr, uint8_t temp_h, uint8_t temp_l) { uint8_t hi i2c_read_reg(dev_addr, temp_h); uint8_t lo i2c_read_reg(dev_addr, temp_l); // 典型格式高字节是整数部分低字节高3位是0.125度小数 int16_t raw ((int16_t)hi 3) | (lo 5); return raw; } // 使用时temp_degC raw * 0.125f;平时多路读取时我一次性把四片传感器的数据全部读完再统一换算而不是读一片换算一片。原因很简单I2C每启动一次通讯都有开销多片轮流访问时如果中间插了耗时的浮点运算总线时序会被拖长特别是在高负载情况下通讯错误率会明显增加。我都是读完所有原始寄存器后再进入批量换算和处理。状态寄存器里的远程开路短路标志要按照“清零后重读”的逻辑处理。有的芯片读取状态寄存器后会自动清除错误标志如果只做一次判断可能把瞬时的毛刺当成永久故障。我加了三次连续读三次都报错才列故障瞬时干扰基本能滤掉大半。4.3 ALERT中断和轮询结合在HVAC应用里风扇水阀这类执行器的动作会带来电流冲击。如果只靠ALERT中断做超温保护中断频率太高反而增加程序不确定性。我最后采用的是“轮询为主、中断兜底”的结构主循环每200ms扫一遍所有温度点做滤波和趋势判断ALERT外部中断只在温度越限或者探头故障时触发中断里不做复杂处理只置一个全局标志位主循环看到标志后去读状态寄存器确认是哪个设备哪一路触发再进报警流程。这样即使轮询逻辑因为某个执行器控制分支暂时阻塞ALERT中断也能把人拉回来。但是一定要记得中断服务程序里不要做浮点运算不要跑I2C只把事件记录下来。我之前在中断里直接读传感器结果I2C总线和主循环的读取冲突数据错乱还查不出来。4.4 滑动平均和突变剔除PJ85718DM的瞬时读数在电磁环境恶劣时会有毛刺不能直接拿来做控制输出。我做了一个简单的温度滤波函数保存最近六次读数去掉一个最大值和一个最小值剩下四个取平均。这个滤波对HVAC这种慢速对象特别合适既不伤真实变化的响应速度又能干掉绝大多数脉冲干扰。另外就是突变剔除。如果某一秒读到80°C下一秒读到25°C大概率是干扰不可能是真实温度。我设了一个阈值两次采样温差超过8°C这一拍就先用上一次的有效值顶替并且给传感器记一个“可疑计数”连续出现三次才认定是真实过温。风电、变频器场合下这个策略把误报警次数从一晚上十几次降到基本为零。5. 系统挂了多路传感器之后怎么办5.1 数据组织设备表、通道表和报警等级当系统上了四片PJ85718DM之后数据管理就不能再用散落的全局变量了。我在PIC24EP里维护了一个传感器管理结构体每个传感器实例包含设备地址、本地通道值、远程1通道值、远程2通道值、滤波后的有效值、故障状态、超温计数和报警等级。整个表就放在一个数组中主循环遍历数组对每个实例执行“刷新数据、检查更新、执行动作”三步。控制逻辑上我区分了三档报警关注、报警、保护。关注是温度快到阈值但还有余量只是记录和上报报警是超过第一级阈值输出提示并做适当降载保护是超过硬限温度直接关断执行器或者启动急停。这样做的好处是不会因为一个传感器抖动就直接把整个机组停掉。5.2 传感器的失联和故障容错I2C总线上有一片传感器突然不应答最忌讳的是主控一去不复返。PIC的I2C通讯要有超时机制每次读不到ACK就记失败连续五次失败就标记该设备离线。离线后控制逻辑不再使用这个温度点而是退回到相邻传感器数据或者固定的安全默认值。远程探针开路或短路PJ85718DM状态寄存器会有对应标志。我在读取流程里专门检查这个标志一旦发现探头故障就把该通道的当前温度置为无效并且不参与报警判断。这样做虽然可能少了一个保护点但至少不会因为“探头读数显示零下40度”而导致机组误停机。5.3 USB上报、本地显示和控制输出的串联PIC24EP512GU814自带USB接口我把所有温度数据定期打包成固定结构通过USB虚拟串口上报给上位机。上位机或者SCADA系统只需要解析一个表格化的帧头设备号、通道号、温度值、状态、时间戳。数据上报周期不用太短500ms到1s足够。太短了上位机要处理的帧太多主控也被通讯占掉大量时间。控制输出方面我用了PWM去控风机。温度越高PWM占空比越大风机转速越高但PWM要加斜坡变化不能直接从30%跳变到90%否则电流冲击会影响传感器读数。我实测把斜坡变化步长限制在每100ms变化2%以内系统稳定性明显变好传感器报警也少了很多。6. 实测翻车现场远程读数漂移、误报警与恢复方法6.1 两米长线之后读数为什么偏低第一次把远程探针拉到两米之外做测试读数整整偏低1.5°C。一开始我以为是三极管个体差异换了三颗还是这个结果后来才明白问题出在线阻上。DP和DN两根线各自有串联电阻流过偏置电流时产生压降芯片测到的ΔVbe被“吃掉”了一截。多数远程温度芯片会内置一定范围的串联电阻补偿但补偿量有上限线阻超过补偿范围读数就会偏低。解决的路径有两个加粗线缆降低线阻或者在DP/DN串接等值电阻并保持两线对称让补偿算法更好地工作。我最后换成了正规的双绞屏蔽线单线电阻从每米约1.2Ω降到0.2Ω读数偏差回到0.3°C以内。还有一个隐蔽的原因是地电位差。探针端的地和主板地之间如果有压差等效于把测量基准偏移了。解决方法是让探头端的三极管基极、集电极就近接到独立地线不要和电机电流的大地走同一根线并且屏蔽层单端接地。6.2 ALERT引脚上电误报不是干扰是I/O状态没管好有一版样机出现一个古怪现象上电一开始没接任何传感器ALERT引脚就会被拉低几十毫秒PIC有时候会在这几十毫秒里捕获到一个中断导致系统还没开始工作就先报了一次传感器故障。最初怀疑是电源抖动加了一堆电容无济于事。后来用逻辑分析仪盯着I2C总线和ALERT脚发现PIC复位时I/O引脚默认是数字输入还是模拟输入如果在配置阶段把接ALERT的引脚临时变成了低电平输出就会直接把这条开漏线拉到地制造一次假的低电平有效触发。真正原因是初始化顺序。解决方法是上电后第一时间把与传感器ALERT连接的引脚配置成输入模式开内部上拉然后再初始化I2C和传感器使能外部中断要放在所有传感器都配置完成之后。这是纯软件问题排起来却花了我一个晚上写出来提醒大家。6.4 静电和冷凝水的坑HVAC现场的静电和湿度比实验室严重得多。有一次样机传感器读数在设备动作后瞬间跳到“-128°C”查了半天发现是人为触摸远程接口端子时产生的静电把芯片内部状态打崩了。加了双向TVS之后这个现象再也没有出现过。还有冷凝水问题。空调机组里冷通道的探头表面很容易结露如果三极管引脚之间有水膜形成微弱漏电读数会慢速漂移。我的做法是探头统一用环氧灌封或套管保护PCB方面在传感器区域加三防漆接口端子用防潮型号。成本增加不多但现场返修率下降非常明显。最后再说点实在话这套组合最让我满意的地方是它把“本地温度”和“远程温度”统一到了一个数字总线模型里本地通道管板上远程通道管远处报警和状态都有明确标志不需要在模拟世界里做各种补偿。温度数据真正变成了一组干净的数字后面接PID控制、楼宇协议上传、故障统计分析都顺手得多。如果项目里测温点少于三个、都在同一块板子上老老实实用NTC加ADC就够了不必上这套方案。但只要探头开始远离主板、要跨长线、还要在电噪声环境里稳定工作PJ85718DM加PIC24EP512GU814值得认真考虑。我建议你第一次做这套方案时先焊一块小验证板一个PJ85718DM、一颗MMBT3906、一块PIC24EP核心板用吹风机对着三极管吹热风看温度曲线和ALERT是否按预期工作。这一步跑通后面再扩点多路复用、USB上传、PID控温都只是按部就班的事了。