1. 从一颗温度传感器说起:为什么HVAC系统需要"双脑"测温架构
做过暖通空调控制板的人都有一个共识:温度采样这件事,看起来简单,实际上是最容易翻车的地方。一颗NTC热敏电阻加一个ADC通道,理论上就能读出温度,但真正放到嵌入式HVAC场景里,问题立刻变得复杂起来——本地控制面板需要实时知道当前回风温度,远程的室外机或者远端温区又需要把数据汇总到主控,两边的采样精度、响应速度、抗干扰能力要求完全不同。
我最近在做一个HVAC控制器的温度监测模块,核心思路就是用PJ85718DM这颗I2C接口的远程温度传感器配合PIC18F46K22这颗经典8位MCU,搭一套本地+远程双路温度监测方案。选这个组合不是拍脑袋决定的,而是踩过几次坑之后总结出来的:PIC18F46K22自带多路10位ADC,适合接本地NTC做低成本采样;而PJ85718DM作为远程二极管温度传感器,可以外接一颗低成本的三极管或者二极管作为感温元件,把测温点延伸到几米甚至十几米之外,通过I2C总线把数字温度值直接读回来,省掉了长距离模拟信号传输带来的噪声问题。
这套方案解决的核心问题是:在同一个控制板上,用最低的BOM成本实现本地高精度温度采样和远程温度监测的共存。适合做HVAC主控板、新风系统控制器、机房精密空调、冷柜温控器等场景的嵌入式工程师参考。不管你是刚接触PIC18系列的新手,还是做过多年温控板的老手,这套组合的细节都值得掰开揉碎讲一讲。
2. PJ85718DM的测温原理与PIC18F46K22的ADC采样逻辑
2.1 远程温度传感器到底"远程"在哪里
PJ85718DM这类远程温度传感器的核心原理,是利用半导体PN结的正向压降与温度之间的线性关系。具体来说,它内部有一个高精度的电流源,轮流输出两个不同大小的电流(比如典型的10uA和100uA)注入外部的感温三极管。三极管在两种电流下的基极-发射极电压差ΔVbe与绝对温度成正比:
ΔVbe = (kT/q) × ln(N)
其中k是玻尔兹曼常数,q是电子电荷,T是绝对温度,N是两个电流的比值。这个ΔVbe大概在几十微伏每摄氏度的量级,非常微弱,但PJ85718DM内部有高精度ADC和斩波放大器,能把它转换成0.0625°C分辨率的数字值。
"远程"的含义就在这里:感温元件可以是一颗普通的2N3904三极管,也可以是专门封装的二极管,通过双绞线拉到几米外。因为传输的是电流信号而不是电压信号,线路电阻带来的压降影响很小,抗干扰能力比直接拉NTC模拟线强得多。这一点在HVAC场景里特别关键——室外机的温度采样点往往离主控板有好几米,如果用NTC拉长线,线阻和噪声会让读数飘得没法看。
2.2 PIC18F46K22的ADC配置要点
PIC18F46K22这颗MCU我用了很多年,它的10位ADC在8位机里算是中规中矩,但有几个配置细节如果不注意,采样值会莫名其妙地跳。本地温度采样我用的是一颗10kΩ的NTC热敏电阻,配合一个10kΩ的上拉电阻分压,接到AN0通道。
ADC配置的关键参数如下:
| 配置项 | 设置值 | 说明 |
|---|---|---|
| 参考电压 | VDD/VSS | 用电源做参考,简单但需保证电源稳定 |
| 采集时间 | 至少4us | NTC分压电路内阻较高,采集时间要够 |
| 转换时钟 | Fosc/16 | 在16MHz晶振下约1us每bit |
| 结果对齐 | 右对齐 | 方便直接读10位值 |
| 通道切换后 | 丢弃第一次转换 | 通道切换后第一次采样不准 |
这里有个很多人忽略的点:NTC分压电路的内阻。10kΩ NTC和10kΩ上拉电阻在25°C时分压点内阻大约是5kΩ,这个内阻对ADC采样电容充电需要时间。如果采集时间设得太短,采样值会偏低。我一般会把采集时间设到8us以上,并且在通道切换后丢弃第一次转换结果,从第二次开始取。
2.3 两条测温路径的数据融合
本地NTC走的是模拟通道,远程PJ85718DM走的是I2C数字通道,两者在MCU内部汇合。我的做法是:本地温度每100ms采样一次,做滑动平均滤波;远程温度每500ms读一次,因为远程传感器的转换时间本身就需要几百毫秒。两个温度值分别用于不同的控制逻辑——本地温度用于面板显示和即时控制,远程温度用于系统级的负荷计算和故障判断。
这种"双脑"架构的好处是:即使远程传感器断线或者I2C总线被干扰,本地温度依然能保证基本控制不失控。HVAC系统最怕的就是单点故障导致整个温控失效,双路冗余是必须的。
3. 硬件连接与I2C总线布线的实战细节
3.1 PJ85718DM的外围电路怎么搭
PJ85718DM的典型应用电路不复杂,但有几个电阻电容的取值需要根据实际场景调整。它的SDA和SCL引脚需要上拉电阻,典型值是4.7kΩ,但如果总线走线较长或者挂载设备较多,需要减小到2.2kΩ甚至1.5kΩ。我在HVAC板上一般用2.2kΩ,因为板子上I2C总线上通常还挂着EEPROM或者IO扩展芯片。
感温三极管的接法有两种:一种是接成二极管形式(基极和集电极短接),另一种是用两个三极管做差分。单管方案简单,但精度受三极管自身Vbe离散性影响;差分方案精度高,但占用更多PCB面积。对于HVAC这种对成本敏感的场景,单管方案配合出厂校准就够了。
注意:感温三极管到PJ85718DM之间的走线要尽量短,如果必须拉长,一定要用双绞线,并且远离功率开关管和继电器驱动线。我见过一个案例,感温线跟继电器驱动线捆在一起走,结果继电器一吸合温度读数就跳5°C。
3.2 PIC18F46K22的I2C外设配置
PIC18F46K22的MSSP模块可以配置成I2C主模式,配置步骤大致如下:
// I2C主模式初始化,100kHz SSP1CON1 = 0x28; // SSPEN=1, I2C主模式 SSP1ADD = 0x27; // 100kHz @ 16MHz Fosc SSP1STAT = 0x80; // 标准速度模式这里SSP1ADD的计算公式是:SSP1ADD = (Fosc / (4 × Fscl)) - 1。在16MHz晶振下,要得到100kHz的SCL频率,SSP1ADD = (16000000 / (4 × 100000)) - 1 = 39 = 0x27。
实际调试时我发现,PIC18F46K22的I2C在400kHz下跑长线容易出错,所以HVAC场景我一般就用100kHz,稳定压倒一切。如果确实需要更快读取,可以把远程温度的读取周期缩短,而不是提高总线速度。
3.3 电源与去耦的坑
PJ85718DM对电源噪声比较敏感,特别是它的远程测温精度直接受电源纹波影响。我在PCB布局时会在它的VDD引脚旁边放一个0.1uF的陶瓷电容和一个10uF的钽电容,两个电容要尽量靠近引脚。PIC18F46K22这边,AVDD和AVSS之间也要加0.1uF去耦,否则ADC读数会有周期性跳动。
还有一个容易忽略的点:I2C总线的地线。如果PJ85718DM和PIC18F46K22不在同一块板上,两地之间的地电位差会直接影响I2C电平判断。这种情况下要么用光耦隔离,要么保证两地共地良好。我在一个分布式HVAC项目里就遇到过这个问题,远程板的地线太长,I2C通信时好时坏,后来加了一根粗地线并联才解决。
4. 固件实现:从寄存器操作到温度换算的完整链路
4.1 PJ85718DM的寄存器读写流程
PJ85718DM内部有一组寄存器,最常用的是本地温度寄存器(地址0x00)、远程温度寄存器(地址0x01)、状态寄存器(地址0x02)和配置寄存器(地址0x09)。读取远程温度的完整流程是:
- 发送起始条件
- 发送设备地址+写位(PJ85718DM的7位地址通常是0x4C或0x4D,取决于A0引脚)
- 发送寄存器地址0x01
- 发送重复起始条件
- 发送设备地址+读位
- 读取高字节和低字节
- 发送停止条件
温度值的格式是11位,高字节是整数部分,低字节的高3位是小数部分,分辨率0.125°C。换算公式:
温度 = (高字节 << 3 | 低字节 >> 5) × 0.125
如果读到的值是负数(最高位为1),需要做补码转换。这个细节很多新手会漏掉,导致冬天室外温度读出来是200多度。
4.2 本地NTC的查表与线性化
NTC的阻值-温度关系是指数型的,直接用线性公式换算误差很大。我的做法是:先用ADC值算出NTC阻值,然后查表加线性插值。表格不需要太大,从-20°C到80°C,每5°C一个点,共21个点,存在Flash里。
const uint16_t ntc_table[21] = { 97000, 72000, 53000, 39000, 29000, // -20到0度 22000, 17000, 13000, 10000, 7800, // 5到25度 6200, 4900, 3900, 3100, 2500, // 30到50度 2000, 1600, 1300, 1050, 850, 700 // 55到80度 };查表时用二分查找定位区间,然后线性插值。这样算出来的温度误差在0.5°C以内,对于HVAC控制完全够用。如果要求更高,可以增加表格密度或者用Steinhart-Hart方程,但8位机的计算能力有限,查表是最务实的选择。
4.3 温度数据的滤波与异常处理
原始温度数据不能直接用,必须滤波。本地NTC我用的是滑动平均,窗口大小8,每100ms更新一次。远程温度因为读取周期长,我用的是中值滤波加限幅——如果新读到的值跟上一个值差距超过5°C,就认为是异常,丢弃不用。
异常处理还包括:I2C通信超时检测、传感器断线检测(读到的值固定为某个异常值)、温度超范围报警。这些逻辑在HVAC系统里是必须的,因为温度失控可能导致设备损坏或者能耗飙升。
5. 实测中遇到的三个典型问题与排查过程
5.1 远程温度读数周期性跳变
第一次联调时,发现远程温度每隔几秒就跳一次,幅度大概2-3°C。用示波器看I2C波形,发现SCL线上有毛刺。排查过程:
- 先怀疑上拉电阻太大,从4.7kΩ换成2.2kΩ,跳变频率降低但没消失
- 再看电源,发现PJ85718DM的VDD上有大约50mV的纹波,频率跟开关电源的开关频率一致
- 在VDD引脚旁边加了一个10uF钽电容后,纹波降到10mV以下,跳变消失
根因是开关电源纹波通过电源线耦合到了温度传感器的内部参考源上。这个坑在HVAC板子上很常见,因为板上通常有多个开关电源。
5.2 本地NTC在低温段读数偏高
在低温箱里测试时,发现-10°C以下NTC读数比实际值高3-4°C。排查后发现是NTC的自热效应——10kΩ NTC在分压电路里的功耗大约是(VDD/2)²/10k = 0.25mW,这个功耗会让NTC自身温度略高于环境温度。在常温下影响不大,但低温段NTC阻值变大,功耗降低,反而显得读数偏高。
解决办法是:降低采样频率,只在需要的时候给NTC分压电路供电,其他时间断开。用一个MOS管控制分压电路的上拉电阻供电,采样前10ms打开,采样后关闭。这样自热效应基本消除。
5.3 I2C总线在电机启动时通信失败
HVAC系统里有风机和压缩机,电机启动时会产生强烈的电磁干扰。实测发现,压缩机启动瞬间,I2C通信失败率明显上升。排查过程:
- 用示波器抓SDA线,发现电机启动时SDA上有大幅度的尖峰
- 检查PCB布局,发现I2C走线跟电机驱动线平行走了很长一段
- 重新布线,让I2C走线远离电机驱动线,并且包地处理
- 同时在SDA和SCL上各加一个100pF的电容到地,滤除高频尖峰
改板后,电机启动时I2C通信恢复正常。这个经验告诉我,HVAC板子的I2C布线绝对不能跟功率线平行走,交叉走都比平行走好。
6. 双路温度监测在HVAC控制策略中的实际用法
6.1 本地温度做主控,远程温度做补偿
在典型的HVAC控制逻辑里,本地温度(回风温度)是主控变量,用来决定压缩机启停和风机转速。远程温度(室外温度或者远端温区温度)用来做补偿——比如室外温度高时,适当提高室内设定温度,减少压缩机负荷。
具体实现上,我用了一个简单的补偿公式:
设定温度 = 用户设定值 + (室外温度 - 25) × 0.1
室外温度每高于25°C一度,设定温度提高0.1°C。这个系数是根据实际建筑的负荷特性整定的,不同项目需要调整。
6.2 远程温度的故障诊断价值
远程温度除了做补偿,还有一个重要用途是故障诊断。比如:
- 如果远程温度跟本地温度差距异常大(超过20°C),可能是传感器断线或者风道堵塞
- 如果远程温度变化速率异常(比如1分钟内变化超过10°C),可能是传感器接触不良
- 如果远程温度长时间不变,可能是传感器失效
这些诊断逻辑我都在固件里实现了,通过状态寄存器上报给上位机。HVAC系统维护成本高,能自动诊断故障可以省下大量现场服务费用。
6.3 采样周期的权衡
本地温度采样周期100ms,远程温度500ms,这个组合是权衡的结果。本地温度需要快速响应,因为回风温度变化直接影响控制稳定性;远程温度变化慢,500ms足够。如果远程温度也做到100ms,I2C总线负载会增加,而且PJ85718DM本身的转换时间就需要几百毫秒,读太快没意义。
提示:PJ85718DM的远程温度转换时间跟配置有关,默认是8次平均,大约需要300ms。如果对速度要求高,可以减少平均次数,但精度会下降。
7. 从这套方案延伸出去的几个优化方向
7.1 多路远程温度的扩展
PJ85718DM只支持一路远程测温,如果系统需要监测多个温区,有两个方案:一是用多颗PJ85718DM,通过A0引脚设置不同地址挂在同一条I2C总线上;二是换用支持多通道的远程温度传感器。前者成本低但占用PCB面积,后者集成度高但单价贵。我在一个多温区冷柜项目里用了三颗PJ85718DM,地址分别设为0x4C、0x4D、0x4E,共用一条I2C总线,工作很稳定。
7.2 温度数据的校准策略
批量生产时,每块板的NTC和感温三极管都有离散性,需要校准。我的做法是:在产线用标准温度源分别测两个温度点(比如0°C和50°C),算出每块板的偏移量和斜率修正系数,存在EEPROM里。运行时用这些系数修正读数。这样可以把整体精度从±2°C提升到±0.5°C以内。
7.3 低功耗场景的考虑
如果HVAC控制器有电池备份或者低功耗要求,PJ85718DM可以配置成单次转换模式,平时处于关断状态,需要测温时唤醒转换一次再关断。PIC18F46K22也有多种低功耗模式,配合起来可以把待机功耗降到微安级。不过HVAC主控一般都有市电供电,这个优化更多是用在无线温控器或者电池供电的传感器节点上。
这套PJ85718DM加PIC18F46K22的温度监测方案,我从第一版打样到现在批量出货,前后改了三次板,固件迭代了十几个版本。最大的体会是:温度采样这件事,原理简单但细节魔鬼,电源、布线、滤波、校准,每一个环节都可能让读数不准。把这些问题都解决之后,这套方案的稳定性确实让人放心,连续跑几个月温度漂移都在0.5°C以内。