
1. 从一颗温度传感器说起为什么HVAC场景需要本地远程双路测温做嵌入式这行十几年温度监测的项目我经手过不少但每次碰到HVAC暖通空调相关的需求都会格外谨慎。原因很简单HVAC系统对温度的依赖不是锦上添花而是生死攸关。无论是商用楼宇的中央空调、数据中心的精密空调还是工业厂房的环境控制温度数据的准确性直接决定了压缩机启停、风阀开度、水泵转速这些执行机构的动作逻辑。一旦测温环节出了问题轻则能耗飙升重则设备损坏。这次要聊的方案核心是用一颗PJ85718DM温度传感器配合STM32L151ZD微控制器实现本地温度和远程温度的双路监测。PJ85718DM是一颗支持本地测温加远程二极管测温的传感器芯片通过I2C接口与MCU通信STM32L151ZD则是ST旗下超低功耗系列的Cortex-M3 MCU自带LCD驱动、多路I2C和USART非常适合HVAC这种需要长期在线、功耗敏感、还要带显示面板的场景。你可能会问为什么不用一颗数字温度芯片搞定为什么非要本地远程两路这个问题我在第一次接HVAC项目时也问过。后来实际调试才明白本地测温测的是控制板自己所在位置的温度而远程测温测的是真正需要被控温的那个点的温度。这两者之间可能隔着几米甚至十几米的距离中间还有发热器件、风道、金属壳体等干扰因素。如果只测本地温度控制板自己发热5度那整个系统的温控基准就偏了5度压缩机可能永远达不到设定点。所以这套方案的价值在于用一颗芯片同时拿到两个位置的温度数据MCU做差值补偿和逻辑判断既省了BOM成本又提高了系统可靠性。适合谁看做楼宇自控的嵌入式工程师、做工业环境监测的开发者、以及正在选型HVAC控制板的技术负责人。下面我会从芯片选型逻辑、硬件设计细节、I2C通信实操、温度数据处理、远程测温的坑、低功耗策略这几个维度把整个方案拆开讲透。2. PJ85718DM的测温机制与STM32L151ZD的匹配逻辑2.1 本地测温与远程测温的物理原理差异PJ85718DM这颗芯片的测温架构分两部分。本地测温用的是芯片内部的PN结利用半导体PN结正向压降随温度变化的特性通过内部ADC转换成数字量。这个通道的精度通常在±1°C左右响应速度快适合监测控制板周围的环境温度。远程测温则完全不同。它需要外接一个二极管接法的三极管通常是MMBT3904这类小信号管或者直接用带二极管模式的温度探头。芯片通过强制两个不同电流流过远程二极管测量两次压降差再根据公式算出温度。这个方法的妙处在于二极管可以放在离芯片很远的地方用双绞线连回来测的就是那个远端的真实温度。注意远程二极管的接线必须用双绞线且尽量远离高频开关节点。我见过一个案例远程测温线跟继电器驱动线捆在一起走结果温度读数每隔几秒跳变十几度排查了两天才发现是耦合干扰。2.2 为什么选STM32L151ZD而不是更便宜的F0系列STM32L151ZD属于L1系列Cortex-M3内核最高32MHz主频带128KB Flash和16KB RAM。有人会问温度监测这种任务用STM32F030这种几块钱的芯片不就够了为什么要上L1这里有几个关键考量。第一是功耗。HVAC控制板通常要求待机功耗极低L1系列在Stop模式下典型电流只有0.4μARTC走时加RAM保持也才1μA出头。F0系列在同等条件下要高出好几倍。第二是外设。L151ZD自带8x40段式LCD控制器可以直接驱动段码屏显示温度省掉一颗显示驱动芯片。第三是I2C数量。L151ZD有2路I2C一路接PJ85718DM一路可以接EEPROM或其它传感器不用做总线复用。第四点容易被忽略L151ZD的工作电压范围是1.65V到3.6V而PJ85718DM的I2C电平兼容1.8V到3.6V。这意味着整个系统可以跑在1.8V供电下进一步降低功耗。如果选5V或3.3V固定逻辑的MCU就得加电平转换又多两个器件。2.3 I2C地址配置与总线速率取舍PJ85718DM的I2C地址由ADDR引脚决定接地时地址是0x48接VDD时是0x49接SDA时是0x4A接SCL时是0x4B。这个设计很灵活同一条总线上可以挂四颗芯片分别测四个区域的温度。在HVAC主板里我通常把主控板那颗设为0x48风道回风口的设为0x49这样MCU轮询时不会搞混。总线速率方面PJ85718DM支持标准模式100kHz和快速模式400kHz。我实测下来400kHz下读取一次本地远程温度两个16位寄存器大约需要0.3ms100kHz下约1.2ms。如果系统对实时性要求不高比如每秒采样一次100kHz完全够用而且抗干扰能力更强。但如果总线上还挂了其它高速器件或者需要频繁读取那就上400kHz。这里有个经验STM32L151ZD的I2C外设在400kHz时如果上拉电阻用4.7k上升沿可能偏慢尤其在总线电容较大的情况下。我一般用2.2k上拉配合100nF的电源去耦波形很干净。但要注意功耗2.2k上拉在总线拉低时会有约1.5mA电流如果系统是电池供电得权衡。3. 硬件设计从原理图到PCB布局的实操细节3.1 远程二极管的选择与偏置电阻计算远程测温通道的核心是那颗外接三极管。不是随便拿个8050就能用必须选低噪声、高hFE的小信号管。我常用MMBT3904它的基极-发射极压降特性比较一致批次间差异小。接线方式是集电极和基极短接接到PJ85718DM的D引脚发射极接到D-引脚。这样它就是一个二极管接法只有两个端子。偏置电阻方面PJ85718DM内部有电流源不需要外部偏置。但D和D-之间建议并一颗100pF到1nF的电容滤掉高频噪声。这个电容不能太大否则会影响电流切换时的建立时间导致测温误差。我试过用10nF结果读数偏低3度换成470pF就正常了。提示远程二极管如果走线超过30cm建议在D和D-上各串一颗10Ω电阻再并电容。串阻可以抑制振铃但阻值不能大否则电流源驱动能力不够。3.2 电源去耦与参考电压的稳定性PJ85718DM的供电范围是1.8V到3.6V典型3.3V。它的测温精度直接受电源纹波影响。我在测试时发现如果电源纹波超过20mVpp本地温度读数会有±0.5度的波动。所以去耦电容必须到位VDD引脚旁边放一颗100nF的X7R陶瓷电容再并一颗1μF的钽电容或MLCC。STM32L151ZD这边VDDA和VDD要分开滤波。VDDA用磁珠或10Ω电阻隔离再并1μF加100nF。如果系统里有继电器或电机驱动数字地和模拟地要单点连接否则开关噪声会串进ADC参考影响温度计算的稳定性。3.3 PCB布局中远程测温走线的处理远程测温走线是整套方案里最容易出问题的地方。我的原则是D和D-必须平行走线间距不超过2mm最好用地线包起来。如果走线要经过连接器连接器上要有专门的GND引脚夹在D和D-中间。这样做的目的是让两条线受到的共模干扰一致芯片内部做差值时可以抵消掉。另外远程二极管如果放在金属壳体内要注意壳体是否接地。如果壳体接大地而控制板地是浮地两者之间可能有几十伏的共模电压会击穿芯片输入。这种情况下要么把壳体接到控制板地要么在D和D-上各加一颗TVS管做保护。4. 固件实现I2C驱动、温度换算与滤波算法4.1 STM32L151ZD的I2C初始化与读写时序STM32L151ZD的I2C外设配置不算复杂但有几个坑。首先时钟控制寄存器CCR的计算要准确。以400kHz为例如果APB1时钟是32MHzCCR 32MHz / (2 * 400kHz) 40。但实际配置时还要考虑上升时间标准模式上升时间最大1000ns快速模式300ns。如果上拉电阻偏大实际速率会低于设定值。初始化代码大概长这样I2C_InitTypeDef I2C_InitStruct; I2C_InitStruct.I2C_ClockSpeed 400000; I2C_InitStruct.I2C_Mode I2C_Mode_I2C; I2C_InitStruct.I2C_DutyCycle I2C_DutyCycle_2; I2C_InitStruct.I2C_OwnAddress1 0x00; I2C_InitStruct.I2C_Ack I2C_Ack_Enable; I2C_InitStruct.I2C_AcknowledgedAddress I2C_AcknowledgedAddress_7bit; I2C_Init(I2C1, I2C_InitStruct); I2C_Cmd(I2C1, ENABLE);读温度寄存器的流程是先发起始条件写设备地址写位然后写寄存器指针本地温度是0x00远程温度是0x01再发重复起始条件写设备地址读位然后读两个字节。PJ85718DM的温度寄存器是16位高字节在前低字节在后。高字节的低4位是符号位和整数部分低字节的高4位是小数部分分辨率0.0625°C。4.2 原始数据到摄氏度的换算与校准换算公式不复杂但要注意符号扩展。原始16位数据右移4位得到整数部分低4位乘以0.0625得到小数部分。如果是负数要用补码方式处理。我一般直接用一个int16_t变量接收原始数据然后int16_t raw (high 8) | low; float temp raw * 0.0625f;这样正负都对了。但PJ85718DM的远程通道有个偏移误差典型值±1°C最大±3°C。如果对精度要求高需要做单点校准。方法是在已知温度下比如冰水混合物0°C读取远程通道原始值算出偏移量写进芯片的偏移寄存器地址0x11。这个寄存器是8位有符号数每LSB代表0.0625°C范围-8°C到7.9375°C。我通常会在产线测试时做一次校准把偏移值存到STM32的Flash里每次上电初始化时写回PJ85718DM。这样即使换传感器也不用改固件。4.3 滑动平均与中值滤波的配合使用原始温度数据肯定有噪声尤其远程通道。我试过直接读波动在±0.5度左右。为了得到稳定的显示值和控制依据必须滤波。我的做法是先做中值滤波窗口大小5去掉最大最小再取中间然后做滑动平均窗口大小8。这样既滤掉了脉冲干扰又平滑了随机噪声。但滤波会带来滞后。如果温度变化很快比如HVAC系统刚启动时滤波后的值可能比实际值慢好几秒。所以我在固件里做了动态调整当连续三次采样差值超过1度时自动缩短平均窗口到3加快响应稳定后恢复窗口8。这个逻辑用状态机实现代码不复杂但效果很好。5. 远程测温的典型故障与排查链路5.1 读数恒为-127°C或127°C的根因定位远程通道最常见的故障就是读数卡在极值。PJ85718DM在检测不到远程二极管时会返回-127°C如果D和D-短路会返回127°C。我遇到过一次产线反馈说远程温度一直是-127。排查过程是这样的第一步用万用表测D和D-之间的压降。正常应该有0.6V左右。结果是0V说明二极管没接上或者坏了。第二步检查连接器发现远程二极管的引脚定义搞反了D和D-接反。调换后正常。所以记住D接二极管正极集电极基极D-接负极发射极。还有一种情况是二极管选了肖特基管压降只有0.3V芯片检测不到。必须用普通硅二极管接法的三极管。5.2 温度跳变与电源噪声的关联分析另一个坑是温度读数周期性跳变。有一次客户反馈说远程温度每隔10秒跳一次幅度有5度。我带着示波器去现场发现跳变时刻正好是继电器动作的时刻。原因很清楚继电器线圈断电时产生反电动势通过共地路径耦合到了远程测温线上。解决方案分三层第一继电器线圈两端加续流二极管这是最基本的第二远程测温线改用屏蔽双绞线屏蔽层单端接地第三在PJ85718DM的D和D-上各加一颗BAT54S做钳位。三层做完跳变消失。注意如果远程测温线必须经过强电区域建议用光耦或数字隔离器做隔离虽然成本高但可靠性是值得的。5.3 长走线导致的电容负载问题远程二极管走线超过1米时线间电容可能达到几百pF。PJ85718DM的电流源切换频率大约在几十kHz如果电容太大电压建立时间不够测温就会偏低。我实测过用普通排线走2米读数偏低约2度。换成低电容双绞线后偏差缩小到0.5度以内。如果走线实在无法缩短可以在固件里做补偿根据线长估算一个偏移量加到远程温度上。但这个方法不精确因为线电容受温度、湿度影响。更好的办法是降低电流源切换频率但PJ85718DM不支持配置。所以我的建议是远程走线尽量控制在1米以内超过1米就要用高质量双绞线并做实际校准。6. 低功耗设计与HVAC长期运行的可靠性考量6.1 STM32L151ZD的Stop模式与定时唤醒策略HVAC控制板通常不是电池供电但低功耗设计依然重要因为可以降低整机温升提高测温精度。STM32L151ZD的Stop模式电流只有0.4μARTC可以继续走时。我的策略是系统默认每5秒唤醒一次读取PJ85718DM的温度更新LCD显示然后判断是否需要控制输出。如果温度在设定范围内直接回Stop模式如果超限才进入运行模式做PID计算。唤醒源用RTC的周期唤醒配置成5秒中断。中断里置一个标志位主循环检测到标志位后执行测温流程。这样平均功耗可以做到10μA以下控制板自身发热几乎可以忽略本地温度更接近真实环境温度。6.2 PJ85718DM的单次转换模式与功耗优化PJ85718DM默认是连续转换模式每秒转换多次功耗约200μA。如果不需要这么高的刷新率可以配置成单次转换模式Shutdown模式。写配置寄存器地址0x01的bit0为1芯片进入关断电流降到0.1μA。需要测温时写bit0为0启动一次转换等转换完成后再关断。转换时间取决于分辨率。9位分辨率约30ms12位约240ms。我一般用11位约120ms精度0.125°C对HVAC足够。这样平均功耗可以降到几微安级别。6.3 看门狗与I2C总线恢复机制长期运行的系统I2C总线可能因为干扰而锁死。STM32L151ZD的I2C外设有总线错误检测但有时候需要手动恢复。我的做法是在I2C读写函数里加超时计数如果连续三次超时就执行总线恢复流程——把SCL配置成GPIO手动发送9个时钟脉冲然后发停止条件再重新初始化I2C。另外独立看门狗IWDG必须开超时时间设2秒。主循环里每500ms喂一次狗。如果程序跑飞看门狗复位后重新初始化所有外设系统能自动恢复。这个机制在无人值守的HVAC机房裡特别重要。7. 本地与远程温度的协同应用从数据到控制决策7.1 差值补偿在变风量系统中的应用拿到本地和远程两个温度后怎么用最直接的是做差值补偿。比如本地温度30度远程温度25度差值5度。如果控制目标是远程点维持24度那本地温度其实不用管直接以远程为准做PID。但本地温度可以用来判断控制板是否过热如果本地超过70度说明板子散热有问题需要报警。在变风量VAV系统里远程温度通常放在回风口本地温度在控制箱内。回风温度反映房间负荷控制箱温度反映设备状态。两者结合可以判断是房间真的热还是控制箱被晒热了导致误动作。7.2 温度变化率作为故障预警指标除了绝对值温度的变化率也很有用。我在固件里计算每分钟的温度变化斜率。如果远程温度在1分钟内上升超过5度可能是传感器脱落或者风阀卡死如果本地温度快速上升而远程不变可能是控制板附近有热源。这些异常都可以触发预警通过USART上报给上位机。这个功能我是在一个数据中心项目里加的后来帮客户提前发现了一次空调皮带断裂——回风温度在3分钟内升了8度系统自动切到备用机组避免了服务器过热宕机。7.3 双通道数据的LCD显示与上位机通信STM32L151ZD自带LCD控制器可以直接驱动段码屏。我通常把本地温度显示在左上角远程温度在右上角中间显示设定值和运行状态。段码屏的优点是功耗低、阳光下可读适合机房环境。上位机通信走USART协议用Modbus RTU寄存器地址映射0x0000本地温度0x0001远程温度0x0002状态字。波特率96008N1。Modbus的好处是通用任何组态软件都能接。如果客户要求无线可以加一颗LoRa模块但那是另一个话题了。8. 我在实际项目中积累的几条硬经验第一PJ85718DM的远程测温通道如果不用一定要把D和D-短接并接地否则悬空引脚会引入噪声影响本地测温。这个坑我在早期项目里踩过本地温度无故跳动查了半天才发现是远程引脚悬空。第二STM32L151ZD的I2C引脚是开漏输出必须外接上拉。内部上拉虽然可以开但阻值太大约40k400kHz下波形根本起不来。老老实实焊2.2k到4.7k的外部电阻。第三温度校准不要只做单点。如果系统工作范围是0到50度至少在10度和40度两个点做校准取线性拟合。单点校准在两端会有偏差HVAC系统对低温制热和高温制冷都有要求两端精度都得顾。第四PCB上的PJ85718DM尽量远离DC-DC电源和继电器。我一般把它放在板子边缘下方铺铜接地但不要铺到D和D-走线下面否则寄生电容会影响远程测温。第五固件里一定要加温度合理性检查。如果读数超出-40到125度范围直接丢弃用上一次的有效值。这个简单的判断能避免很多因干扰导致的误报警。这套方案我在三个不同项目里用过最长的一个已经连续运行了四年多温度读数依然稳定在±0.5度以内。HVAC这个领域可靠性比什么都重要选对芯片、做好滤波、留足余量剩下的就是让时间验证了。