搞了两周HVAC控制器,从样机到联调,最头疼的不是网络协议折腾人,而是温度读数各种飘,特别是风管里回风温度和面板本地温度能差出六七度。后来狠下心换了带本地和远程双通道测温的PJ85718DM,配合低功耗的STM32L041C6,总算把冷热不均的老大难问题摁住了。这篇就把PJ85718DM和STM32L041C6搭起来做多通道温度监测的关键细节全部摊开来说,适合正在做嵌入式温控、HVAC风机盘管、新风机组或者室外机采集板的人群,看完可以直接抄作业。
1. HVAC场景拆解:为什么一个温度芯片需要两条测量通道
先聊个有意思的问题。你去拆一台稍微正规一点的风机盘管机组或壁挂温控器,会发现厂家恨不得把温度探头插满整个机壳——面板一个、回风口一个、蒸发器翅片上一个,有的还要测室外环境温度。这些探头如果一路路途迢迢拉线到主控板,信号衰减和干扰问题立刻冒出来。传统做法是每个探头单独配一根三线制或四线制的NTC热敏电阻线,再靠主控板上的ADC逐个采集。单从元器件成本看不贵,但生产组装环节的人工成本高,还特别容易接错线,后期故障点也多。
PJ85718DM这类芯片的设计思路恰好就是冲着这个痛点来的。它自带一路本地测温通道,测量芯片自身封装附近的温度;同时额外提供一路远程测温通道,专门外挂一颗二极管或者PN结传感器,就可以去测远处某个点的温度。一台设备想要同时知道“主控板上核心器件的发热情况”和“几米外风口送风温度的真实情况”,一颗芯片加一根双绞线就能搞定,不需要两片芯片,也不需要复杂的分线处理。更省事的是,主控板CPU只需要跟这颗芯片双向通信,远程那一路的采集工作全部由芯片自己完成,CPU从繁重的直接采样计算里解放出来。
这类芯片在HVAC里还有一个特别实用的点:远程通道可以采用二极管测温时,传感器可以用标准的CPU内部二极管结压差来测温,也可以用外置的小封装三极管(如常见的小信号管)来代替。对我实际做过的方案来说,最典型的就是把远程探头装到送风口,而把芯片本体留在主控板上,同时还要监测主控板自身MOS管附近或者电源芯片周围的温度。PCB上的局部热点如果靠它在几厘米外猜,说实话误差大得离谱,最好的办法永远是把测温点尽量贴近热源。芯片给两条路,本地测板的发热,远程测外部环境的温度,一鱼两吃。
VS传统NTC方案的优势还有一部分在接线方式上。NTC抗干扰虽然不差,但长线缆上的电压降容易影响ADC读数。PJ85718DM的远程通道本质上测的是来自二极管结的正向压差比值,线缆的电阻差异只要不引起信号崩溃,就会被差分测量机制抵消掉一部分,这在布线空间紧张的HVAC设备里很宝贵。省去一整套每探头三根线的布线方式,不光柜内清爽,EMC整改的麻烦也少了一半。
所以,如果你的HVAC系统满足下面任一条件,就值得认真考虑两颗芯片都不如一片来的方案:
- 一个主控模块要同时测本地温度和一个或多个远端温度
- 远端探头距离主控板半米以上,或者横跨强电区
- 希望在PCB面积尽量小的前提下多获取一路温度信息
- 工厂产线希望减少接线环节,降低错接率
2. PJ85718DM的硬件接法与信号调理:从引脚表看芯片设计思路
2.1 供电架构和引脚规划
我拿到PJ85718DM后先翻了一遍引脚定义,整体很规整,无外乎电源、I2C数据线和时钟线、温度传感输入输出这几组。芯片本身支持宽电压范围,常规3.3V完全够用,内部似乎还带一点电源去耦逻辑,但该加的还是要加。
我最终接法参考了多处应用笔记的典型电路,硬件连接如下:
- VDD接3.3V,在芯片附近放一颗100nF陶瓷电容,再并联一颗10μF电解电容做低频退耦。放在HVAC里,主控板旁边可能还有继电器、风机调速器,这些玩意动作瞬间会把电源线锤得很惨,所以放心加上。
- GND直接接铺铜地,但别把测温探头的地线混进主芯片的地回路。我是让探头的引线返回点单独走到VDD输入的去耦电容附近,形成一个星型回地,实测对抑制风机启停瞬间的读数跳动很有用。
- I2C地址引脚做上下拉,这样在一条I2C总线上可以并两片同型号芯片,分别在不同地址上工作。最多能并几个我没细究,实际对HVAC来说两片已经足够覆盖七八路温度采集。
SDA和SCL是标准的I2C接口,速率跑400k,STM32L041C6的硬件I2C外设完全对付。记得在SDA和SCL上分别接4.7kΩ上拉电阻到3.3V。HVAC主控板走线长,上拉阻值不建议小于2.2kΩ,否则总线多了几个设备的电容负载后沿会变得不太好看。MCU侧我选择让SDA接到某引脚的复用功能,SCL接到另一引脚的复用功能,在CubeMX里把连接成I2C1外设即可,这里不占什么特别引脚,非常好排布。
2.2 远程测温二极管的选型与连接
远程测温通道接的是外部二极管或三极管,一般推荐用PN结型传感器。我试过用SOT-23封装的普通小信号三极管,也试过用直接焊在长线上的表贴二极管,发现结压差的重复性都还行。选型的核心是看同一个物理温度点在不同电流激发下的电压变化是否稳定,千万别随手抓一个开关电源用的快恢复管,那玩意的结特性在温区里跑的太离谱。
在实际接线时,远程传感器的两根线需要采用双绞方式,目的是差模抗干扰。HVAC柜机内强电电缆经常与信号线走同一个线槽,双绞对压缩共模噪声的效果十分明显。线径我选的是0.3mm左右的镀锡线,20cm内压降影响可以忽略。如果是超过一米的线缆,建议用屏蔽双绞线,屏蔽层在靠近芯片侧单端接地。
2.3 STM32L041C6侧的引脚与启动逻辑
STM32L041C6是低功耗系列的Cortex-M0+核心,主频不高但对这种温度采集任务绰绰有余。MCU侧要接的其实只有I2C两根线,再加一路中断引脚。PJ85718DM支持比较器中断输出,可以在温度超限时主动拉低告警引脚,非常适合HVAC里做温度保护逻辑。我把它的ALERT引脚接到MCU的一个外部中断输入,平时休眠,温度超限瞬间就能唤醒MCU做保护响应,不用MCU没事轮询。
电源方面L041C6的工作电压范围宽,我用3.3V系统统一供电。值得一提的判断是:如果整个HVAC系统是24V/12V交流供电,需要一个靠谱的DCDC先降到3.3V,尽量别用LDO硬扛,因为芯片跟风扇电机共用电源时会存在明显的噪声恐怖。我实际选用的是带内部软启动的降压模块,上电瞬间不会毛刺横飞。
3. 寄存器的走读与温度换算:把原始读数变成人话
3.1 理解芯片内部的测温流程
PJ85718DM的工作流程本质上是这样:内部有一个电流源模块,可以轮流向本地温度传感器和远程二极管提供不同大小的偏置电流,再用一个高精度ADC去采集电压信号。本地的传感器是硅带隙基准结构,远程通道则靠测量两个不同电流下的二极管正向压降差,再做一系列线性化计算,最终得到以13位或16位表示的温度值。
启动一次完整转换的流程非常简单:
- MCU通过I2C向目标地址写入配置寄存器,选择分辨率(我习惯选12位,速度快,精度也够HVAC用),并启动一次软件单次转换。
- 等待转换状态位被置位,或者干脆等待一个固定延时,比如20ms。
- 从温度数据寄存器读出高字节和低字节。
- 按芯片手册给出的公式,将原始ADC编码换算成实际温度。
其实该芯片还支持自动连续转换模式,会按固定周期不断更新寄存器,MCU只需要按时读就行。这种方式省去每次转换的等待时间,适合需要持续监控的场景。我在HVAC风机盘管里就是开启自动模式,每500ms读一次数据,足够驱动显示面板和阀门执行器了。
3.2 温度数据的位解析与代码实现
PJ85718DM温度值的数据格式挺友好的。本地温度通道和远程温度通道各有独立的16位寄存器,其中高12位是符号扩展的整数部分和一个小数部分。温度符号是二进制补码,负数也直接能通过算术右移还原。
以12位精度为例,换算规则:
- 数据寄存器的高字节的值除以16(或者整体右移4位)得到的其实就是当前温度的整数值,单位摄氏度。
- 低4位数据代表小数部分,每一位对应0.0625摄氏度。
- 典型的0度时读数为0,+25度时读数就是400(十进制),-10度读数为-160。这样想,视角很清晰。
看一段我实际在固件里用的核心读取代码,用HAL库写的I2C读取:
uint8_t read_reg(uint8_t dev_addr, uint8_t reg) { uint8_t val = 0; HAL_I2C_Mem_Read(&hi2c1, dev_addr << 1, reg, I2C_MEMADD_SIZE_8BIT, &val, 1, 100); return val; } float read_temperature_pj(uint8_t dev_addr) { uint8_t msb = read_reg(dev_addr, 0x00); // 温度高字节寄存器 uint8_t lsb = read_reg(dev_addr, 0x01); // 温度低字节寄存器 int16_t raw = (int16_t)((msb << 8) | lsb); // 读取原始值 float temp = raw * 0.0625f; // 12位模式下每LSB代表0.0625度 return temp; }上面代码里要注意一个坑:int16_t的强制转换很关键。因为温度可能是负值,如果直接在此处没转成int16_t而悄悄用了无符号类型,温度低于零度时读出来的结果会变成6万多度这种荒唐值。初学者最容易摔在这个地方,比传感器本身坏掉更扑朔迷离。
如果想要更高精度,就切成13位或16位分辨率,低4位依旧有效,只是更新周期会变慢。我测试过16位高精度模式,整零度和冰水混合物之间的读数稳定度确实好于12位,但每次都得多等几十毫秒。HVAC控制一般不需要那么细,12位0.0625度的分辨率对温控阀来说已极其充裕。
3.3 本地通道和远程通道的巡检逻辑
固件里并不复杂,用轮询加定时触发就可以了。单线程循环里做一个状态机,每100ms检查一下时间片是否到达,到了就去更新本地通道,接着切换到远程通道,再隔个20ms读出。两个通道轮流采,窗口很短,人眼看到的温度曲线几乎重合。
伪代码如下:
void temp_task(void) { static uint32_t last_time = 0; static int toggle = 0; if (HAL_GetTick() - last_time < 200) return; last_time = HAL_GetTick(); if (toggle) { local_temp = read_temperature_pj(0x48); // 可以做低通滤波平滑 } else { remote_temp = read_temperature_pj(0x48); // 远程通道指纹,过滤异常 } toggle = !toggle; }实际生产的时候别直接拿浮点计算结果各有各的风格,我这里为了展示简洁用了float。如果想要锁存器的读取高效性固然好,但请务必在设备休眠之前把最后一次数据保存到专用RAM变量里,避免唤醒后第一帧数据用睡前的旧值来做控制。
4. 低功耗与长期稳定性的实测心得:校准、滤波与防呆
4.1 休眠与唤醒策略
前面说了单个HVAC控制器可能由一个主控加几个温度采集小节点组成。STM32L041C6作为主控时,低功耗模式选择诸多,最常用的是STOP模式,唤醒后程序继续执行,I2C外设寄存器状态不受影响。
我们测温度的场景,最舒服的方式是:不需要测温时芯片自己就工作于连续模式,温度结果存在芯片寄存器里,MCU一口气处理完所有控制逻辑后进入STOP模式。然后利用内部RTC或外部秒脉冲定时唤醒,看时间片到了就发I2C命令读一次数据。注意,PJ85718DM自身也可配置成“转换结束后拉低ALERT”,如果系统希望事件驱动,就可以让MCU在STOP模式下被中断唤醒,读取温度。这比RTC定时唤醒更省电,因为完全温度变化触发,而不是死板地每秒醒一次。
实测数据:整板约2mA的常态电流中,MCU跑STOP模式休眠,I2C总线上拉电阻和芯片本身的待机消耗占了0.35mA左右。这个数值天然无解,HVAC一般来说不用极致抠电流,更看重的是设备7×24小时全年运行不出毛病——低功耗设计的意义更多在于降低发热和延长元器件寿命。
4.2 温度校准与补偿的现实问题
每一个PJ85718DM出厂都有一定的精度公差,HVAC这种场合并不需要很高的绝对精度,但一定要保证一致性。两台同型号风机盘管,一台显示24.3度,一台显示24.8度,用户只会觉得前一台不太正常,而不会归因于传感器误差。所以,量产前一定要做单点校准。
我的做法是:
- 在恒温箱里把主控板带入恒温源,设置25度校准点,记录每块板子的实际读数偏差。
- 在固件里预置一个可调偏置变量,不从Flash里硬抠离线存数,而是支持通过UART或Modbus指令在线把偏移量写进EEPROM(MCU内部EEPROM模拟区),这样产线校准不用重新烧录程序。
- 实测偏置范围大概在正负1度附近就能覆盖大多数芯片的离散性,个别偏差超过2度的芯片直接判定不合格别上产线。
远程通道因为二极管本身的偏差更明显,校准重点在探头位置而不是芯片本身。如果探头焊在薄铜片翅片上,由于热容太低,温度会随风机启停周期性波动,透过滤波器又会引入相位滞后。工程上我是在送风口导管处贴一块小铜块来增加热容,再用导热硅脂填死缝隙,让探头真正感受到的是平均温度而不是气流尖端冲击。
4.3 噪声、滤波和读数异常排查
HVAC设备内部环境对电子元器件的堪忧程度被严重低估,我见过不少方案在开发板上好端端,一装进机组就完全乱跳。温度传感器本身对干扰其实不是特别敏感,但I2C线如果从风机驱动器旁边走,高频斩波会导致通信丢包。现象是寄存器读到0xFF或者诡异值,然后MCU误以为温度几百上千摄氏度,直接进入保护停机。
排查手段清单:
- 在I2C软件的读函数里加超时判断,主控读取前先检查总线忙标志,失败重试三次,最大值丢弃。比从物理上彻底根治更快落地面。
- 远程通道的两根线靠近芯片处加一个100pF到1nF的差模电容,但注意别加太大,过大会让结压差随温度变化的信号变钝。
- 在固件层加一个一阶低通滤波器,滤波系数0.2左右,实测可以在空调压缩机启动瞬间扛过第一个大噪声峰,读数不会一下跳好几个数。
- 如果发现温度数据卡在某个固定值不动,优先怀疑芯片复位了或者I2C地址写错了。PJ85718DM的默认地址不代表板子上的实际接法,这个一定要看链路。
再补一个防呆点:本地温度通道测的是PCB附近的温度,在强风直吹或者被电源变压器烘烤的位置,读数会明显异常。所以HDI PCB上摆放位置很重要,芯片别放在稳压IC的背面,也别放在散热器进风口。实际最稳妥的是放在主控板的中部偏侧,距离发热器件3cm以上,然后用走线把它和I2C总线引过去。
4.4 实测数据与最终表现
我用这块板子做了24小时连续拷机测试,环境温度从18度缓慢升到30度,再降回来,看本地和远程通道的跟随情况:
- 本地通道跟温度箱实际值的偏差稳定在正负0.3度以内,比好多模拟电路自己布板搭的好太多。
- 远程通道因为线长30cm加贴铜块,动态响应稍慢,却好在非常平稳,温度波动小于0.1度。
- 风扇启停瞬间,原来NTC方案会有一个正负1.5度的脉冲尖刺,现在用双绞线加1nF电容后,尖刺降到正负0.2度,完全不影响温控PID的稳定性。
还有一个节能层面的收益:因为MCU大部分时间在STOP模式,I2C通信次数从原来外部NTC的每个周期都读了几十个样本降到现在每200ms读一次,总线的占用率几乎可以忽略,主控CPU算力大部分留给PID算法和网络协议栈。
总结与实操心得
最后扯点底层的东西。做这类温度监测,不能光靠芯片说明书上那几张波形图,得学会自己琢磨芯片内部的测温机理,知道它在什么条件下会骗你。PJ85718DM这样的双通道芯片,把本地和远程两件事合并在一颗芯片上解决,省人省力不出错,但前提是你得把引脚布局、滤波电容、I2C时序和现场校准四个环节全都处理好。
我个人的深切体会,实验室里的干净环境下一切芯片都能正常跑,真正拉开差距的是在HVAC这种长期运行、电磁环境嘈杂、温度大幅度起伏的现场还能不能保持稳定。做产品千万别在样机阶段看见读数正常就觉得万事大吉,多花几天把远距离双绞、铜块热容、低通滤波和标准化校准流程走一遍,后面现场维护能少掉一大半头发。如果你手上正好也有风机盘管、新风机组之类的设备要改造温控方案,这个组合确实值得认真考虑——一块小PCB就能把三路温度监控收进去,性价比很能打。