首页 / 资讯中心 / 文章详情

嵌入式HVAC双通道温度监测:PJ85718DM与STM32L021K4方案

嵌入式HVAC双通道温度监测:PJ85718DM与STM32L021K4方案 ★ FEATURED ARTICLE
做嵌入式的朋友应该都碰到过这种尴尬温度传感器明明就在手边读出来的却不是你想要的那个温度。特别是暖通空调这类环境控制板通常装在设备内部继电器、电源、甚至马达都在附近散发热量板载传感器测出来的其实是“机器自己的体温”而不是房间里、风管里真正需要控制的温度。这次要聊的方案就是围绕这个痛点展开用一颗 PJ85718DM 温度传感器搭配 STM32L021K4 低功耗 MCU在嵌入式和 HVAC 应用中同时把本地温度与远程温度监测起来一套系统解决两类问题。这个组合特别适合做智能温控器、风机盘管控制器、新风系统控制板、机房环境监测这类产品想低成本实现双通道温度采样的嵌入式开发者也能直接参考。整篇文章会从方案选型讲到 PCB 布局、固件实现、校准方法最后把实际操作中踩过的坑都列出来算是把“测温”这件事一次讲透。1. 场景拆解与方案选型为什么非要做“本地远程”双通道1.1 两种温度两个完全不同的用途先说说“本地温度”和“远程温度”在实际项目里的角色差异。本地温度指的是传感器芯片周围、也就是控制板本体上的温度。它最大的用途是设备保护和健康监测判断板子上的电压变换器是不是过热、继电器模块附近是不是已经到了绝缘材料的极限温度、整机散热风扇是否失效。如果控制板所在的环境异常升温程序可以提前降载或者报警避免设备烧毁。远程温度则是把传感器本体和测温点分开用一根导线把测温点“搬”到需要真正测量温度的位置。HVAC 系统里这个需求极其常见室内回风口的温度、风管内的送风温度、冷凝管的表面温度、距离控制板好几米远的房间平均温度……这些位置你不可能把整个控制板放过去只能拉一根测温线过去。一个很典型的风机盘管应用控制板装在吊顶内的机组里附近就是电动阀和变压器而真正需要显示的“空调房间温度”在墙上的操作面板或远处探头那里。如果像很多低成本方案那样用一颗板载 NTC 直接测读出来的温度跟房间实际温度的偏差能到四五度制冷制热就会来回折腾用户体验很糟糕。1.2 传感器选型对比NTC 方案输在哪很多朋友一说到测温就用 NTC 热敏电阻接 MCU 的 ADC简单便宜但在这个场景下它有几个硬伤校准成本高NTC 的阻值-温度曲线批次间差异不小只能靠分压电阻和查表或者出厂时逐台打点校准对批量生产不友好。远程不太靠谱NTC 走长线时线阻会直接叠加到分压里导线自身的温漂也混进来想要达到 ±0.5°C 级别的精度得用恒流源加四线制工程量立刻上去。ADC 资源占用12 位 ADC 本身才给到约 0.3°C 左右的量化步进想要更好分辨率就得过采样CPU 和电源都被拖累。相比之下用一颗带本地远程双通道的数字温度传感器就干净很多。我手里这颗 PJ85718DM 走的是 I2C/SMBus 接口本地通道自带温度采集远程通道接一颗普通小信号三极管靠测量二极管结压差来还原温度。远程测温端只需要两颗元件抗干扰能力、线性度和精度都比拉线 NTC 强一个档次。下面是几个常见测温方案的大致对比能看出适用范围方案典型精度远程测温能力抗噪声/走线距离成本量级开发工作量NTC ADC±1% 跨度非线性一般线阻影响大较弱最低查表校准数字传感器 二极管远程通道±1°C 以内可校准强差分式测量强可走数米双绞线中较低热电偶 冷端补偿±0.5°C 左右强需专用调理电路中高较高PT100 运放调理±0.2°C 级别强强高高1.3 为什么是 PJ85718DM STM32L021K4PJ85718DM 所在的双通道数字传感器家族普遍具备这些能力本地温度范围覆盖 -40°C 到 125°C远程通道也能覆盖类似区间分辨率能做到 0.0625°C 级别内部有可配置的转换频率和报警阈值ALERT 引脚可以直接接 MCU 外部中断超温了不用轮询、立刻能触发远程通道还带开路/短路检测探头线断了能直接报出来。这套特性对 HVAC 设备简直是量身定做的——本来就需要本地过热保护又需要远程精确控制。至于 STM32L021K4它是一颗 Cortex-M0 内核的超低功耗 MCU16KB Flash、2KB SRAM听起来资源不大但在这个项目里完全够用I2C 通信、GPIO 点灯、定时唤醒全部不到 2KB。它真正的价值在功耗——连接待机状态下微安级的电流配合间隔唤醒去读传感器整机用电池跑几个月没有任何压力。很多温控器产品是要挂电池或者依赖能量收集工作的这时候低功耗 MCU 就不是选择项而是必选项。另外这两颗芯片可以共用 3.3V 电源轨MCU 能在 1.65V 到 3.6V 工作I2C 电平不需要做转换硬件上省事不少。MCU 的 I2C 外设本身兼容 SMBus 时序跟这类传感器的通信协议能很好配合。2. 硬件设计实操接线、布局与远程二极管的学问2.1 最小系统与接口怎么连先搭最小系统。STM32L021K4 的供电脚就近放 0.1µF 和 1µF 去耦电容复位脚接标准的 RC 复位电路如果对时钟精度有要求接一颗 32.768kHz 低速晶振给 RTC系统时钟用内部 HSI 也就是够了——毕竟主要工作是每几秒读一次温度。I2C 使用 I2C1 的 SCL 和 SDA 引脚各接一颗 4.7kΩ 上拉电阻到 3.3V。这里有个细节低速低功耗设计里上拉可以加大到 10kΩ边沿会变缓但只要总线电容不大通信照样稳功耗还能再省一点。传感器这边VCC 同样加 0.1µF 陶瓷电容紧贴电源脚。ALERT 引脚接 MCU 的一个 GPIO并且配置成外部中断输入。在 HVAC 设备里这个引脚可以做两件事一是超温快速拦截不必等 I2C 轮询二是远程探头断线时立刻告警。总之别让 ALERT 悬空它便宜但是很好用。远程二极管建议用贴片的 MMBT3904 或 MMBT3906 这类小信号三极管把集电极和基极短接形成一个二极管。我习惯用 PNP 管MMBT3906压差方向和传感器的恒流源驱动配合比较常规。这个“二极管”就是远程测温探头它放在需要测温度的位置两根引线回到传感器输入端。2.2 远程二极管为什么能测温ΔVBE 原理很多第一次接触远程温度传感器的人会好奇一个二极管怎么就能测得准温度这里需要解释一下背后的原理理解了它后面排查问题会顺手很多。二极管的正向压降 VBE 和温度大致成线性关系大约每升高 1°C 电压下降 2mV 左右。但单纯测绝对压降是没法用的因为二极管自身的批次离散性会让同一个温度下电压差出几十毫伏换算成温度就是十几度的偏差而且绝对压降还受电流影响。所以传感器的做法是在两个不同的电流下测两次 VBE然后取差值 ΔVBE。根据 PN 结物理特性ΔVBE 正比于 T × n × ln(I1/I2)其中 T 是绝对温度n 是二极管的发射系数I1、I2 是两个已知的电流。电流比值固定、自然常数固定反推出来的温度基本不依赖二极管本身的绝对参数。这就是远程二极管测温能做得准的根本原因。温度读不准、读数飘多半不是芯片的问题而是破坏了 ΔVBE 测量条件比如引线串入电阻、外部噪声干扰、或者二极管选得不对后面排查部分会展开讲。2.3 PCB 布局布线的经验这部分是拿真金白银换来的教训上机实测过才算数。先说传感器本体布局不要把 PJ85718DM 放在功率器件正边上。本地通道读的是传感器自己周围温度如果把它凑着继电器或降压芯片放本地温度会比整板平均值高不少保护逻辑容易误动作。原则是放在主控附近、避开热源离强电区至少 5 到 10mm。远程二极管的走线要当作模拟信号对待。两个连接点最好走成差分线一路绕远路都比靠近继电器驱动线强。如果现场走线超过 30cm强烈建议用双绞线或者在二极管两端并联一颗 1nF 到 10nF 的滤波电容。这个电容不会影响直流工作点但对抑制射频噪声有明显作用。还有一个很多人忽略的点远程二极管走线上的串联电阻。线缆每增加 1Ω读数就可能偏高零点几度具体系数看芯片手册这是 ΔVBE 原理下无法完全消除的系统误差。能用粗一点的双绞线就尽量粗别为了省成本用细漆包线拉七八米。我实测过一段 0.2mm² 的普通电线拉 5 米读数能飘 1°C 以上后来换了双绞屏蔽线才好很多。3. 固件实现三步拿到稳定的温度值3.1 初始化流程与寄存器配置固件整体不复杂核心就是 I2C 读写几个寄存器。先把底层 I2C 初始化为 100kHz然后对传感器做初始化。不同厂家对于寄存器地址的定义会稍有区别具体偏移地址以下手册为准我这里用符号常量的方式写方便你移植时快速替换。#define PJ85718DM_ADDR (0x4C 1) /* 7位地址器件地址引脚决定 */ #define REG_CONFIG 0x01 #define REG_STATUS 0x02 #define REG_LOCAL_TEMP 0x05 #define REG_REMOTE_TEMP 0x07 static uint8_t temp_sensor_write(uint8_t reg, uint8_t val) { uint8_t buf[2] { reg, val }; return HAL_I2C_Master_Transmit(hi2c1, PJ85718DM_ADDR, buf, 2, 100); } uint8_t temp_sensor_init(void) { uint8_t cfg 0x00; /* 本地远程通道都使能分辨率设最高档转换速率适中 */ cfg | 0x00; /* 通道使能位按手册配置 */ cfg | 0x04; /* 转换频率示例值按手册核对 */ if (temp_sensor_write(REG_CONFIG, cfg) ! HAL_OK) { return 1; } return 0; }初始化之后最好读一次状态寄存器确认芯片应答正常再读一遍配置寄存器回读校验。这一步能避免上电时序异常导致的“寄存器写失败但主程序毫不知情”的陷阱。3.2 温度读取与负温度换算读温度就两行代码的事但换算要注意负温度。芯片输出的裸数据通常是二补码最高位为 1 表示负温如果直接把 int16_t 无符号往里塞再乘系数零下温度会变成巨大的正数在 HVAC 制冰蓄冷这类场景里会出大问题。typedef struct { float local; float remote; } temp_result_t; static int16_t temp_sensor_read_reg16(uint8_t reg) { uint8_t buf[2]; HAL_I2C_Master_Transmit(hi2c1, PJ85718DM_ADDR, reg, 1, 100); HAL_I2C_Master_Receive(hi2c1, PJ85718DM_ADDR, buf, 2, 100); return (int16_t)((buf[0] 8) | buf[1]); } uint8_t temp_sensor_read(temp_result_t *out) { int16_t raw_local, raw_remote; raw_local temp_sensor_read_reg16(REG_LOCAL_TEMP); raw_remote temp_sensor_read_reg16(REG_REMOTE_TEMP); /* 12位分辨率时 LSB 为 0.0625°C14位时换算系数不同看手册 */ out-local raw_local * 0.0625f; out-remote raw_remote * 0.0625f; return 0; }我建议每次读完后先看状态寄存器的远程通道开路/短路标志。如果远程探头断线或者短路芯片通常会给出上限或下限的饱和值比如 -128°C 或 127°C这时候千万别让这个值进控制逻辑宁可把上一次有效值保持住或者直接进入故障处理分支。3.3 低功耗采样策略这个项目真正区别于普通单片机测温的地方在于 STM32L021K4 低功耗模式的运用。因为传感器本身在持续转换MCU 完全没必要一直跑着等数据。我的做法是主循环让 MCU 进 STOP 模式用 RTC 闹钟周期性唤醒醒来读一次温度处理完继续睡。void temp_loop(void) { temp_result_t t; temp_sensor_read(t); process_hvac_control(t); /* 控制逻辑比较阈值、驱动继电器等 */ enter_stop_mode(); /* 进入 STOP等 RTC 唤醒 */ }处理器进入 STOP 模式前记得先把传感器也配置成合适的转换速率。有些双通道传感器默认连续转换功耗有几百微安对电池设备来说太高了。把转换降低到每 2 秒一次或者用 ALERT 引脚的超温中断配合让 MCU 只在真正需要处理的时候才醒过来整机平均功耗就能压到很低的水平。我实测过一个 3.7V 锂电池供电的样机平均电流能控制在 50µA 以内连续待机几个月没有压力。4. 校准与可靠性处理让误差从“能看”变成“能信”4.1 远程通道的误差来源数字传感器出厂时做过工厂校准本地通道通常精度不错但远程通道整体误差会大一些原因不在芯片而在于外部二极管和线缆。主要有三个误差来源二极管的发射系数 n传感器内部假设的是典型值比如 n≈1.008 或 1.004不同厂家、不同批次的三极管会有差异这个差异直接乘到 ΔVBE 里。最好的解决办法是选芯片手册推荐型号的管子别频繁换料。串联电阻走线和管子内部的串联电阻会叠加到 VBE 测量里产生近似线性的偏移。有些高端传感器支持串联电阻抵消功能开启后能自动修正一部分。温度梯度引起的附加误差如果探头和芯片之间有温差测到的自然是对应的折中值这不算错误但应用中要清楚测的是哪个点。4.2 我的两点校准实操流程我做过几轮 HVAC 项目经验是不用追求什么高深算法两点线性校准在 -10°C 到 60°C 这个温控常见区间内已经能把误差压到很理想。流程很简单把探头和整机放在 0°C 冰水混合液里稳定 10 分钟后记录本地和远程读数算出偏移量 1。放到 50°C 恒温箱或者用桶装温水加搅拌棒稳定控温记录第二个点算出偏移量 2。把两组偏差做成线性修正公式在固件里乘一个斜率、加一个偏置。float temp_calibrated(float raw_temp) { /* 以两点标定为例K 为斜率修正B 为偏置修正 */ return raw_temp * cal_k cal_b; }需要特别提醒远程探头和本地通道要分开校准因为二者的误差来源完全不同。校准时的参考温度计也要用经过溯源的别拿了个洗衣机温度计就当标准器那整个标定链条就全废了。4.3 滤波去毛刺与控制逻辑的结合实测环境中尤其是 HVAC 设备里继电器和压缩机频繁动作远程探头连线会收到空间耦合噪声单次读数偶尔会跳一个很大的值。我在固件里做了两层防护第一层是中值滤波。连续采 5 个点取中间值能有效干掉单点毛刺又不会像均值滤波那样把真实温度变化拉平。中值滤波在数组里用简单的冒泡排序就够不需要引入复杂算法。第二层是变化率限幅。HVAC 房间温度变化率一般不会超过每分钟 1°C如果相邻两次有效读数差了 5°C 以上基本可以判断是干扰或者异常直接沿用上一拍的值。这两层下来我见过最恶劣的继电器切换干扰场景也能稳住读数。再往上层说控制逻辑里还要加滞回区间。比如设定 25°C 制冷别在 24.9°C 和 25.0°C 之间反复切换继电器至少要留 ±0.5°C 的滞回死区这既保护继电器触点也让房间温度波动更平缓。测温准只是第一步控制稳才算真正把项目做完整。5. 常见问题与排查技巧实录5.1 I2C 读不到设备或地址错误这是玩 I2C 最常遇到的问题。先用总线扫描工具把挂在总线上的器件地址扫一遍确认实际地址和代码里写的是否一致。很多双通道传感器有地址引脚通过接高、接低甚至接 SCL/SDA 来切换地址上拉电阻没焊、地址脚悬空导致编译地址与实际地址对不上这类问题我见过不止一次。排查顺序建议先量 SCL/SDA 静态电平是否被上拉到高再用示波器看通信时有没有 ACK 应答波形最后检查传感器供电和去耦电容——芯片如果供电纹波大I2C 时序可能变得异常。5.2 远程温度显示 -128°C 或 127°C这两个值大概率不是真实温度而是远程通道的开路/短路指示。开路时读数会跳向高端饱和短路时跳向低端饱和。先查探头接线再看方向对不对最后用万用表二极管档量一下 MMBT3904 的两个引脚确认 PN 结压降在 0.5V 左右。我之前就碰到过贴片三极管焊反方向的低级错误片子一焊反读数直接飞了。5.3 低功耗下整机电流比预期大得多MCU 明明睡了电池还是掉得很快基本都要查两个点。第一传感器的转换频率是不是还在最高档这是个大电流源第二I2C 总线上拉电阻直通供电总线不活跃时候选电阻本身在耗电这种情况下把上拉电阻换成 10kΩ、或改成软件控制的 GPIO 上拉能省一笔。另外 GPIO 悬空输入也会产生漏电所有未使用的引脚都要配置成模拟输入或输出低。5.4 继电器一动作读数就跳变HVAC 设备里继电器吸合瞬间的电流冲击会在远程探头的长线上感应出很强的共模干扰。解决办法按优先级排列先给探头线加双绞和屏蔽层屏蔽层单端接地再在二极管两端并一个 1nF 电容固件里打开中值滤波和变化率限幅。三轮下来基本能把跳变压到看不出来。现象最可能的原因首选处理方式I2C 无 ACK地址或接线问题扫描总线、查地址引脚配置远程温度显示饱和值探头开路/短路用万用表量 PN 结整机静态电流偏高传感器高速转换、上拉电阻过大功耗降低转换速率、换大阻值上拉继电器动作读数跳变远端探头受干扰双绞线屏蔽滤波电容本地温度明显偏高传感器离功率器件太近调整布局位置、远离热源5.5 校准点对不上如果标定时发现偏差不是固定值、而是随温度变大变小说明斜率本身不对多半是远程二极管型号选错或批次差异大需要替换成手册推荐型号并重新标定。如果是固定偏移基本就是串联电阻或焊点接触电阻造成的逐点检查线缆接头和插座镀层就能看出一二。我在实际项目里还有一个习惯就是把出厂标定的参数直接写进 Flash 保留区上电时再读出来。这样生产线上一次性校准后面的固件升级也不会把校准数据冲掉批量出货时省事很多。这个方案做完之后我把它用在了一台风机盘管温控器的改版上原来最头疼的回风温度偏差问题基本消失整机待机功耗也压到了可以接受的范围。如果你正在做类似的温控项目建议先从给板子加一路“引出去能测准”的温度入手体验完远程二极管测温的省心程度多半就回不去拉线 NTC 的老路了。
阅读完成 · 觉得有帮助?
咨询建站