1. 项目背景与核心需求拆解
1.1 为什么要在嵌入式与暖通场景下做温度监测
暖通空调系统里,温度是最基础也最关键的物理量。无论是商用楼宇的中央空调、数据中心的精密空调,还是工业厂房里的恒温恒湿机组,温度数据的采集精度和响应速度直接决定了整套系统的能效比和运行稳定性。我接触过不少做暖通控制器的团队,他们早期用热敏电阻加分立运放搭采样电路,精度勉强做到±1℃,但批量生产时一致性很差,标定环节能把产线工人逼疯。后来大家逐渐转向集成式温度传感器方案,用数字接口直接读取温度值,省去模拟链路里那些温漂、噪声、参考电压漂移的麻烦。
这个项目标题里提到的PJ85718DM,就是一颗典型的本地与远程温度监测芯片。它同时支持本地温度传感和远程二极管温度传感,通过I2C或SMBus接口与主控通信。而STM32F745VG是一颗Cortex-M7内核的高性能MCU,主频能跑到216MHz,带FPU和DSP指令集,用来跑温度采集、滤波、逻辑判断和通信协议栈绰绰有余。把这两者组合在一起,目标很明确:构建一个能同时监测板载温度和外部远程温度节点的嵌入式系统,并且具备远程数据传输能力,适配暖通空调场景下的分布式测温需求。
1.2 本地温度与远程温度到底差在哪
很多人刚接触这类芯片时会混淆“本地”和“远程”两个概念。本地温度指的是芯片自身所处的环境温度,由芯片内部的PN结或带隙基准源测得,反映的是PCB板附近的温度状况。远程温度则不同,它需要外接一个二极管接法的三极管(通常是MMBT3904这类小信号管),或者使用CPU、FPGA内部自带的温度二极管。芯片通过强制注入不同电流、测量二极管正向压差的方式,反推出远程节点的温度。
这个区别在实际部署中非常关键。暖通系统里,控制板往往装在电控箱内,箱内温度受功率器件发热影响,比实际回风温度高出好几度。如果只看本地温度,控制器会误判环境状态,导致压缩机频繁启停或者风机转速异常。远程二极管可以贴在风道、水管或者远端墙面上,把真实的环境温度拉回来。PJ85718DM这类芯片的价值就在于,一颗芯片同时搞定两路测量,省去额外的传感器和走线。
1.3 方案选型的几个核心考量
选STM32F745VG而不是更便宜的F103系列,主要出于三点考虑。第一,F745的I2C外设支持快速模式Plus,速率能到1MHz,在多路传感器轮询时能显著缩短总线占用时间。第二,F745的浮点单元和DSP指令让温度补偿算法可以实时跑,不需要查表近似,精度更有保障。第三,暖通控制器通常还要跑Modbus、BACnet或者自定义的上位机协议,F745的RAM和Flash足够把这些协议栈都塞进去,不用外挂存储。
PJ85718DM的选型逻辑则更偏向功能集成度。它支持双通道远程测温,也就是说一颗芯片能管两个远端节点,加上本地通道就是三路温度数据。对于暖通场景里常见的“回风+送风+板载”三测点需求,一颗芯片刚好覆盖。它的温度分辨率可配置到0.0625℃,在-40℃到125℃范围内精度能控制在±1℃以内,远程通道在3℃到100℃范围内也能做到±1℃。这些指标放在暖通控制里完全够用,毕竟空调系统的控制精度通常只要求±0.5℃到±1℃。
2. 硬件设计与关键参数解析
2.1 PJ85718DM的引脚配置与外围电路
PJ85718DM通常采用MSOP-8或者SOIC-8封装,引脚包括电源、地、串行数据、串行时钟、报警输出、远程二极管的正负端等。实际布线时,有几个地方特别容易出问题。
电源去耦必须做好。芯片的VDD引脚旁边要放一个0.1μF的陶瓷电容,位置越靠近引脚越好。如果板子上还有别的开关电源,最好再串一个磁珠或者小电感,把高频纹波挡一挡。我见过一个案例,客户把传感器芯片放在DC-DC旁边,读数每隔几十毫秒就跳变两三度,后来加了磁珠和屏蔽罩才稳住。
远程二极管的走线是另一个坑。D+和D-必须走差分对,尽量等长、靠近,远离时钟线和电源线。如果远程节点距离超过十厘米,最好用屏蔽双绞线,屏蔽层单端接地。走线太长或者干扰太强时,芯片读到的远程温度会偏高,因为注入电流在寄生电容上产生了额外压降。实测下来,二十厘米以内的普通走线问题不大,再长就要认真对待了。
2.2 STM32F745VG的I2C外设配置要点
STM32F745VG的I2C外设功能很全,但配置起来有几个参数需要仔细算。假设我们使用标准快速模式,总线速率400kHz,I2C时钟源选择APB1时钟,假设APB1跑在54MHz。那么CCR寄存器的值等于APB1时钟除以两倍的目标速率,即54MHz除以800kHz,得到67.5,取整为68。实际速率就是54MHz除以136,约397kHz,误差在可接受范围内。
上升时间寄存器TRISE要根据总线电容来设。标准模式最大上升时间1000ns,快速模式300ns。如果总线电容在100pF到200pF之间,TRISE可以设为APB1周期数乘以上升时间再加一。54MHz下周期约18.5ns,300ns对应约16个周期,TRISE设为17比较稳妥。
还有一点容易被忽略:STM32F745的I2C外设在某些批次上存在模拟滤波器导致的时序偏差,如果通信不稳定,可以尝试关闭模拟滤波,改用数字滤波,把DFSD位设成合适的值。这个细节在参考手册里写得很隐蔽,但实际调试时能省不少时间。
2.3 远程二极管的选择与校准
远程测温用的三极管不是随便拿一个就行。必须选择二极管接法下正向压降特性一致性好、串联电阻小的型号。MMBT3904是常见选择,它的发射结串联电阻大约在0.5Ω到1Ω之间,对测温精度影响很小。如果用了串联电阻大的管子,芯片读到的温度会偏高,因为串联电阻上的压降被误认为是结压降的一部分。
校准环节不能省。虽然PJ85718DM出厂时对远程通道做了初步校准,但实际板子的寄生参数、二极管批次差异都会带来偏移。我的做法是在已知温度点(比如25℃恒温箱)下读取远程通道原始值,和本地通道以及标准温度计对比,算出一个偏移量,写进STM32的补偿参数里。如果要求更高,可以做两点校准,分别在低温和高温点测偏移,用线性插值补偿。
3. 软件架构与核心代码实现
3.1 整体软件分层设计
软件部分我习惯分成三层:底层驱动层、数据处理层、应用逻辑层。底层驱动负责I2C读写和寄存器操作,数据处理层做温度换算、滤波和校准补偿,应用逻辑层处理报警判断、通信上报和系统控制。这样分层的好处是,换传感器或者换MCU时,只需要改驱动层,上面的逻辑基本不用动。
驱动层用STM32的HAL库来写比较快,但HAL的I2C函数在中断模式下有时会卡死,建议用DMA模式或者自己写状态机。我一般用DMA加空闲中断的方式,把I2C读写做成非阻塞的,主循环里轮询标志位。这样即使某个传感器暂时无响应,也不会拖死整个系统。
3.2 PJ85718DM的寄存器操作与温度换算
PJ85718DM的内部寄存器包括本地温度值、远程1温度值、远程2温度值、状态寄存器、配置寄存器、报警阈值寄存器等。温度值通常是16位,高字节是整数部分,低字节的高四位是小数部分,分辨率0.0625℃。换算公式是:温度等于原始值乘以0.0625。如果是负数,要注意补码处理。
读取流程一般是:先写指针寄存器指定要读的寄存器地址,然后发起读操作,连续读取两个字节。本地和远程通道的寄存器地址不同,需要分别读取。如果开了报警功能,还要读状态寄存器判断是哪一路触发了报警。
下面是一段简化的读取代码,基于STM32 HAL库:
#define PJ85718_ADDR 0x48 << 1 #define REG_LOCAL_TEMP 0x00 #define REG_REMOTE1_TEMP 0x01 #define REG_REMOTE2_TEMP 0x02 float read_temperature(uint8_t reg) { uint8_t buf[2]; HAL_I2C_Mem_Read(&hi2c1, PJ85718_ADDR, reg, I2C_MEMADD_SIZE_8BIT, buf, 2, 100); int16_t raw = (int16_t)((buf[0] << 8) | buf[1]); return raw * 0.0625f; }这段代码里,raw是16位有符号数,直接乘以0.0625就得到摄氏度。注意HAL_I2C_Mem_Read的地址参数要左移一位,因为HAL库把读写位也算在地址里了。
3.3 温度滤波与异常值处理
原始温度数据难免有噪声,尤其是远程通道走线较长时。直接拿原始值去做控制,会导致执行机构频繁动作。我通常用一阶低通滤波,公式是:滤波值等于上一次滤波值乘以系数a,加上本次采样值乘以1减a。a取0.8到0.95之间,根据响应速度要求调整。暖通系统里温度变化慢,a取0.95都行,响应时间常数大概几十秒,完全够用。
异常值处理也不能少。如果某次读到的温度突然跳变超过5℃,大概率是通信干扰或者传感器瞬态问题,直接丢弃这次采样,用上一次的值代替。如果连续多次异常,就要触发传感器故障标志,上报给上位机。这个逻辑用简单的计数器就能实现,不需要复杂的算法。
3.4 远程数据传输的实现方式
标题里提到“远程温度监测”,这里的远程有两层含义。一层是远程二极管测的是远端温度,另一层是数据要传到远端的上位机或者云平台。对于后者,暖通场景里常用Modbus RTU或者MQTT。如果是有线方案,RS485加Modbus最稳妥,抗干扰强,布线简单。如果是无线方案,LoRa或者NB-IoT都可以,但要注意功耗和实时性的平衡。
我在一个项目里用STM32F745的UART加MAX485收发器做Modbus从站,波特率9600,每500毫秒上报一次三路温度值。上位机是组态软件,直接读保持寄存器就行。协议栈自己写精简版,只实现功能码03和06,代码量很小,跑起来很稳。
4. 实操调试与常见问题排查
4.1 上电后读不到数据的排查思路
第一次调试时,最常见的问题就是I2C通信失败,读回来的全是0或者0xFF。排查顺序我一般是这样:先用示波器看SCL和SDA有没有波形,如果没有,检查GPIO有没有配置成复用开漏模式,上拉电阻有没有焊。如果有波形但数据不对,检查从机地址对不对,PJ85718DM的地址由A0、A1、A2引脚决定,悬空和接地的地址不一样。
还有一种情况是波形正常但ACK不对。这时候要检查电源电压是否在芯片工作范围内,PJ85718DM通常支持2.7V到5.5V,如果供电只有2.5V,芯片可能不工作。另外,如果总线上挂了多个从机,要确认没有地址冲突。
4.2 远程温度读数偏高的几种原因
远程通道读数偏高是最常见的精度问题。原因通常有三个:一是远程二极管的串联电阻太大,换低串联电阻的管子能改善;二是D+和D-走线太长,寄生电容导致电流注入时产生额外延时,芯片采样时刻偏晚,读到的压差偏大;三是芯片内部的电流源不匹配,这个只能通过校准补偿。
我遇到过一个案例,客户用了一颗杂牌三极管,串联电阻接近5Ω,远程温度比实际高了将近8℃。换成MMBT3904之后,偏差降到1℃以内。所以远程管的选择真的不能省成本。
4.3 温度跳变与通信干扰的抑制
温度跳变通常和通信干扰有关。如果I2C总线和电机驱动线、继电器线捆在一起走,干扰会耦合进来。解决办法一是拉开距离,二是加屏蔽,三是在软件上做多次采样取中值。我一般会连续读三次,去掉最大值和最小值,取中间值,这样能滤掉大部分瞬态干扰。
如果干扰特别严重,可以考虑降低I2C速率,从400kHz降到100kHz,波形边沿变缓,高频干扰的影响会小一些。另外,在SDA和SCL上各串一个33Ω到100Ω的电阻,也能起到一定的限流和阻尼作用。
4.4 常见问题速查表
| 现象 | 可能原因 | 排查方法 | 解决措施 |
|---|---|---|---|
| I2C无波形 | GPIO未配置为复用开漏 | 检查GPIO初始化代码 | 配置为AF_OD模式,加上拉 |
| 读回全0xFF | 从机地址错误 | 用示波器看地址字节 | 核对A0-A2引脚电平 |
| 远程温度偏高 | 二极管串联电阻大 | 查二极管型号 | 换MMBT3904等低阻管 |
| 温度周期性跳变 | 电源纹波大 | 示波器看VDD | 加去耦电容和磁珠 |
| 通信偶尔失败 | 总线电容过大 | 测上升时间 | 减小上拉电阻或降速 |
| 本地温度偏高 | 芯片靠近发热源 | 红外测温对比 | 远离功率器件或加隔热 |
5. 暖通场景下的应用扩展与经验总结
5.1 多测点组网与地址分配
暖通系统里往往需要监测多个区域的温度,比如每层楼一个测点,或者每个房间一个。PJ85718DM支持通过A0、A1、A2引脚设置不同地址,同一条I2C总线上最多可以挂8颗芯片,也就是最多24路温度。如果还不够,可以用I2C多路复用器扩展,或者改用RS485总线加多个节点。
地址分配建议在PCB上就用电阻固定好,不要用跳线帽,避免现场松动导致地址漂移。我在一个项目里见过因为跳线帽氧化导致地址随机变化,系统读到的温度全乱了,排查了半天才发现是硬件问题。
5.2 低功耗设计与休眠唤醒
如果设备是电池供电或者对功耗有要求,可以利用PJ85718DM的关断模式。通过配置寄存器的SHUTDOWN位,把芯片置于低功耗状态,电流降到几微安。STM32F745也有多种低功耗模式,Stop模式下功耗可以降到几百微安。采集时唤醒,采集完继续休眠,平均功耗可以做到很低。
不过要注意,从关断模式唤醒后,第一次温度转换需要等待一段时间,典型值是几十毫秒。如果唤醒后立刻读,可能读到的是旧数据或者无效值。我的做法是唤醒后延时100毫秒再读,确保转换完成。
5.3 实际项目中的几点体会
做这类温度监测项目,硬件和软件各占一半功夫。硬件上,电源和走线是重中之重,省什么都不能省去耦电容和屏蔽。软件上,滤波和异常处理必须做,否则数据没法用。还有一点,校准环节一定要在批量生产前做好,每块板子至少做一次单点校准,把偏移量写进Flash,这样出厂一致性才有保障。
另外,PJ85718DM的报警输出引脚可以接到STM32的外部中断,实现超温快速响应,不用轮询状态寄存器。这个功能在暖通安全保护里很有用,比如防冻保护或者过热保护,响应时间能缩短到毫秒级。
这个方案后续还可以扩展,比如加湿度传感器做焓值控制,或者加CO2传感器做新风联动。STM32F745的算力和外设资源足够支撑这些扩展,不用换主控。