ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于PJ85718DM与STM32F412RE的远程温度采集方案

基于PJ85718DM与STM32F412RE的远程温度采集方案 1. 从一个温度采集需求说起为什么选 PJ85718DM 配 STM32F412RE嵌入式温度监测这个方向看起来简单真做起来坑不少。我接触过好几个 HVAC暖通空调相关的项目从商用楼宇的空调控制面板到工业机柜的环境监控温度采集几乎是最基础也最容易出问题的环节。基础是因为原理简单——读传感器、算温度、传数据容易出问题是因为一旦涉及多点采集、本地显示加远程上报、还要在电磁环境复杂的 HVAC 场景里稳定运行选型和架构上的每一个决定都会在后期被放大。这次要聊的方案是PJ85718DM 搭配 STM32F412RE的组合。PJ85718DM 是一颗远程温度传感器支持本地和远程双通道测温通过 I2C 或 SMBus 接口与主控通信。STM32F412RE 则是 ST 家基于 Cortex-M4 内核的 MCU带 FPU、主频 100MHz、512KB Flash、256KB SRAM外设资源丰富尤其适合需要一定算力又要跑通信协议栈的场景。两者搭配正好覆盖 HVAC 应用里本地板载温度 远程探头温度同时监测的需求。为什么不用 MCU 内置的温度传感器因为内置传感器测的是芯片结温受 MCU 自身功耗发热影响极大精度通常在 ±1.5°C 甚至更差而且只能测芯片附近那一点。HVAC 场景里你要测的是风管温度、回风温度、室外温度探头可能离主板好几米远内置传感器完全无能为力。PJ85718DM 这类远程温度传感器就是为这种场景设计的——它支持外接二极管连接的晶体管比如常见的 2N3904 或专用测温三极管作为远程探头通过测量晶体管的 Vbe 电压变化来反推温度探头可以拉很远布线灵活。STM32F412RE 在这里的角色是大脑通过 I2C 读取 PJ85718DM 的温度寄存器做线性化校准、滤波、阈值判断然后驱动本地显示屏同时通过 UART 或以太网把数据上报到上位机或云平台。它的 FPU 在做温度补偿算法时很省心不用像 M0 那样软浮点跑得费劲。提示PJ85718DM 的远程测温精度和探头三极管的选型强相关不是随便找个 NPN 就能达到标称精度。后面会专门讲探头选型和校准。2. PJ85718DM 的测温原理与寄存器操作细节2.1 本地通道和远程通道到底怎么测的PJ85718DM 内部有两套测温机制。本地通道用的是芯片内部的带隙基准源本质上和 MCU 内置传感器类似但因为它独立封装、功耗低、热设计更专注精度能做到 ±0.5°C 左右。远程通道则是它的核心价值所在——它通过一对引脚通常标为 D 和 D-向外输出激励电流外部接一个二极管连接方式的三极管芯片测量该三极管在不同电流下的 Vbe 差值从而计算出 PN 结温度。这个原理叫ΔVbe 测温法。具体来说芯片会交替输出两个不同大小的电流比如 10μA 和 100μA流过远程三极管测量两次 Vbe差值 ΔVbe 与绝对温度成正比ΔVbe (kT/q) × ln(N)其中 k 是玻尔兹曼常数T 是绝对温度q 是电子电荷N 是两路电流的比值。这个关系是线性的所以只要测准 ΔVbe温度就能算出来。这种方法的优点是探头本身不需要校准因为 ΔVbe 只和物理常数有关和三极管的个体差异关系不大——当然实际中还是有偏差后面会讲。2.2 I2C 通信与关键寄存器PJ85718DM 挂在 I2C 总线上7 位地址通常是 0x18 到 0x1F 可配取决于具体型号的地址引脚接法。STM32F412RE 这边用硬件 I2C 外设去读写标准模式 100kHz 或快速模式 400kHz 都支持。几个必须搞清楚的寄存器寄存器地址名称作用常用配置0x00本地温度值高字节低4位为小数只读0x01远程温度值高字节远程通道温度整数部分只读0x02状态寄存器标识哪个通道超限、开路等读后需处理0x03配置寄存器设置转换速率、关断模式等0x00 连续转换0x04转换速率设置每秒转换次数0x04 约4次/秒0x05本地高限本地温度报警上限按需设置0x06本地低限本地温度报警下限按需设置0x07远程高限远程温度报警上限按需设置0x08远程低限远程温度报警下限按需设置0x09远程温度值低字节远程通道小数部分只读0x0A远程温度偏移远程通道校准偏移校准用读温度的标准流程是先读状态寄存器确认数据就绪再读温度寄存器。远程温度的高字节在 0x01低字节在 0x09低字节的高 4 位是小数部分分辨率 1/16°C。组合起来// 读取远程温度返回摄氏度浮点值 float read_remote_temp(I2C_HandleTypeDef *hi2c, uint8_t dev_addr) { uint8_t raw_high, raw_low; uint8_t reg 0x01; HAL_I2C_Master_Transmit(hi2c, dev_addr 1, reg, 1, 100); HAL_I2C_Master_Receive(hi2c, (dev_addr 1) | 1, raw_high, 1, 100); reg 0x09; HAL_I2C_Master_Transmit(hi2c, dev_addr 1, reg, 1, 100); HAL_I2C_Master_Receive(hi2c, (dev_addr 1) | 1, raw_low, 1, 100); int16_t temp_raw (int16_t)((raw_high 8) | raw_low); return temp_raw / 256.0f; }注意这里把高低字节拼成一个 16 位有符号数再除以 256是因为芯片内部温度是 11 位有效数据加 4 位小数左对齐存放。这个细节很多初次使用的人会搞错直接拿高字节当整数、低字节当小数结果温度跳变。2.3 转换速率和功耗的权衡HVAC 场景对温度变化的响应要求不高温度本身变化慢所以没必要每秒转换几十次。PJ85718DM 的转换速率寄存器可以设置从 0.25 次/秒到 32 次/秒。我一般设成 4 次/秒寄存器值 0x04这样既保证响应及时又不会让芯片功耗和 I2C 总线负载太高。如果设备是电池供电的可以设成 0.25 次/秒配合 MCU 的间歇唤醒整体功耗能压到很低。注意转换速率设太低时读到的温度可能是上一次转换的结果状态寄存器里的数据就绪标志要检查否则会读到旧数据。3. STM32F412RE 侧的软件架构与温度处理链路3.1 为什么用 F412 而不是更小的 MCU有人会问就测个温度用 F0 或者 L0 系列不就行了便宜又省电。这话在单点测温场景下没错但 HVAC 应用通常不止测温。以我做过的一个楼宇空调控制面板为例它需要驱动段码 LCD 或小尺寸 TFT 显示当前温度和目标温度、处理按键输入、通过 RS485 或以太网和上位机通信、跑 Modbus 或 BACnet 协议栈、可能还要控制继电器输出。这些任务加起来F0 的 Flash 和 RAM 就捉襟见肘了。STM32F412RE 的 512KB Flash 和 256KB SRAM 给协议栈和显示缓冲留足了空间100MHz 主频加 FPU 让温度补偿算法和滤波跑起来毫无压力。而且 F412 带硬件 CRC、真随机数发生器、多个 UART/SPI/I2C外设组合很适合这种采集显示通信的三合一需求。选型时多花的那点成本在开发效率和后期扩展性上完全赚回来了。3.2 温度数据的滤波与校准原始温度数据不能直接用。PJ85718DM 的输出虽然有 1/16°C 的分辨率但实际噪声和抖动还是存在的尤其是远程通道探头线缆长的时候容易耦合干扰。我通常做两级处理第一级是滑动平均滤波。维护一个长度为 8 的环形缓冲每次新数据进来替换最旧的然后取平均。这样能平滑掉大部分随机噪声又不会引入太大滞后。温度变化本来就慢8 个采样点的滞后在 HVAC 场景里完全可以接受。第二级是远程通道偏移校准。前面说过远程测温虽然原理上和三极管个体差异关系不大但实际中探头线缆电阻、三极管封装热阻、PCB 走线都会引入偏差。做法是把远程探头和本地传感器放在同一恒温环境里比如用恒温水浴或者高精度恒温箱读两者的差值把这个差值写进远程温度偏移寄存器0x0A。偏移寄存器是 8 位有符号数每 LSB 代表 0.0625°C范围大约 ±8°C足够覆盖常见偏差。// 校准示例假设本地读25.0°C远程读25.8°C偏差-0.8°C // 偏移寄存器值 -0.8 / 0.0625 -12.8 ≈ -13 (0xF3) uint8_t offset (uint8_t)(int8_t)(-13); uint8_t reg 0x0A; uint8_t data[2] {reg, offset}; HAL_I2C_Master_Transmit(hi2c, dev_addr 1, data, 2, 100);校准一次之后这个偏移值可以存在 MCU 的 Flash 里每次上电自动加载不用重复校准。3.3 本地显示与远程上报的数据流设计数据流的设计要清晰否则代码会越写越乱。我的做法是分三层采集层定时器触发比如每 250ms调用 I2C 读取函数拿到本地和远程温度原始值做滤波和校准存入全局结构体。应用层根据校准后的温度做阈值判断、报警逻辑、控制输出比如温度超过设定值就开继电器驱动压缩机。通信层本地显示直接读应用层的数据刷新 LCD远程上报通过 UART 或以太网按 Modbus 寄存器映射把温度值放到保持寄存器里上位机轮询读取。这样分层的好处是显示和通信互不干扰采集层的定时也不受通信阻塞影响。F412 的 DMA 可以帮 I2C 和 UART 减轻 CPU 负担但温度采集数据量小用中断模式就够了不必上 DMA。4. 远程探头选型、布线与抗干扰实战4.1 三极管探头的选择不是随便抓一个就行PJ85718DM 的远程通道要求外接一个二极管连接的三极管。理论上任何 NPN 三极管把基极和集电极短接都能用但实际效果差别很大。我试过几种2N3904最常见的小信号 NPN便宜好买精度一般在 0°C 到 70°C 范围内偏差大约 ±1°C做普通环境监测够用。MMBT3904SMD 版本性能和 2N3904 差不多适合贴片探头板。专用测温三极管有些厂商出专门用于温度传感的三极管Vbe 特性更一致精度能到 ±0.5°C 以内但价格贵一些采购周期也长。选哪个取决于你的精度要求。HVAC 控制一般 ±1°C 就够了2N3904 完全胜任。如果是精密空调或者实验室环境那就上专用管。4.2 探头线缆的长度和屏蔽远程探头最大的坑在布线。探头离主板几米甚至十几米远的时候线缆电阻和分布电容会影响测量。D 和 D- 两根线要双绞最好用屏蔽双绞线屏蔽层单端接地接主板地探头端悬空。双绞的作用是让两根线耦合到的干扰共模化芯片内部的差分测量能把它抑制掉。线缆长度方面我实测过 5 米以内的普通双绞线读数稳定超过 10 米后如果不加屏蔽温度读数会开始跳动幅度能到 ±2°C。加屏蔽并做好接地后15 米以内都能稳定在 ±0.5°C 的波动范围内。再长的话建议在探头端加一个小 RC 滤波比如 100Ω 串联加 100nF 对地把高频干扰滤掉。注意D 和 D- 的走线要尽量靠近不要分开走否则会形成环路天线引入更多干扰。PCB 上这两根线也要等长、平行走。4.3 探头自热和热耦合问题三极管测温有个固有问题是自热。芯片给探头注入激励电流虽然电流很小微安级但三极管本身还是会有一点点发热。如果探头封装很小、散热不好自热会导致读数偏高。解决办法是用低占空比的激励PJ85718DM 的转换速率设低一些或者选封装稍大的三极管热阻小一些。另一个问题是热耦合。探头要测的是环境温度但如果探头贴在 PCB 上或者被其他发热元件烤着测的就是局部温度了。HVAC 风管测温时探头要伸进风管用导热硅脂或者金属套管保证和空气充分热交换同时引线部分要做好隔热避免沿引线传热。5. 调试过程中踩过的坑与排查链路5.1 I2C 读不到数据从地址到上拉电阻的完整排查第一次调 PJ85718DM 的时候I2C 死活读不到数据HAL 函数返回 HAL_ERROR。排查过程是这样的第一步确认地址。PJ85718DM 的地址由地址引脚决定我一开始按 0x18 去访问后来查手册发现地址引脚悬空时是 0x18但我的板子上地址引脚接了地实际地址是 0x19。改过来之后还是不行。第二步查上拉电阻。I2C 总线需要上拉我板子上用的是 10kΩ按理说 100kHz 下没问题。但用示波器一看SCL 和 SDA 的上升沿很缓明显是上拉太弱加上总线电容偏大。换成 4.7kΩ 后波形好多了。第三步查电源。PJ85718DM 的供电范围是 3.0V 到 3.6V我一开始用 3.3V 没问题但后来发现芯片的 Vdd 引脚旁边没有放去耦电容导致电源纹波大芯片工作不稳定。补上 100nF 和 1μF 电容后通信正常了。这个排查链路告诉我I2C 不通的时候不要只盯着代码硬件层面的地址、上拉、电源、去耦都要逐一确认。5.2 远程温度读数跳变屏蔽和滤波的双重作用远程通道调通后发现温度读数每隔几秒就跳一下幅度大概 ±1.5°C。本地通道很稳说明问题出在远程探头和线缆上。先查线缆发现我用的是普通排线没有双绞也没有屏蔽。换成屏蔽双绞线后跳变幅度降到 ±0.5°C。然后在软件里加滑动平均滤波跳变基本看不出来了。最后在探头端加了 RC 滤波彻底稳定。这个过程说明远程测温的稳定性是硬件和软件共同保证的单靠软件滤波会引入滞后单靠硬件屏蔽成本又高两者结合最划算。5.3 温度值整体偏高校准偏移的正确用法板子跑起来后发现远程温度比实际温度高了大约 2°C。一开始以为是探头问题换了好几个三极管都一样。后来意识到是偏移寄存器没配置。按照前面说的方法用恒温环境校准把偏移值写进去温度就准了。这里有个细节偏移寄存器的值是 8 位有符号数写入的时候要注意类型转换。我一开始用uint8_t直接写负数结果编译器警告实际写入的值也不对。改成先转int8_t再转uint8_t就对了。6. 从原型到产品几个工程化建议6.1 温度数据的掉电保存与上电恢复产品化的时候校准偏移值、报警阈值这些参数不能每次上电都重新设。我的做法是在 Flash 里划一个专用扇区存一个结构体包含偏移值、高低限、设备地址等。上电时先读这个结构体如果校验和不对就用默认值。F412 的 Flash 擦写寿命是 10k 次以上这些参数不会频繁改完全够用。6.2 多点远程测温的扩展PJ85718DM 只有一路远程通道如果要测多个点怎么办两个办法一是挂多片 PJ85718DM 在同一个 I2C 总线上用不同地址区分二是用 I2C 多路复用器比如 TCA9548A扩展总线。前者简单但每片芯片占一个地址总线负载也大后者灵活但多一层切换逻辑。我一般根据点数选4 点以内直接挂多片超过 4 点用多路复用器。6.3 与 HVAC 控制逻辑的联动温度监测最终要服务于控制。比如回风温度超过设定值 2°C 就加大风机转速低于设定值 1°C 就降速。这些逻辑放在应用层用状态机实现避免一堆 if-else 堆在一起。F412 的定时器资源丰富可以用一个定时器做控制周期另一个做采集周期互不干扰。7. 一些实测数据和经验参数最后分享几组我在实际项目中测到的数据供参考场景探头类型线缆长度未滤波波动滤波后波动校准后精度板载本地内部-±0.1°C±0.05°C±0.5°C机柜内远程2N39042m 双绞±0.3°C±0.1°C±0.8°C风管内远程2N39048m 屏蔽双绞±0.8°C±0.2°C±1.0°C室外远程专用管15m 屏蔽双绞±1.2°C±0.3°C±0.6°C从表里能看出来线缆越长、环境越恶劣波动越大但通过屏蔽、双绞、滤波、校准这套组合拳最终精度都能满足 HVAC 控制的要求。转换速率我一般设 4 次/秒采集周期 250ms滤波窗口 8 点这样从温度实际变化到显示更新大约有 2 秒的滞后对于空调控制来说完全够用。如果做快速响应的场景可以把转换速率提到 16 次/秒滤波窗口缩到 4 点滞后能压到 0.5 秒以内。这套 PJ85718DM 加 STM32F412RE 的方案我从原型到量产跑过好几轮稳定性没问题成本也可控。关键是把探头选型、布线屏蔽、校准偏移这几件事做扎实剩下的就是常规的嵌入式开发工作了。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进