做嵌入式温度监测做久了,你会发现最磨人的往往不是芯片选型,而是“温度到底准不准、稳不稳”。尤其HVAC这类系统,本地测的是控制面板周边的环境温度,远程测的可能是几米外的水管、风管里的温度,一个读数漂移几摄氏度,整个控制逻辑就会跟着抽风。我最近用一颗PJ85718DM配合一片STM32F469II把一整套本地/远程温度监测方案跑通了,从传感器原理、PCB走线、I2C读取、数据滤波一直做到现场排障,踩了不少坑,也攒了不少可以直接抄作业的细节。这篇就来重点拆解这套方案,做暖通控制器和嵌入式监控的同行,应该能直接拿走用。
1. 项目拆解与硬件选型思路
1.1 先把“本地/远程温度”这层窗户纸捅破
项目标题里的“本地温度”和“远程温度”是同一颗芯片上的两个独立测温通道,含义完全不同。
本地温度指的是PJ85718DM芯片自己所在位置的温度。芯片内部集成了一路温度传感元件,通常是带隙基准(bandgap)这类硅基结构,直接把PCB板面附近的环境温度转换成数字量。对HVAC设备来说,这个位置往往代表控制器安装环境、回风区域的温度。对嵌入式设备来说,它反映的是模块或单板的壳温、进风温度。
远程温度则是通过外部的一颗二极管(实际上我们常用一颗普通小信号三极管,把基极和集电极短接)来感知远处温度。芯片通过两条走线接到这个二极管上,利用二极管PN结的压降随温度变化的特性,换算出远端测点温度。这个测点可以放在距离主控板几十厘米到几米的回风管、冷水管、电池簇、功率器件外壳上。
为什么需要“本地+远程”组合?因为HVAC控制逻辑往往需要两个温度做对比。风机盘管温控器需要面板周边的环境温度来做舒适度控制,同时需要回风口或盘管内的温度来判断实际换热效果。机房监控设备需要单板的进风温度,又需要机柜出风口的温度来判断散热是否有效。如果老老实实用两颗独立温度芯片,就要多走一路I2C、多占一块PCB面积,成本和故障概率都上去了。PJ85718DM这种一颗芯片输出两路温度的设计,天然就是为这类场景准备的。
1.2 为什么用PJ85718DM而不是两颗温度传感器
选传感器方案时,我对比过三种常见路线:热敏电阻分压ADC、两颗单点数字传感器、本地加远程测温芯片。实际权衡下来,第三种在HVAC场景里最省心。
热敏电阻加MCU内置ADC的方案成本最低,但需要软件做非线性查表,而且ADC参考电压、分压电阻的温漂都会影响精度。在空调机组这种强干扰环境里,模拟量传输线容易被变频器和接触器干扰,调理电路稍微设计不好,读数就会飘。两颗I2C数字传感器则简单可靠,但成本翻倍,还要考虑地址冲突,布线上也多一组电源和信号。
本地加远程测温芯片的优势在于:模拟前端、ADC、非线性校正、温度报警比较器全都集成在芯片内部,软件只需要通过I2C读寄存器。远程通道的BOM成本就是一颗几毛钱的三极管,总物料成本反而比两颗数字传感器更低。芯片自带的上限、下限温度比较器还能在温度越限时直接拉低ALERT引脚,不依赖主控一直轮询。
选这类芯片时我建议重点看几个硬指标:I2C地址引脚的数量,决定一条总线上能挂几颗;本地和远程测温范围是否能覆盖应用场景;一次温度转换时间,HVAC控制周期一般是一秒到几秒,转换时间几百毫秒级别完全够用;远程走线的串联电阻抵消能力;ALERT引脚支持比较模式还是事件模式;封装是不是方便量产贴片。PJ85718DM在这些方面都符合主流数字温度传感器的水准,属于很典型的本地加远程双通道测温器件。
1.3 STM32F469II在这套方案里的角色
STM32F469II是一颗Cortex-M4F内核的主控,主频180MHz,片上带2MB Flash和384KB SRAM。F469系列最有特点的是内置了LTDC液晶控制器和Chrom-ART图形加速器(DMA2D),可以直驱中尺寸TFT彩色屏。放在这个温度监测项目里,意味着MCU不仅能采集和运算温度数据,还能把数据实时画成曲线、仪表盘、报警界面,完全不用外挂图形控制芯片。
很多人觉得F469用来测温是大材小用。如果只是把温度上报给上位机,确实用不到这么多资源。但HVAC控制器通常是一台带屏幕、带按键、可能要接楼宇自控总线的设备。F469的4个I2C接口可以挂传感器、EEPROM、RTC;多个UART可以走Modbus或调试;以太网MAC加外置PHY可以直接对接网络监控。温度数据进来之后,LTDC负责屏显,DMA2D负责加速画曲线,大容量Flash还能圈出一块区域存历史温度记录。
所以这套组合的逻辑很清晰:传感器芯片负责把物理温度变成数字量,STM32F469II负责把数字量变成用户能看懂、控制逻辑能使用的信息。两者分工明确,硬件上只需要一根I2C总线。
1.4 远程测温原理:一颗小三极管凭什么能测温
远程通道的核心原理是PN结压降的温度特性。二极管正向导通时,两端压降Vf大约是0.6V到0.7V,温度每升高1°C,Vf大约下降2mV。这个关系曲线比较稳定,但直接测量Vf是测不准的,因为Vf还受二极管制造工艺、通过电流大小影响。
精确测温芯片用的方法是“不同电流密度下的电压差”,也就是ΔVbe法。芯片给同一个二极管先后注入两个已知电流I1和I2,设I2是I1的N倍,分别测得压降V1和V2。物理上满足ΔVbe = (k×T/q)×ln(N),其中k是玻尔兹曼常数,q是电子电荷常数,N是电流比值。这两个测量是在同一个二极管上完成的,二极管本身的工艺偏差被抵消掉了,剩下的电压差只和绝对温度T成正比。反解出T,就是我们需要的那两路远程温度之一。
这个原理用生活经验来类比也很直白:称东西的时候先称“皮”,再称“皮加物”,用差值消除容器本身的重量的影响,ΔVbe法就是给二极管加两个不同的“砝码”,用压降差反推温度,单点Vf的绝对误差自然被消除。这也是远程测温不挑剔传感器元件的原因,任何一颗普通小功率三极管,把基极和集电极短接当二极管用,都能得到不错的测量效果。芯片内部还会对远程走线的串联电阻做抵消,线阻带来的附加压降会被软件修正掉。真正决定远程温度精度的,反而成了二极管到芯片之间的那段走线质量。
2. 硬件设计与PCB布局要点
2.1 最小硬件连接:一张表看清所有信号
这套方案的最小硬件连接并不复杂,核心是PJ85718DM与STM32F469II之间的I2C总线,以及芯片到远端二极管之间的两条测温线。
| 信号 | PJ85718DM | 连接去向 | 注意事项 |
|---|---|---|---|
| VCC | 供电引脚 | 3.3V电源 | 就近放0.1μF和10μF去耦电容 |
| GND | 地 | 系统地 | 建议单点接入主地 |
| SCL | 串行时钟 | F469的I2C1_SCL | 接4.7kΩ上拉到3.3V |
| SDA | 串行数据 | F469的I2C1_SDA | 接4.7kΩ上拉到3.3V |
| ALERT | 温度报警输出 | F469外部中断引脚 | 开漏输出,需10kΩ上拉 |
| D+ | 远程二极管阳极 | 小三极管基极-集电极短接点 | 双绞线连接 |
| D- | 远程二极管阴极 | 小三极管发射极 | 双绞线连接 |
I2C上拉电阻的取值并不是固定的。400kHz快速模式下常用4.7kΩ,如果总线上挂的设备多或者走线较长,可以换2.2kΩ来保证信号边沿足够陡。但上拉太小会增大灌电流,具体要查芯片手册的IOL参数。
ALERT引脚是开漏输出,初始化配置成输入模式并检测下降沿。芯片内部比较器检测到温度越过上限或下限时,会把ALERT拉低,F469的外部中断被触发后,软件可以在中断里读取状态寄存器判断具体是哪一路越限。这样做的好处是主控不用每毫秒盯着温度,系统功耗也更低。
2.2 远程二极管接口要按差分信号来设计
远程测温的两条走线是整个方案里最容易出问题的地方。D+和D-之间传输的是微伏级别的测量电压差,走线稍微受点干扰,读数就会跳动。
常规设计约束有四条。第一,D+和D-尽量双绞或者近距离平行走线,面积越小越好。第二,在远程二极管那一端并联一个滤波电容,典型值是100pF到2200pF,具体值看芯片手册允许范围。电容太小滤不掉干扰,太大又会影响测量信号的建立时间。第三,走线长度控制在1米以内最稳妥,超过3米就建议加屏蔽线或考虑其他方案,因为线缆电阻、分布电容都会开始明显影响测量结果。第四,同层PCB上不要让D+/D-与继电器触点、变频器输出、开关电源的电感节点并行走线,这些高dv/dt信号会通过寄生电容耦合噪声。
我实际调过一套设备,远程温度在电机启动瞬间能跳变3°C以上,用示波器探D+/D-能看到明显的尖峰脉冲。把平行走线改成双绞线,在远程二极管端并一个1000pF电容后,尖峰基本消失。这个电容的位置很关键,加在远程二极管那一端比加在传感器芯片那一端有效得多,因为电容在这里可以直接就地吸收从线缆耦合进来的高频噪声。
2.3 本地传感器位置与PCB热管理
本地温度测的是芯片周围的环境温度,但芯片周围恰好是PCB上其他发热元件的地盘。电源芯片、主控MCU、继电器驱动电路、大功率MOS管都会把热量传导给传感器,造成本地温度读数偏高。
布局时要把PJ85718DM当作一个精密的模拟器件来对待。传感器不要贴在DC-DC电感的正下方,不要放在主控芯片的散热风道里,至少留出1到2厘米的间距。如果PCB空间紧张,可以采用开热隔离槽的办法,在传感器附近的地铜皮上开一条窄槽,切断热传导路径。传感器下方的铜皮不要和发热器件的铜皮大面积相连,不然热量会顺着铜皮直接导过来。
HVAC设备的继电器吸合时线圈发热,如果传感器离继电器太近,每次继电器动作本地温度都会跳高一点。我见过一块板子,本地温度比水银温度计实测高3°C,用红外热像仪一看,传感器正好夹在主控和DC-DC中间,改板布局之后偏差就下来了。如果改板成本太高,也可以靠软件偏移补偿,但出厂前必须每台实测校准。
2.4 HVAC整机环境的电气防护
HVAC箱体内的电气环境比普通消费电子恶劣得多。24V交流供电的控制器、带感性负载的接触器、变频器、水泵电机,这些都会在电源和地上叠加噪声。温度传感器如果直接暴露在这种环境里,要做足防护。
传感器供电建议从3.3V或5V的线性稳压器取,不要直接接在DC-DC输出纹波大的那一路。I2C总线上建议加双向ESD保护器件,防止外接端子被误触。ALERT引脚如果引出到端子,同样加保护。远程二极管跨板连接时,端子选镀金的,避免长期运行后氧化导致接触电阻变化。冷凝水较多的场合,传感器和连接器要涂三防漆。
如果传感器和主控板隔得很远,比如远程测温模块在机组内部,主控在配电柜里,最好用数字隔离器把I2C隔开。隔离后的传感器小板自己带电源,主控和传感器之间没有电气上的共地关系,地环流噪声就不会窜进温度读数。这个方案比单纯加滤波更彻底,代价是多两颗隔离芯片和一路隔离电源。
3. 软件框架:从CubeMX到温度数据流
3.1 CubeMX初始化与I2C配置
软件层面我用STM32CubeMX做初始化配置,工程结构清晰,后面维护也方便。选芯片时直接选STM32F469II,配一个25MHz外部晶振,PLL倍频到180MHz主频,这是F469的最高运行频率,足够快。
I2C1配置成I2C标准模式或快速模式都可以,PJ85718DM这类芯片一般支持到400kHz,直接选Fast Mode。I2C的传输速度对这套系统影响不大,因为温度转换时间通常是几十到几百毫秒,读数频率不会高到哪里去。还要把ALERT对应的GPIO配置成外部中断输入,串口配置一个调试输出口。
生成工程之后,写一个封装好的寄存器读取函数,后续所有代码都基于这个函数展开:
HAL_StatusTypeDef sensor_read_reg(uint8_t reg, uint8_t *buf, uint8_t len) { return HAL_I2C_Mem_Read(&hi2c1, SENSOR_ADDR, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 100); }需要注意HAL库对从机地址的处理,有的版本直接传7位地址,有的需要左移一位传8位地址,建议根据手头使用的HAL版本实际测试一下。最简单的验证方法就是先读一次芯片ID寄存器,看返回值是否在预期范围。
3.2 读温度:寄存器格式与数据拼接
读温度的核心是把寄存器里的原始值拼接成真实温度值。不同温度传感器芯片的寄存器布局大同小异,都是高低字节组合、符号扩展、乘分辨率三步。
以典型布局为例,本地温度寄存器占两个字节,高字节是整数部分和符号位,低字节的高4位是小数部分。12位有效数据加上符号位,分辨率是0.0625°C/LSB。读取两个字节后,拼成一个16位整数,右移4位取出12位有效数据,再乘以0.0625,就是实际温度:
uint8_t regs[2]; sensor_read_reg(LOCAL_TEMP_REG, regs, 2); int16_t local_raw = (int16_t)((regs[0] << 8) | regs[1]); local_raw >>= 4; float local_temp = local_raw * 0.0625f;远程温度通道的寄存器格式类似,但有些芯片的分辨率规格不同,比如11位有效数据、0.125°C/LSB,这时候右移位数就要相应调整。千万不要照抄网上代码的位移量而不看手册,寄存器位宽和偏移定义稍有差别,读出来的温度就差出好几度。
3.3 状态寄存器与错误处理
读温度之前必须先看状态寄存器。PJ85718DM这类芯片会把远程通道的开路、短路、温度越限等故障信息记录在状态位里。远程二极管断线时,芯片可能读出一个极端值,比如-128°C;D+和D-短路时,可能读出一个正的满量程值。如果主控不检查状态寄存器就直接用这个数据参与控制,轻则显示乱码,重则触发错误的告警和联动。
我习惯的软件流程是:先读状态寄存器,有错误位就先上报故障,不更新温度缓存;没有错误位才读温度寄存器。故障位还要做延时确认,连续读到3次错误才真正报故障,避免远程二极管接线端子瞬间接触不良导致的误报。错误状态恢复之后,也要连续几次正常读数才清掉故障标志,防止控制逻辑来回抖动。
3.4 滤波与校准实战
HVAC现场的温度信号通常会叠加高频干扰,但被控对象的真实温度变化又很缓慢。这种情况下最简单有效的手段是一阶低通滤波,也就是常说的惯性滤波。
static float filtered_temp = 25.0f; filtered_temp += alpha * (raw_temp - filtered_temp);alpha取值直接决定响应快慢。读取周期1秒时,alpha取0.2到0.3比较合适,既能滤掉大部分噪声,也不会让温度变化看起来太迟钝。如果读取周期是100毫秒,alpha就要降到0.05到0.1,不然滤波后的温度变化会很缓慢,控制响应跟不上。
校准则要看应用需求。如果传感器的绝对精度已经满足要求,就不需要额外校准。如果PCB布局导致本地温度有固定偏差,比如传感器离发热元件近导致高温了2°C,可以在固件里做一个单点偏移。更严格一点的两点线性校准则需要恒温槽,分别在低温和高温点记录修正系数,最终形式是temp_final = a × temp_raw + b,a和b存到F469内部Flash,量产测试时用串口命令写入。
3.5 LCD显示与报警联动设计
温度读取稳定之后,剩下的工作是把它变成界面和控制信号。F469的LTDC可以直接驱动TFT屏幕,用DMA2D加速画曲线,温度趋势图可以做到每秒刷新不卡顿。界面上同时显示本地温度、远程温度、当前上下限阈值和报警状态。
报警联动我习惯用硬件中断加软件确认组合。ALERT引脚拉低时F469的外部中断被触发,中断里只置一个标志,具体判断逻辑放在主循环里做。这样可以避免在中断里做耗时的I2C读操作。联动逻辑则要根据HVAC工艺来写,比如远程温度超过供水上限时关闭电动阀门,本地温度超过回风上限时切换风机风速档位:
if (remote_alarm) { valve_ctrl = RELAY_CLOSE; alarm_led = ON; } if (local_temp > local_hi_threshold) { fan_speed = FAN_LOW; }报警阈值最好留滞环,比如上限是30°C,那么等到降到28°C再解除报警。这样能防止温度在阈值附近波动时报警状态反复跳变,现场人员也不容易被误报折腾。
4. 实操:一次完整的联调过程记录
4.1 物料清单与上电前检查
动手之前先把工具和物料备齐。一套F469开发板或自制的核心板,PJ85718DM的模块或者空芯片自己焊接,两颗小信号三极管做远程二极管,4.7kΩ电阻,0.1μF和10μF电容,USB转串口工具,逻辑分析仪或者示波器。
上电前的检查绝不能省。先量一遍电源,确认电压范围在芯片允许值内,极性没接反。再看SCL和SDA有没有接反,这两根线接反之后通信一定失败,现象是I2C扫描不到任何设备。远程二极管的极性要特别留意:基极和集电极短接之后接入D+,发射极接入D-。接反之后芯片的状态寄存器会显示远程通道异常,或者读回一个离谱的温度值。ALERT引脚的开漏结构别忘了上拉,不然中断信号根本拉不出来。
4.2 从I2C扫描到实时读数
第一步烧录CubeMX生成的最基础工程。先用一段扫描代码遍历I2C总线上所有地址,确认PJ85718DM的应答地址和你预期一致。地址引脚A0、A1的接法决定芯片的7位地址,常见地址会在0x48到0x4F这个范围附近,具体看手册里的地址表。
确认设备在线之后,读取芯片ID寄存器验证通信链路完全正确。ID值对不上说明地址配错、I2C时序有问题或者芯片供电不稳。接着按顺序读取本地温度、远程温度和状态寄存器,通过串口打印出来。
串口的典型输出应该是这样的:
Local Temp: 25.375 C Remote Temp: 26.000 C Status: 0x00 Local Temp: 25.437 C Remote Temp: 26.125 C Status: 0x00 Local Temp: 25.375 C Remote Temp: 33.750 C Status: 0x00第三次打印的Remote Temp突然升高,是因为我用手捏住了远程三极管。人体热量隔着封装传进去,温度读数快速上升,说明远程测温通道的整个链路都通了。如果捏住三极管温度没反应,优先检查极性、接线和滤波电容是否过大。
4.3 HVAC现场排障实录
写两个我实际碰到的案例,都很有代表性。
第一个案例是远程温度周期性漂移。现场是一套空调机组控制系统,温度传感器在主控板上,远程三极管装在风管测温点。系统运行之后发现远程温度每10分钟左右出现一次尖峰,最高能跳到比正常值高5°C。用示波器挂在D+和D-上看,尖峰出现的时间和风柜接触器吸合、释放的时间完全同步。检查走线发现,远程测温线和220V交流接触器的控制线束绑在同一个线槽里,接触器动作时产生的磁场耦合进了两条测温线。解决办法是把两束线分开走,原来的平行线换成双绞线,并在远程三极管端并联了一个1000pF电容。处理后连续跑了一周,温度再没出现过尖峰。
第二个案例是本地温度偏高。控制面板上的液晶显示25.8°C,用标准水银温度计实测则是24.8°C,整整差了1°C。用红外热像仪扫PCB,传感器周围的主控芯片表面温度接近50°C,DC-DC电感的温度更高。传感器虽然没和发热元件直接贴在一起,但热量通过PCB铜皮一路传导过来,把本地温度抬高了。改板时把传感器挪到靠近面板边缘的通风位置,并加了一条热隔离槽,偏差降到0.2°C以内。
这两个案例说明一个道理:温度读得准,硬件布局和走线比芯片本身的精度指标影响还要大。
5. 常见问题与排查技巧实录
5.1 问题速查表
把这些年在温度采集项目里遇到的问题整理成一张表,排查时可以对照着看:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| I2C扫描无设备 | 地址错误、芯片未供电、上拉电阻缺失、SCL/SDA接反 | 先量供电,再用扫描程序遍历地址,核对原理图 |
| I2C总线卡死 | 芯片锁死、电源瞬间跌落、总线上其他设备异常 | 复位芯片电源或整机、加总线超时恢复机制 |
| 远程温度读到-128°C左右 | D+开路、虚焊、端子氧化、二极管断线 | 看状态寄存器开路位,补焊、换端子 |
| 远程温度读到满量程正数 | D+与D-短路、线缆绝缘破损、滤波电容过大 | 查短路点,检查电容取值 |
| 远程温度无规律跳动 | 走线受电磁干扰、地线噪声、线过长 | 双绞线、屏蔽、远端加滤波电容、缩短距离 |
| 本地温度偏高 | 传感器靠近发热元件、PCB导热 | 改布局、热隔离、软件偏移补偿 |
| 温度响应特别慢 | 滤波系数过小、转换周期过长 | 调大alpha、检查配置寄存器 |
5.2 经典踩坑案例
第一个坑是I2C总线挂死。某次联调时程序跑到读温度就直接卡住,用示波器看SCL引脚一直维持低电平。排查发现是传感器供电那一路电源被继电器瞬时大电流拉低,芯片进入异常状态。这种情况靠软件发停止条件往往没用,SCL一直被芯片拉死,只能给传感器单独复位电源。后来把传感器电源和继电器驱动电源分开,传感器供电用独立的LDO,并在软件里实现了一旦检测到总线忙就尝试发送九次SCL脉冲来释放总线,卡死问题基本消失。
第二个坑是远程线拉长之后读数系统性偏高。一开始测温线只有0.5米,精度正常。现场安装时为了走线方便延长到5米,远程温度整体偏高4到5°C。原因就是线缆电阻混进了测量回路,拉高了二极管两端的压降差。解决办法是开启芯片的串联电阻抵消功能,如果芯片支持自动抵消,软件只需要把一个使能位配置好。不能抵消的话只能换更粗的线或者缩短走线,模拟量传输的远程通道对线长是敏感的。
第三个坑是报警误报。设备白天下线运行正常,晚上安静环境下频繁报警。检查发现阈值设置得太贴近工作温度,控制环路正常波动就会触发越限。后来在软件里加了延时确认机制,连续3个扫描周期都越限才真正报警,同时把比较器阈值改成拥有2°C滞环的上下限配置,误报彻底消失。
5.3 提升整机可靠性的三条经验总结
第一条经验,把D+和D-当作模拟差分信号来设计。不要因为它们最终接进了数字芯片就轻视布线,这一段是整套系统里最脆弱的模拟链路。
第二条经验,软件永远不要相信一次读数。状态寄存器检查、滤波处理、连续确认三件套几乎是标配。单次读数的偶发异常太常见了,不处理就会变成现场扑朔迷离的故障。
第三条经验,出厂校准入口必须留好。哪怕只是固件里留一个串口命令,允许生产测试时写入温度偏移值,也能帮你处理批量元件的离散偏差。不要等设备批量发到现场才发现问题,那时候改一件都费劲。
最后说点个人体会。做这类温度监测方案,七分功夫在硬件,三分功夫在软件。芯片本身的精度是器件手册保证的,但现场读出来的温度能不能让用户信服,取决于PCB布局、走线处理、滤波校准这些基本功。PJ85718DM配STM32F469II这套组合让我比较省心的地方在于,采集、显示、存储、联动全都集成紧密,不需要在多个芯片之间做复杂的协同。如果你也准备做类似的东西,建议先把芯片和传感器用现成的开发板点起来,把数据流完整走一遍再画PCB,这个顺序能帮你避开大部分返工。