做嵌入式测控这几年,我最大的感受是:温度监测看着是基础功能,但真要把“本地板温”和“远端传感器点温度”同时做到稳定、准确、可远程读取,坑远比想象中多。最近在搞一套冷水机组控制器,主控用了STM32F429ZI,温度采集端选了PJ85718DM这颗支持单总线式本地加远程双通道测温的I2C芯片。整套方案做完,从硬件设计到软件滤波,再到现场标定,踩了不少跟头,也沉淀了一些可以直接复用的实操经验。这篇我把整个项目的设计思路、硬件要点、驱动实现和HVAC场景下的调试验证过程完整梳理出来,给正在做类似嵌入式测温项目的朋友做个参考。
1. 项目整体设计与核心思路拆解
1.1 为什么需要本地与远程双通道测温
很多设备在测温方案上有个误区,以为放一个NTC热敏电阻在PCB板上就完事了。但在嵌入式和HVAC这类场景里,真正需要监测的温度点往往有两类,而且要同时关心。
一类是板级温度,也就是主控芯片、功率器件附近的温度。这类温度直接决定了系统是否过热降频、是否触发保护。另一类是远端工况温度,比如空调系统的回风温度、冷水机组管道表面温度、压缩机电机绕组温度等。远端温度点通常离主控板有几厘米甚至几米的距离,如果用NTC去测,需要额外的恒流源、放大电路和ADC通道,而且线径带来的电阻误差和屏蔽问题会让人非常头疼。
PJ85718DM这种同时具备“本地测温”和“远程测温”能力的传感器IC,解决的就是这个痛点。它内部自带的本地温度传感器测芯片自身温度,也就是PCB板温;同时它还有一个远程PN结测量通道,通过两根线接到外部一个普通二极管或者三极管上,就能测那个PN结所在位置的温度。等于一颗芯片解决了两个测温需求,而且远程测量原理基于PN结正向压降的温度特性,线长带来的串联电阻影响可以被补偿,比NTC方案稳定太多。
回到HVAC这个具体场景。冷水机组中,控制板内部的开关电源、继电器和驱动电路发热很大,板温必须监控;而压缩机绕组、冷凝器管壁上的温度点,是判断系统运行是否正常的核心参数。一套系统里同时出现这两种需求太常见了,所以PJ85718DM这类双通道芯片选得就很有针对性。
1.2 PJ85718DM与STM32F429ZI的选型逻辑
接下来说说主控和传感器搭配上的考量。
先看传感器。PJ85718DM是I2C接口的数字温度传感器,本地通道精度能做到±0.5°C左右,远程通道在合适的PNJ校准和走线条件下也能做到±1°C以内,这个精度对HVAC控制策略来说完全够用。它支持可编程的转换分辨率、阈值报警和ALERT引脚,这些是工业测控场景的基本盘。它的I2C地址可以通过引脚配置,一条总线上可以挂多颗芯片,扩展起来很顺手。
还有一个很关键的点是功耗。PJ85718DM支持单次转换模式和低功耗监测模式,在电池供电的嵌入式设备里很有优势,测温不是每一毫秒都要取数的,定时唤醒读一次就够了。
再看主控STM32F429ZI。这颗芯片在F4系列里属于性价比很高的型号,Cortex-M4内核,带FPU和DSP指令,180MHz主频。做HVAC控制器往往要同时处理温度采集、风扇PWM控制、通讯协议、人机交互几件事,M4的性能余量足够用。而且它有多个I2C外设、丰富的GPIO和定时器,扩展性和资源规划都非常从容。
我觉得这套组合还有一个隐性优势。PJ85718DM负责把模拟测温问题直接转成数字I2C通信问题,STM32F429ZI的I2C外设成熟稳定,再加上它足够大的Flash空间能存历史温度曲线、标定参数和升级固件,整个项目的软硬件边界非常清楚,调试时不会出现“不知道温度误差是硬件还是软件造成的”这种混沌局面。
1.3 远程PN结测温原理与误差边界
远程通道的原理值得单独说一下。二极管或三极管的PN结,在正向偏置电流恒定的情况下,正向压降会随温度变化,大概是-2mV/°C左右。如果只用单点压降测温度,工艺差异造成的绝对压降偏差会直接变成温度误差,根本没有一致性可言。
所以现在的远程温度传感器普遍采用Delta-VBE测量法,也就是用两个不同大小的正向电流分别驱动同一个PN结,测量两次压降的差值。这个差值和温度之间有着非常好的线性关系,而且能抵消掉PN结本身的绝对压降工艺误差,精度就能做上去。
PJ85718DM内部就是干这个活的,它会轮流给外接PN结施加高低两档电流,算出VBE差值后映射到温度。外部传感器可以是一个普通的二极管,也可以是一个三极管。工程上常用三极管的基极-集电极短接方式,形成一个近似二极管的PN结,这样测温的灵敏度和一致性会比普通整流二极管更好。
但这里有个必须注意的误差边界,就是远程传感器的线缆电阻和漏电流。线缆串联电阻会影响电流源的精确度,好在很多远程温度芯片内部有串联电阻补偿机制,PJ85718DM这类器件一般都会做,允许一定范围内的线缆电阻。不过接插件氧化、湿气侵入造成的高压漏电,是远程测温稳定性的头号杀手,比线缆电阻更隐蔽,现场排查时要优先怀疑这些点。
2. 硬件连接与关键参数配置
2.1 I2C接口与上拉电阻选型
PJ85718DM的I2C接口是标准的两线制,SCL和SDA。STM32F429ZI这边用I2C1或者任意空闲的I2C外设都可以。硬件上需要特别注意两个地方,一是上拉电阻,二是电平匹配。
STM32F429ZI的IO电压是3.3V,PJ85718DM的工作电压通常也支持2.7V到5.5V,为了省去电平转换,我直接把两者都跑在3.3V上。I2C总线是开漏结构,必须接外部上拉电阻才能拉高电平。上拉电阻的阻值选择跟总线电容、通信速率都有关系,标准模式100kHz下,4.7kΩ是常见值;如果总线上的器件比较多,或者线比较长,要适当减小到2.2kΩ甚至1.5kΩ来保证上升沿够快。
我这次用的上拉电阻是3.3kΩ,总线上挂了两个PJ85718DM和一颗温湿度传感器,时钟频率是400kHz的高速模式,示波器实测上升沿没有明显畸变,通信完全稳定。如果发现I2C偶发NACK或者数据错位,可以先量SCL/SDA上升沿是不是太缓,太缓就减小上拉阻值。
另外,I2C从机地址冲突问题很容易被忽略。PJ85718DM一般会提供地址配置引脚,把该引脚拉高拉低就能切换地址。设计硬件时一定要留好跳线或者焊盘选项,不然现场要挂多个传感器时会非常被动。
2.2 远端PN结传感器的选型与接法
PJ85718DM的远程通道需要外接一个PN结。温度探头自己做还是直接买现成的,取决于项目预算和精度要求。
对于暖通空调场景,我建议优先选用三极管接成二极管形式,比如常见的2N3904这类小信号三极管。接法是把基极和集电极短接在一起,当成二极管的阳极,接到PJ85718DM的D+引脚;发射极作为阴极,接到D-引脚。基极和集电极短接能保证电流主要流过基极-发射极结,而这个结的温度特性是器件手册里给得最准的,测量一致性比较好。
如果你用手头现有的1N4148等普通开关二极管也可以,但要注意两点。首先,二极管型号要固定,不同型号的PN结面积和漏电流特性差异很大,定型后不要随意更换。其次,二极管引脚是有极性的,反接的话远程通道读数会直接变成一个几伏的异常值,在软件里表现为非常离谱的温度或者固定跳变,根本不用怀疑是芯片坏了。
远程传感器和主控板之间的接线也讲究。距离近的话用普通的双绞线就行,距离超过半米或者现场有变频器、继电器这类干扰源,我建议用屏蔽双绞线,屏蔽层单端接地,避免形成地环路。传感器探头那端最好做灌封处理,防水防潮。HVAC环境里冷凝水非常常见,远程测温点进水后漏电流会直接毁掉测量数据,这一点比电磁干扰更致命。
2.3 抗干扰与防护措施的工程取舍
HVAC设备现场的电磁环境其实挺恶劣的。压缩机变频器启动时,几十安培的电流切换会在空间里制造很强的电磁干扰。如果PJ85718DM的I2C线或者D+/D-走线没有防护,温度数据跳变、通信假死都是常见现象。
我在这块的处理策略是区分对待。I2C总线是板级的,布线距离不超过10cm,所以着重做好电源去耦和板内布局就行。PJ85718DM的VDD引脚附近要放一个100nF的陶瓷电容,最好再并一个1uF到10uF的胆电容或者陶瓷电容,用来吸收电源线上的高频纹波。如果板子上有继电器或者大电流绕组,传感器附近的地平面要尽量完整,别把温度传感器塞进开关电源的环路里。
D+/D-远程测量线是跨出板外的,风险更高,需要做滤波。PJ85718DM这类器件的数据手册通常会给出推荐的RC滤波电路,一般是在D+/D-上串入小阻值电阻,再在靠近芯片端对地并一个电容,形成一个低通滤波器。这样做能有效滤掉高频共模干扰,避免干扰被内部ADC采样后变成毛刺。
但要注意,在D+/D-上加电容会延长远端PN结的充放电时间,如果电容值太大,测量精度反而会下降。我一般是先按手册推荐值起步,比如串联电阻取2.2kΩ左右,对地电容取1000pF级别,然后在实际电路上对比加滤波前后的读数稳定度,逐步微调。
3. 嵌入式软件实现
3.1 寄存器结构与配置流程
PJ85718DM的操作方式很标准,就是写配置寄存器、读温度寄存器、处理状态位。虽然具体寄存器地址和位定义要查芯片手册,但架构上大同小异,核心配置流程可以抽象成下面几步。
第一步是复位和基本配置。上电后先延时几十毫秒,等内部电路稳定,然后写入配置寄存器,设置测量分辨率、转换速率、远程通道滤波开关等关键参数。
第二步是设置报警阈值。PJ85718DM支持高温报警、低温报警等阈值寄存器,超限后通过ALERT引脚拉低来通知主控。阈值寄存器的格式跟温度寄存器一样,都是带符号数,写入前要算好。
第三步是启动转换并等待数据就绪。可以工作在连续转换模式,也可以工作在单次转换模式。HVAC控制器一般用连续转换就行,单次转换主要用于电池供电的便携设备。
第四步是读温度数据。本地和远程温度各占两字节寄存器,读完拼成12位或13位有符号数,再乘以对应的LSB权重就能换算成摄氏度。
下面是我整理的一个初始化流程图思路,用文字表达就是:写配置寄存器,写阈值,读状态寄存器确认无异常,进入主循环周期读取。代码实现上,这些读写操作全封装成底层I2C读写函数,上层业务逻辑调用起来非常干净。
#define PJ85_I2C_ADDR 0x48 // 具体地址看A0/A1引脚配置 #define REG_LOCAL_TEMP_H 0x00 #define REG_LOCAL_TEMP_L 0x01 #define REG_REMOTE_TEMP_H 0x02 #define REG_REMOTE_TEMP_L 0x03 #define REG_STATUS 0x04 #define REG_CONFIG 0x05 #define REG_LOCAL_HIGH_LIMIT 0x06 #define REG_LOCAL_LOW_LIMIT 0x07 #define REG_REMOTE_HIGH_LIMIT 0x08 #define REG_REMOTE_LOW_LIMIT 0x09 #define CONFIG_CONTINUOUS 0x00 // 连续转换 #define CONFIG_SINGLE 0x20 // 单次转换,占位示例 #define CONFIG_FILTER_ON 0x04 // 远程滤波器使能3.2 I2C驱动与温度读取函数
STM32F429ZI的I2C驱动,我习惯直接用HAL库把底层打通,业务层自己写状态机。如果你对I2C时序要求比较苛刻,也可以用LL库甚至寄存器操作,但HAL库在多数工业项目里够用且易维护。
第一个基础函数是写入寄存器。PJ85718DM支持写单个寄存器,流程是发出起始信号、发送从机地址加写位、发送寄存器地址、发送数据字节、停止信号。HAL库封装了现成的写函数。
static HAL_StatusTypeDef pj85_write_reg(uint8_t reg, uint8_t data) { uint8_t buf[2]; buf[0] = reg; buf[1] = data; return HAL_I2C_Master_Transmit(&hi2c1, PJ85_I2C_ADDR, buf, 2, 100); }第二个基础函数是读取多字节数据。温度寄存器都是连续地址,可以一次性读回多个字节,减少总线通信量。
static HAL_StatusTypeDef pj85_read_regs(uint8_t reg, uint8_t *buf, uint8_t len) { HAL_StatusTypeDef ret; ret = HAL_I2C_Master_Transmit(&hi2c1, PJ85_I2C_ADDR, ®, 1, 100); if (ret != HAL_OK) return ret; return HAL_I2C_Master_Receive(&hi2c1, PJ85_I2C_ADDR, buf, len, 100); }接下来是核心的温度数据解析。PJ85718DM的温度值是12位或13位有符号数,高字节的符号位扩展要注意。假设LSB是0.0625度,那么本地温度的值等于高字节左移8位后、加上低字节,再把整体当作有符号16位数处理。
#define TEMP_LSB_WEIGHT 0.0625f static float pj85_parse_temp(int16_t raw) { return (float)raw * TEMP_LSB_WEIGHT; } int16_t pj85_read_raw_local(void) { uint8_t buf[2]; int16_t raw; if (pj85_read_regs(REG_LOCAL_TEMP_H, buf, 2) != HAL_OK) { return 0x8000; // 读失败标志 } raw = ((int16_t)buf[0]) << 8; raw |= buf[1]; return raw; } int16_t pj85_read_raw_remote(void) { uint8_t buf[2]; int16_t raw; if (pj85_read_regs(REG_REMOTE_TEMP_H, buf, 2) != HAL_OK) { return 0x8000; } raw = ((int16_t)buf[0]) << 8; raw |= buf[1]; return raw; }有个非常容易踩的坑是符号位处理。温度低于0度时,比如-0.25度,高字节是0xFF,低字节是0xFC。如果把高字节强转成uint8_t再拼接,最后得到的是一个非常大的正数,算出来的温度就是天差地别。正确做法是把高字节先转成int16_t再左移,C语言里有符号整型的移位和符号扩展行为要心里有数。
3.3 数据处理、滤波与报警逻辑
裸读寄存器拿到的温度值虽然能用,但现场干扰和测量噪声会让数据抖动。HVAC控制逻辑如果直接用抖动的温度做PID或者保护判断,会很头痛。所以我在软件层做了两级处理。
第一级是中值滤波。连续采5个原始值,排序后取中间3个的平均,能有效剔除偶发的尖峰脉冲。尤其当现场偶尔有变频器谐波干扰,中值滤波最管用。
第二级是滑动平均。在已做中值处理的数据上,维护一个长度为4或者8的滑动窗口,每次取窗口平均值作为最终输出。中值负责去毛刺,滑动平均负责平滑趋势,组合起来效果很好。
还要注意报警逻辑不要直接拿平滑后的温度跟阈值死比较。HVAC设备启动瞬间、风机切换、压缩机停机再启动,温度本来就会剧烈波动,容易误触发报警。我建议报警判定带滞回,也就是超过高温阈值后,必须回落到阈值减去1度或者2度才撤销报警。滞回量应该根据系统热惯量调,太大会导致真实超温报警延迟,太小又压不住抖动。
阈值寄存器也要同步更新。PJ85718DM内部有ALERT引脚,可以把报警判断下沉到传感器芯片上,主控在阈值触发瞬间收到外部中断,响应更及时,也能减少轮询压力和总线流量。
3.4 低功耗与运行策略
如果你的设备包含电池供电或者对待机功耗有严格要求,PJ85718DM的低功耗玩法要熟练。上面提到的单次转换模式是首选。
单次转换的思路是:平时传感器处于待机状态,电流消耗极低;主控需要温度时,写一个启动转换的控制位,等待转换完成,读取结果,然后让它重新休眠。这样平均电流就能压缩到非常低。
STM32F429ZI侧的轮询策略也要配合调整。不建议用while循环死等转换完成,那样CPU时间全浪费了。更合理的做法是启动转换后,让MCU进入低功耗模式或者去处理其他任务,通过定时器或者PJ85718DM的ALERT中断来唤醒读取。
我实际项目里是500ms做一次完整读取,包括本地通道和远程通道,然后运行中值加滑动平均。控制周期100ms的系统用这份500ms的温度数据做控制也完全够。如果哪天要提升到200ms读一次,把连续转换模式打开,配合DMA读I2C,实时性还会更强。
4. HVAC场景化适配与调试经验
4.1 传感器安装位置的选择标准
HVAC系统的温度监测点怎么选,直接影响系统控制效果。我的经验是“温度测点要代表对象真实状态,不能只图安装方便”。
板级本地温度,也就是PJ85718DM本身感知的温度,应该放在PCB上离主要发热源不远但不直接接触的位置。比如变频驱动板上的功率管附近,或者主控板上电源模块旁边。太远了测不到热异常,太近了又会被局部热点带偏,无法代表整板状态。
远程温度点就要根据HVAC设备的物理结构随着管路走。冷水机组的冷冻水供水回水温度,是判断制冷量的核心变量。测点要贴近管壁,并做好保温棉包扎,让传感器探头和管壁充分接触,避免受环境空气温度干扰。如果测的是压缩机表面温度或者电机绕组温度,探头要卡在绕组端部,而不是外壳上,否则滞后会很严重。
传感器探头的固定方式,我建议用金属卡箍加导热硅脂的工艺。导热硅脂可以减少探头和被测面的接触热阻,卡箍保证固定可靠,不会因为设备振动移位。这一点很多人忽略,接触不良的话远程温度读数凭空偏好几度,而且时好时坏。
4.2 系统标定与误差补偿
PJ85718DM出厂精度虽然不差,但实际系统的误差来源不只在芯片本身,还有探头接触热阻、线缆电阻、ADC参考电压偏差等。因此上电的第一件事不是写死阈值,而是做系统级标定。
标定流程一般是准备一个恒温槽或者标准的精密温度计。把远程探头放进恒温槽,设置两个或三个标定点,比如0度、25度、50度。记录PJ85718DM的读数和标准值之间的偏差,看偏差是不是线性。
如果偏差基本恒定,就在软件里加一个偏置补偿值,一次性调平。
float pj85_get_remote_temp_compensated(float raw_temp) { // offset 通过标定得到,例如0.5度 const float offset = 0.5f; return raw_temp + offset; }如果偏差跟温度相关,是近似线性的斜率误差,就要做两点标定,算出增益和偏置,用线性映射来校正。HVAC现场温度跨度可能从零下到七八十度,还是建议至少取两点,跨度大一点,线性校正的效果才能真正体现。
另外,PJ85718DM远程通道的测量结果会受到远端PNJ型号的影响。如果标定后发现远程通道的绝对偏差比较稳定,可以直接把它当作系统偏差处理,不用换器件型号,这是省事的路子。
4.3 多节点轮询与总线规划
一台HVAC控制器往往不止测一个点。冷水机组至少要测回水温度、出水温度、压缩机油温、电机绕组温度,可能还要测冷凝压力对应的饱和温度。PJ85718DM的本地加远程结构一颗只能管两个点,多测点就要多挂芯片。
多芯片挂在同一条I2C总线上时,需要规划好地址。每个PJ85718DM的地址引脚要错开,然后主控侧建立一个温度传感器节点表,把器件的I2C地址和它对应的物理位置绑定起来。
typedef struct { uint8_t i2c_addr; char location[16]; float temp_local; float temp_remote; uint16_t fault_flags; } pj85_node_t; pj85_node_t temp_nodes[] = { { 0x48, "CONTROL_BOARD", 0.0f, 0.0f, 0 }, { 0x4A, "CHILL_WATER_IN", 0.0f, 0.0f, 0 }, { 0x4C, "CHILL_WATER_OUT", 0.0f, 0.0f, 0 }, { 0x4E, "COMP_WINDING", 0.0f, 0.0f, 0 }, { 0x50, "OIL_TEMP", 0.0f, 0.0f, 0 }, };轮询时每颗芯片先读本地温度再读远程温度,500ms一个周期。如果发现某颗芯片连续N次通信失败,不能让它影响整个总线的巡检,要在软件里对它做故障隔离,暂时跳过,同时记录故障状态,方便远程诊断。
5. 常见问题与排查技巧实录
5.1 异常读数的根因定位
项目调试和现场运行中,温度数据异常是最常见的问题。经验多了之后,基本能凭读数特征快速缩小范围。
远程通道读数固定为0或者一个很小的负值,比如-64度,大概率是D+/D-之间短路了,或者传感器接反了。如果读数是接近某个负的满量程值,比如-128度,可能是D+/D-开路,芯片内部ADC采样不到电流回路,就会落到标志性的错误码区间。
还有一种很隐蔽的情况,就是读到的温度和实际温度变化趋势一致但整体偏差很大。这时候先别怀疑芯片精度,而是去检查探头是不是没有跟被测物贴合好,或者探头处的水汽凝结改变了导热路径。
本地通道异常反而更好查。如果PJ85自身温度读出来比万用表量的板温高好几度,看看芯片旁边是不是有发热元件贴着,或者板子是不是放在封闭环境里。PJ85自身会有一点自热,但正常情况下只有零点几度到一度左右,如果偏高太多,就要检查供电电压是不是异常,或者I2C通信频率太高导致芯片一直处于高活跃状态。
5.2 现场干扰与误报警处理
现场最折腾的问题不是温度不准,而是温度偶发跳变,然后触发热保护停机。客户报障说“设备没看温度多高,就是莫名其妙报警了”,多半是这个原因。
排查时先用示波器挂上D+/D-和I2C时钟线,看看报警时刻点上有没有明显的毛刺耦合进去。HVAC现场变频器一运行,开关噪声非常容易通过空间耦合进远程测温线。
短期处理是把PJ85718DM的内部远程滤波器打开,同时在外部D+/D-上补上RC滤波,把高端噪声滤掉。
中期处理是检查探头的屏蔽层接地。屏蔽层如果两端接地,会造成地环路电流,反而引入更大噪声;正确做法是单端接地,而且接在控制器的模拟地上。
长期处理是调整报警阈值和滞回量。温度保护不是零延时响应,对于热惯性大的风冷系统,允许温度短时间越过阈值1度甚至2度是合理的。这不是降低保护标准,而是避免因为噪声导致的误保护停机,让系统长期可靠运行。
5.3 远程传感器故障快速诊断
远程传感器在现场是消耗品,机械振动、接线端子松动、进水都有可能让它失效。我总结了一套快速诊断流程,谁去现场都能照着查。
先看读数卡在哪一个状态。如果读数是明显的错误码,用数字万用表直接量传感器插头两端的二极管压降。一个好的PN结在正向偏置时,压降大概是0.3伏到0.7伏,反向应该是高阻。量出来是0欧姆或者开路,那不用说了,换探头。
如果二极管压降正常,再量一下线缆两端是否导通。很多故障出在接插件根部,线芯看着没断,其实内部已经氧化或者疲劳暗断了。量的时候要拽一拽线,模拟设备振动时的状态。
最后还要核算线缆电阻。远程测温线太长、太细,线缆电阻过高会导致电流源无法建立正常的偏置,读数漂移。PJ85718DM虽然有串联电阻补偿功能,但补偿范围有限。超过手册标称值就老老实实用更粗的线,或者把传感器信号先转成4-20mA的变送器再进控制器,物理机制变了,问题就不是一个量级了。
写在最后的几点体会
这个项目让我对温度监测有了几个新的认识。
第一,温度和控制的耦合比想象中深。同一套硬件,滤波参数和报警滞回调得好不好,直接决定现场是否频繁误报警。软件上多花点时间做数据平滑和故障隔离,远比在硬件上堆料的性价比高。
第二,标定流程不能省。HVAC设备运行环境温度跨度大,不做系统级标定,误差就容易超过控制策略的设计余量。有条件的话,每一批控制板出厂前都跑一遍恒温槽标定,把补偿值写进固件或者存到Flash里。
第三,现场可维护性从硬件设计开始就要考虑。传感器接口做成可插拔的,线缆用统一颜色标识,PCB上把传感器通道的测试点留出来,这些细节能让后端的售后排查快很多。搞嵌入式的人常常只顾着把功能调通,忽视了这些长期运维成本,等现场出现问题再远程指挥排障,就知道有多被动了。
这套基于PJ85718DM和STM32F429ZI的双通道测温方案,从我这边跑下来的结果看,本地和远程通道的精度、稳定性、抗干扰能力都能支撑HVAC行业的批量应用。如果你也正准备在嵌入式设备里加入温度监测功能,可以按我这个思路先搭一套硬件板,然后照着软件的滤波逻辑和标定流程走一遍,应该能少踩不少坑。