搞HVAC嵌入式项目的朋友应该都有这种感觉:现场机组的回风温度、压缩机的排气温度、管路的表面温度,经常不在同一个物理位置,但主控板上又不可能到处放传感器。最头疼的是,那些靠近强电和震动部件的测点,用普通热敏电阻测出来的数老是飘,铝壳里的读数和你红外枪打出来的能差好几度。我后来在项目里把温度采集统一换成了“PJ85718DM 温度传感器 + STM32F042C6 主控”这套组合,一个数字芯片就能同时搞定本地和远程两路温度监测,再把数据通过总线送出去,整个系统的测温逻辑一下子清爽了很多。
这篇文章就把这套方案从头到尾讲清楚,包括为什么这么搭配、硬件怎么接、软件怎么写、现场会踩哪些坑,还有我从调试记录里总结出来的排查思路。适合正在做HVAC控制器、嵌入式温控模块,或者准备把多点温度监测做成标准化功能的工程师。不管是刚上手还是想优化现有方案,看完基本都能直接往自己板子上套。
1. 整体设计思路:为什么是“本地+远程”双通道
1.1 需求拆解:HVAC系统到底需要测哪些温度
先别急着选型,把HVAC现场的测温点捋一遍。压缩机排气口、冷凝器盘管、蒸发器进出口、回风口、送风道、电控板周围环境……这些点的工作条件差异极大:有的温度只有几度,有的常年七八十度,有的是直接贴在强电驱动板旁边,还有的在离主控板一两米外的风道深处。
这种场景下,把测温点简单分成两类最合理:
- 本地温度:主控板附近的环境温度,或者板级核心器件的壳温。
- 远程温度:远离控制板安装,需要延长线引到被测物表面的温度点。
如果每个远程点都用一颗独立传感器,成本、空间、走线都会失控。更优的思路是:主控板上放一颗带远程通道的数字温度传感器,本地测自己,远程通道通过一条细线拖到远处的测点,用一个PN结(一般就是小信号三极管的基极-发射结)完成感温。PJ85718DM 就是这种架构,一颗芯片顶过去两颗,还省掉了模拟信号长线传输的干扰问题。
以常见风冷模块机组为例,主控板在电气腔,压缩机在另一个腔体,排气温度传感器如果从电气腔拉线过去,传统NTC方案至少要两线制加屏蔽,ADC采集还要做线性化校准。换成PJ85718DM之后,电气腔本地温度由芯片内部测温,压缩机排气口温度通过远程二极管通道采,滤波和ADC都在传感器内部完成,输出直接是数字量,MCU读回来就是校准过的温度值。
1.2 硬件选型:PJ85718DM 和 STM32F042C6 各自承担什么
选 PJ85718DM 的原因很直接:它是 I2C 接口的数字温度传感器,内置本地测温通道和远程测温通道,分辨率能做到 0.0625°C 量级,测量范围覆盖 -55°C 到 +125°C 本地、远程到 +127°C 左右,完全覆盖HVAC常规场景。更关键的是出厂前做过校准,MCU 不用自己做热敏电阻分压标定,省掉的开发和产线工时是实打实的成本。
STM32F042C6 这边,看名字就知道是 Cortex-M0 内核,主频 48MHz,Flash 32KB、RAM 16KB,带2路I2C、UART、SPI、CAN 和 USB。对温度采集这种任务,性能绰绰有余。真正打动我的是三点:
- 硬件I2C支持400kHz甚至更快,不用软件模拟时序,稳定性好很多。
- 自带CAN控制器,HVAC机组之间组网直接省一颗外部CAN IP核的钱,只要加个收发器。
- 低功耗模式丰富,电池供电的温控面板也能撑得住。
选型时我还做过一组对比,供大家参考:
| 方案 | 精度表现 | 接线复杂度 | 成本 | 长期可靠性 |
|---|---|---|---|---|
| NTC + 板载ADC | 依赖分压电阻和校准表,批量一致性差 | 远程线长时易受干扰 | 物料便宜但调校成本高 | 电阻老化会漂 |
| 单点数字传感器 | 出厂校准,精度好 | 远程点仍需另外布点 | 每点都要一颗芯片 | 数字输出,稳定 |
| 热电偶 | 测温范围大但冷端补偿麻烦 | 需要专用调理电路和补偿 | 中高 | 长时间有漂移 |
| PJ85718DM 本地+远程 | 内部校准,双通道一致性好 | 远程点一条双绞线拉二极管即可 | 单芯片双点,性价比高 | 无机械磨损,寿命长 |
这套对比不是理论推演,是我在某次预研项目里实际测过的结论。常规NTC那一路,光做分压电阻温漂补偿就调了两天,最后低温段还是差1.5°C,换了PJ85718DM方案之后,零下和高温端的读数都能对得上校准源。
1.3 系统拓扑:I2C最小系统加总线组网
整个方案的基本拓扑很简单:STM32F042C6 作为 I2C 主机,PJ85718DM 挂在 I2C 总线上作为从机。远程测温点通过屏蔽双绞线连接到传感器的远程通道引脚。主机按需读取本地和远程温度寄存器,然后通过UART转RS485或者CAN总线把数据上报到上位机或集控器。
如果一个项目里测温点超过两个,可以按I2C地址复用扩展,只要芯片地址引脚支持多地址配置,一条I2C总线上挂4~8颗PJ85718DM都没问题。STM32F042C6 的 I2C 外设带超时检测和错误中断,总线上哪颗从机拉死,主控也能及时发现并恢复,这一点在工业现场特别重要。
2. 温度传感器机制与关键参数解析
2.1 本地温度检测原理
PJ85718DM 的本地测温实现,简单说就是内部给一个结型二极管施加已知偏置电流,测量PN结的正向压降变化。半导体PN结的Vbe和温度成反比关系,温度每升高1°C,压降大约下降2mV左右,这个物理特性非常稳定,所以不需要每颗芯片都做复杂的分压电阻校准,出厂时把内部偏移修正系数写好就行。
实际使用中我遇到过有人把它理解成“高级热敏电阻”,这是不对的。热敏电阻的阻值和温度是非线性曲线,数字传感器内部还有ADC、基准电压源和校准存储器,整个感知-量化-校正链路都在芯片内完成。MCU拿到的已经是标准二进制补码形式的温度值,换算关系也固定:12位数据右移4位后乘以0.0625。
这里有个细节,本地通道测的是传感器芯片所在PCB附近的空气温度,不是芯片的结温。如果芯片旁边有个发热量大的电源芯片,读数会偏高。板上设计时,PJ85718DM 要尽量避开大功率器件,或者在结构上给它留出通风缝隙。
2.2 远程温度检测原理与PN结感温
远程通道是这套方案最值钱的部分。原理上仍然利用PN结压降与温度的关系,但感温元件不在传感器内部,而是通过两条引线接到远处的三极管PN结上。一般选用小信号三极管,把基极-发射结用作测温结。传感器内部会给这个外接PN结提供固定的激励电流,然后测量压降并换算成温度。
这样做的好处非常明显:感温端体积小、响应快,可以直接贴在被测表面或者绑在管道上,而主控板和分析电路都在电气腔,避免了敏感模拟信号长距离传输。而且PN结的一致性比热敏电阻好得多,只要三极管的β值满足要求,不同批次之间的互换性都很好。
实际接线中,我习惯在靠近传感器一端串个2.2kΩ到10kΩ的电阻,再对地并一个1nF到4.7nF的电容,组成一级RC低通滤波,抑制引线耦合进来的高频干扰。具体的RC取值还是那句话,以型号手册为准,这个组合只是我在现场验证过可用的起点。
2.3 寄存器地图与精度设计
PJ85718DM 这类双通道数字传感器,寄存器布局通常包括配置寄存器、状态寄存器、本地温度寄存器、远程温度寄存器、温度上限/下限设定寄存器等。配置寄存器主要控制转换速率、单次/连续转换模式、关断模式、ALERT引脚输出极性。温度寄存器一般是16位,高字节为符号位加整数位,低字节的高4位是小数位,低4位不用。
我写驱动时有几个重要习惯:
- 配置寄存器操作之前,先读后写,保留默认位,避免把保留位清零惹出奇怪问题。
- 温度寄存器最好一次性连续读2字节,不要分两次单字节读,防止两次读数之间发生更新导致高低字节不匹配。
- 如果芯片支持SMBus的PEC校验,在工业现场建议开启,虽然增加了一点软件开销,但能拦截很多长线干扰造成的字节错位。
从精度角度看,0.0625°C的分辨率对HVAC应用已经非常富余,毕竟系统控温精度一般在±0.5°C到±1°C,传感器本身的出厂精度通常是±1°C甚至更好。真正限制系统精度的往往是传感器封装和被测表面的热阻,所以后面要专门聊安装工艺。
2.4 I2C总线上拉电阻与地址规划
STM32F042C6 的硬件I2C与PJ85718DM连接时,除了SCL和SDA两根线,还要注意上拉电阻的选择。常见误区是随便放个10kΩ,结果总线电容一大,400kHz下时钟上升沿爬不上去。
我一般这样估算:假设总线总电容100pF,期望上升时间不超过300ns,根据 RC 充电公式 t_r ≈ 2.2RC,R 大约在1kΩ到4.7kΩ之间。实际项目中,2.2kΩ是万金油,既能满足400kHz时序,又不会因为电阻太小导致功耗偏高。如果总线挂载芯片多、走线长,可以降到1.5kΩ,但I2C空闲时电流要重新核算。
地址规划方面,PJ85718DM 的7位I2C地址通常由地址引脚的电平组合决定。一条总线上挂多颗传感器时,提前画好地址分配表,避免和板上的EEPROM、RTC等其他I2C外设冲突。我在某块采集板上挂过两路PJ85718DM,其中一个地址引脚接地、一个接电源,软件里做个地址表映射到物理测点,用起来和独立地址一样清晰。
3. 嵌入式软件实现与核心代码
3.1 基于STM32F042C6的I2C外设初始化
STM32F0系列我用的是 HAL 库配合 CubeMX 初始化,这部分简洁、易维护。一次实际项目中通常这样配置:
hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 400000; // 400kHz Fast Mode hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; // 16/9占空比,400kHz下常用 hi2c1.Init.OwnAddress1 = 0; // 主机不需要自己的从机地址 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; HAL_I2C_Init(&hi2c1);初始化之后,强烈建议在代码里做一次总线扫描,把总线上实际存在的从机地址打印出来。这个动作能在装整机前发现地址冲突、漏焊、虚焊问题。STM32F042C6 的 I2C 超时中断里顺手做一个总线恢复:把SCL翻转9次,让卡在半途的从机复位状态机,这个技巧后面会细说。
3.2 PJ85718DM驱动框架与温度读取
驱动层我习惯封装成三个函数:写配置寄存器、读温度寄存器、处理错误重试。下面代码里的寄存器偏移基于常见兼容定义,具体型号拿到后请以手册为准替换宏定义。
#define PJ85718DM_I2C_ADDR 0x48U // 实际由地址引脚决定 #define PJ85718DM_REG_CONFIG 0x01U #define PJ85718DM_REG_TEMP_LOCAL 0x05U #define PJ85718DM_REG_TEMP_REMOTE 0x07U uint8_t pj_read_temp(uint8_t reg, float *temp) { uint8_t buf[2]; int16_t raw; HAL_StatusTypeDef ret; ret = HAL_I2C_Mem_Read(&hi2c1, (PJ85718DM_I2C_ADDR << 1), reg, I2C_MEMADD_SIZE_8BIT, buf, 2, 100); if (ret != HAL_OK) { return 1; } raw = (int16_t)((buf[0] << 8) | buf[1]); raw >>= 4; // 去掉低4位无效位 if (raw & 0x0800) { raw |= 0xF000; // 12位有符号扩展 } *temp = raw * 0.0625f; return 0; }写配置时注意 HAL 的 Mem_Write 接口,第一个地址参数同样要左移一位,因为 HAL 库在部分版本里传入的是7位地址加上读写位,这里最容易踩坑。我见过同事把地址左移了一次,又靠检查I2C波形找半天,最后发现是HAL封装和寄存器直接操作混着用的锅。
3.3 采样滤波与数据处理
HVAC系统温度变化通常比较缓慢,几秒采样一次足够,但现场EMC干扰可能让单次采样跳变。我用的是一阶滑动平均,窗口大小8次,权重可调。温度进入控制环之前,再加一个变化速率上限判断:如果相邻两次采样差值超过比如5°C,说明大概率是干扰或者接线问题,直接丢弃这次数据,走重新读取流程。
另外,同一个传感器的本地和远程温度读取,最好放在同一个任务周期里完成,这样两路数据的时序对齐。主机读回来的原始数据先存成float,到上层协议再换算成带一位小数的整型值传输,比如250表示25.0°C。这种定标方式在Modbus协议里非常常见,避免浮点传输的字节序争议。
3.4 数据上报与组网接口
STM32F042C6 自带CAN控制器,所以我在HVAC机组节点上更倾向用CAN上报温度。把本地温度、远程温度、告警状态打包成标准CAN数据帧,8字节足够装两路温度加状态位。如果要走RS485,就用Modbus-RTU,寄存器表固定好:保持寄存器40001对应本地温度,40002对应远程温度,40003对应状态字。
考虑到现场调试方便,我通常预留一组测试命令:通过UART串口终端直接读温度寄存器,十六进制打印原始值和换算后的温度值。整机联调时不用依赖上位机软件,拿一个USB转串口就能确认传感器焊接和通信是否正常。
4. HVAC场景中的硬件落地与工程化
4.1 传感器布局、接线与PCB设计细节
PCB上,PJ85718DM 尽量远离开关电源的变压器、电感等磁场源,也不要挨着MOS管驱动电路。本地测温点如果用来采集控制板环境温度,就在芯片周围留一点通风空间,别用大块铺铜把芯片包得严严实实。
远程通道引线在两块板之间走的时候,务必使用双绞屏蔽线,屏蔽层单端接地,接在主控板的地。如果远程测点在压缩机腔体,线束最好避开压缩机启动线,实在避不开,就在靠近传感器一侧加RC滤波,这步非常有效。
ESD防护也不能省。整机做静电放电测试时,从远程引线上直接灌进来的干扰很容易把传感器打坏。我给远程通道串了1kΩ电阻加TVS管,TVS管结电容不要太大,否则影响信号建立时间。电源引脚当然照例放0.1µF去耦电容,位置靠近芯片电源脚。
4.2 安装工艺与两点校正
传感器本身精度足够,但远程测温点能不能测准,很大程度取决于探头和被测表面的热接触。排气管测温时,用卡箍或者铝箔胶带把三极管封装部位压紧在管壁,涂抹导热硅脂填满缝隙。铝箔胶带不要缠太厚,铝箔本身导热性能好,缠多了会形成保温层反而测不准。
出厂前最好做一次两点校正:0°C冰水混合物、60°C恒温槽,整机通电读取本地和远程温度的误差,把偏移量存在MCU的Flash用户区,软件读取温度后加修正。这一步能消掉传感器个体差异、安装应力和引线电阻引起的系统性偏差。
4.3 告警逻辑与看门狗
PJ85718DM 有ALERT引脚,可以配置成温度越限中断输出。我把ALERT接到STM32F042C6的一个EXTI引脚上,配合主循环里的周期查询,双保险保证告警不漏报。远程温度超过压缩机允许上限时,主控要能快速停机或者降频,这个动作不能依赖主机通信链路,必须由本机直接控制输出继电器。
主控侧跑一个独立看门狗,喂狗任务里把I2C总线状态检查带上。如果I2C读传感器连续10次失败,先尝试总线恢复,恢复不了就置故障标志,上传报警。不能因为温度采集异常就直接关压缩机,否则故障树会非常难查。
4.4 生产测试要点
批量生产时,人工拿万用表量测点温度显然不现实。我在产线测试工装上做了一套小流程:工装板同时接触本地和远程测点,给被测板供电,通过UART发送测试帧,读取PJ85718DM的寄存器值,比对是否符合标定温度范围。全程不需要拆壳,一台设备十几秒测完一个板卡。
测试项里一定要包含I2C通信完整性。写一个来回读测试:往配置寄存器写入测试值再读回,确认传感器I2C通信不是“能上电但无法写入状态”。我一共碰到过两次芯片I2C读正常但写不了,都是虚焊导致SCL/SDA接触电阻偏大的疑难杂症。
5. 常见问题排查与调试记录
5.1 I2C读不到传感器数据
排查顺序如下:先量SDA/SCL静态电平,正常应该都是上拉高。如果有一根被拉低,看是不是从机地址配置错误或者芯片没供电。再用示波器看通信波形,抓一下START条件后有没有ACK位。如果主机一直收不到ACK,基本是地址不对、总线电容太大导致低电平拉不深、或者芯片地址引脚虚焊。
我在现场还遇到过一次特殊故障:整机上电后I2C死活不通,量波形发现SCL时序正常,但SDA上有毛刺,最后发现是远程屏蔽线距离时钟线太近,串扰进了数据线。改成双绞屏蔽线并且屏蔽层接地后,问题消失。
5.2 远程温度读数异常漂移
远程温度读出来比实际高十几度或者跳变,先检查三极管极性是否接反,再核对RC滤波参数。PN结测温对激励电流很敏感,串联电阻太大时远端电压建立时间变长,I2C读取频率高的时候可能采到未稳定的中间值。
如果是长线传输,把采样频率降下来,或者开启单次转换模式,每次读取前等待转换完成中断。另外注意三极管型号不要随便换,手册给了β值下限要求,换成β过小的管子,误差会指数级放大。
5.3 多颗传感器地址冲突
I2C总线上挂了两颗PJ85718DM,只读到相同数据时,大概率是地址引脚配置重复。还有一种隐蔽情况:地址引脚悬空,芯片上电默认读取到浮空电平,不同批次表现不一致。解决办法是地址引脚直接接电源或地,不要依赖内部下拉。
如果总线上还有其他芯片,比如串口EEPROM地址正好重叠,干脆把传感器地址整体挪到另一个区间,或者换用地址可编程范围更大的兼容型号。
5.4 常见问题速查表
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| I2C总线死锁,SCL/SDA卡低 | 从机忙状态未释放 | 主机SCL翻转9次复位,重新初始化总线 |
| 本地温度偏高 | 芯片靠近发热器件 | PCB调整布局,增加通风 |
| 远程温度偏低且响应慢 | 热阻过大,导热硅脂缺失 | 重新安装探头,改善贴合 |
| 远程温度跳变 | 引线干扰 | 双绞屏蔽线,加RC滤波 |
| 写入配置后读取不对 | 保留位被覆盖 | 读-改-写方式操作配置寄存器 |
| 低温段误差大 | 未做两点校正 | 软件补偿偏移量 |
6. 最后再说一点个人体会
这套 PJ85718DM 加 STM32F042C6 的方案,我后来在多个项目里复用了同一套驱动和布局模板,效果一直很稳定。如果说有什么经验最值得分享,那就是不要把温度采集只当成“读寄存器”那么简单,安装工艺、线束防护、总线恢复策略这些东西,往往是整个系统交付后能不能省心的关键。每次遇到现场温度不准的反馈,十有八九不是芯片问题,而是探头的固定方式和走线路径出了问题。先在样机阶段把这些物理功夫做足,后面量产和运维都会轻松很多。