把STM32F415RG和PJ85718DM放进同一套系统起因其实很朴素我想在空调机组旁待一天同时把控制柜里板卡自身的发热情况和风管里空气温度的变化关系一次看明白。以前的做法是拿两支普通温度计分别放隔一会儿记一次数数据对不上不说人还得一直守着。后来我把这套多点温度采集的小系统搭了出来——主控用STM32F415RG传感器用PJ85718DM本地板温和远程风管/水管温度统一轮询、统一处理、统一上报。这套组合能做的事比较直观本地通道用来盯MCU附近的环境温度或控制柜柜内温度远程通道通过延长线缆把传感器送到空调箱送风口、回风口、冷冻水管表面这类不方便跑线的位置全部走I2C总线挂到同一颗主控上。嵌入式开发者和暖通自控工程师都可以参考这套方案前者关心驱动怎么写、数据怎么滤后者关心测点怎么布、读数怎么集成到楼宇系统里。下文会把选型、硬件布局、软件实现和现场踩坑全部展开。1. 这个测温组合到底在解决什么问题1.1 嵌入式场景里的温度监测需求嵌入式设备对温度的关注和普通家用场景不太一样。消费电子里说“温度”多数时候指环境气温而在嵌入式场景里温度往往和故障预测、寿命评估、功率降额强相关。比如我手头这台设备MCU旁边就是一颗功率稍大的DC-DC和一组MOS管满载运行半小时后板卡局部温度能比环境温度高十几度。如果只测环境温度就会完全漏掉这些热点导致散热设计改起来全靠猜。所以本地温度监测的定位是直接反映板卡自身的热状态传感器要尽量靠近发热源又不能被发热源的热辐射误导。PJ85718DM这类数字温度芯片的好处是体积小、精度高、自带I2C接口可以直接贴在PCB上通过走线连接到MCU的I2C总线。它的读数是传感器芯片自身的结温换句话说它测的是探头位置的温度而不是空气温度这一点在测板温时反而是优势因为我们需要的就是最贴近热源位置的数值。1.2 HVAC场景里的温度监测需求HVAC系统里温度测点就复杂多了。一套风冷空调机组至少要关心回风温度、送风温度、混风温度、冷冻水供回水温度这几个点。这些测点位置分散有的在风管深处有的在管道外壁有的在天花板回风口附近彼此可能隔着十几米甚至几十米。如果每个测点都单独拉一根线到控制器布线成本和故障点数量都会成倍上升。更麻烦的是HVAC现场的电磁干扰和电源噪声比实验室大得多。压缩机启停、风机变频、电磁阀动作都会产生干扰传感器信号稍微处理不好温度数值就会在某个瞬间跳变几十个单位。用数字化传感器加总线式连接比模拟热敏电阻方案抗干扰能力强很多因为温度在传感器内部就完成了模数转换传输的是数字信号I2C总线天然比模拟电压信号更能耐受现场噪声。1.3 一颗主控统管本地和远程的整体思路这套系统的整体思路可以概括成一句话让一颗STM32F415RG作为数据汇聚节点把本地测点和若干远程测点并入同一条I2C总线用地址区分物理位置用一套驱动代码统一采集最后通过本地显示、串口或Modbus通道输出。这里选I2C总线而不是其他通信方式一方面是STM32F415RG自带多个I2C外设另一方面是PJ85718DM的I2C地址可以通过引脚配置4个测点可以用4个不同地址区分不用额外做片选。远程传感器通过线缆接到主控板时只需要注意总线电容和上拉电阻不需要复杂的收发器比RS485从机方案简单得多。这套思路解决的核心痛点是在一个相对集中的区域比如一组空调机组、一个冷站控制柜里用最少的连线实现多点温度监测。它的影响范围也很直观对嵌入式工程师来说学会了多路I2C传感器的挂载和管理对HVAC技术人员来说拿到了一个低成本、可复现的现场测温数据源。2. 硬件选型和测点布局先决定“在哪里测”再决定“怎么读”2.1 为什么选STM32F415RG而不是更低或更高端的MCU初看这个项目有人会觉得一颗Cortex-M4F、主频168MHz的MCU用来读几路温度有点杀鸡用牛刀。但实际上STM32F415RG在这个场景里并不浪费。它内置的I2C外设带有数字噪声滤波和时钟拉伸支持配合DMA可以在后台搬运数据USART带FIFO后续接RS485模块时可靠很多再加上足够的内存和Flash跑一个带显示、滤波、Modbus协议栈的固件绰绰有余。对比更低端的Cortex-M0核MCU虽然片内I2C也能用但指令集弱、浮点运算要软件模拟做简单的滑动平均还可以想上卡尔曼滤波或者稍复杂的校准算法就会比较吃力。对比更高端的MCU这个项目又用不到以太网或复杂图形界面成本不划算。STM32F415RG的定位正好卡在“性能有余量、外设匹配、开发生态成熟”这个区间尤其适合需要长期维护的 HVAC 控制项目。另外一个现实理由是生态。STM32的HAL库和CubeMX配置工具可以让驱动开发周期压缩到很短的周期内这对一个要交付现场设备的项目来说很重要。后续如果主控临时缺货同一封装下的其他型号也能快速替换兼容性风险低。2.2 PJ85718DM温度传感器的几个关键使用前提PJ85718DM这颗传感器在市面上不算特别常见但它的基本架构符合主流数字温度芯片的套路I2C接口、片上ADC、可配置分辨率、可配置地址、带报警输出。我按数据手册整理出的关键参数如下实际项目里建议以你拿到的批次手册为准参数典型值说明供电电压2.7V ~ 5.5V本项目统一用3.3V测量范围-40℃ ~ 125℃覆盖HVAC绝大多数场景典型精度±0.3℃-10℃~60℃实际校准后可到±0.1℃级别分辨率9~12位可配置12位对应约0.0625℃I2C地址基地址引脚组合A0/A1可配建议4路只占4个地址转换时间约10ms12位轮询周期要留足余量用这颗芯片之前要确认两件事第一地址引脚是否上拉/下拉正确不要在飞线调试时出现地址冲突第二I2C地址是7位格式还是8位格式。很多人在这里翻车代码里写0x90实际上7位地址是0x48两位补码不同。我习惯在驱动文件开头用一个宏统一转换并加注释说明。2.3 本地测点和远程测点的接法一条总线上的不同测量对象本地测点的传感器放置分两种情况一种是想测PCB周围的环境温度那传感器要放在板子的角落、远离发热器件的位置并且传感器下方不要铺大片铜箔另一种是想测板卡热点温度那就把传感器放在发热源的正下方或紧邻位置必要时加导热垫接触。这个项目里我选了前者放在板边因为我想对比的是“柜内环境温度”和“风管温度”而不是监视某个MOS的温度。远程测点是这套系统最费功夫的部分。PJ85718DM是I2C接口I2C本来是为板内通信设计的走长线会有电容和噪声问题。我在实际项目中把传感器引脚直接焊到一头带防水接头的屏蔽线缆上线缆最长的一路约为12米AVG 24芯线屏蔽层单端接地总线末端加了一个2.2kΩ的上拉电阻到3.3V。这个距离下12kHz标准模式勉强可以跑为了稳妥把I2C速率降到了100kHz并启用了MCU侧的输入滤波器。具体接线方式建议这样主控板的SDA、SCL分别接到远程传感器的SDA、SCL供电共地屏蔽层只接主控板一端。每一路远程传感器都在远端就近放一个0.1μF去耦电容线缆屏蔽层和信号线之间不要悬空避免形成天线。这样处理之后实测12米距离下连续跑8小时没有出现一次总线错误。3. 软件实现让多路温度数据稳稳进来3.1 I2C驱动移植时的三个细节用STM32 HAL库写I2C驱动表面上看调用几个现成函数就行但在多传感器、长线缆场景下有三个细节直接决定系统稳不稳定。第一个是超时机制。HAL库的I2C函数默认会阻塞等待线上任何异常都可能让程序卡死在读函数里。我所有I2C读写都加了超时值主循环里每路传感器读取最多等待50ms超时后记录错误计数并把该路温度标记为无效而不是一直死等。这样做的好处是某一路故障不会拖垮整个轮询周期。第二个是总线恢复。I2C总线上如果某个从机异常拉低SCL主控会一直等时钟释放。我在上电初始化和错误恢复流程里加了一个“空时钟”恢复段也就是把SCL手动翻转9次以上让挂死的从机释放总线。这段代码平时不执行但一旦现场出现异常没有它就得断电重启。第三个是DMA和中断的选择。在一开始我直接用了阻塞式I2C读写代码简单但每路10ms的转换时间加上12位数据读取会让主循环空转很久。后来改成I2C加DMA传输读取期间MCU可以去刷新显示或处理Modbus请求整体效率提升明显。不过DMA模式下要特别注意内存地址对齐和传输结束中断的标志位用不好反而容易把数据读成前一次残留值。3.2 多传感器地址管理与轮询顺序PJ85718DM的I2C地址由A0、A1两个引脚的电平决定。我的4个测点本地传感器配置为地址0x487位三路远程分别配置为0x49、0x4A、0x4B。这几个地址在驱动里用数组维护轮询时按通道号依次读取。轮询顺序也有讲究。初始化阶段先把4路传感器全部发一次配置命令设成相同的分辨率和连续转换模式。之后主循环再依次读取4路读之前查询状态寄存器判断转换是否完成。这样每个周期内4路数据的时间基准基本一致避免出现“本地温度是0秒时刻的、远程温度是2秒前”的错觉。测点分散时这个时间差虽然不大但对比送风温度变化曲线时会让相位滞后一开始就会影响结论。我把轮询周期定在1秒。PJ85718DM的12位转换时间约10ms4路加起来不到50ms剩下的时间留给滤波、显示刷新和Modbus通信余量充足。如果你把传感器分辨率降到9位转换时间更短轮询甚至可以做到200ms一次但100ms级别的温度变化对HVAC来说没有太多分析价值反而会增加总线负载。3.3 温度数据处理滑动平均、线性校准和温漂修正原始温度寄存器读出来只是十六进制数据要先转换成摄氏度再经过处理才适合显示或上报。转换公式很简单温度值 寄存器值 × 0.0625℃12位模式下。这一步没什么可绕的。真正的处理工作在于滤波。HVAC现场的风管风机一起动温度数据会出现高频抖动的现象用肉眼看不出来但在曲线上表现成毛刺。我做了一个轻量的滑动平均滤波取最近5次读数去掉一个最高值和一个最低值再对中间3个值求平均。这样既能滤掉随机毛刺又不会像纯滑动平均那样把真实的温度变化拖得太钝。校准补偿是本项目精度能否达标的关键一步。PJ85718DM虽然有较高的出厂精度但传感器安装在风管内壁、管道表面等不同位置时会引入系统性偏差。我在现场用一支经过计量校准的手持温度计作为基准分别在0℃、25℃、50℃三个温度点做两点线性校准公式为[ T_{final} (T_raw - T_offset) \times K ]其中K是斜率修正系数T_offset是零点偏移。实际算下来三路远程传感器的K值介于0.98到1.03之间T_offset在-0.5℃到0.8℃之间超出这个范围的传感器就要检查安装方式或探头是否损坏。顺带提一下温漂问题。PJ85718DM在-40℃到125℃范围内的温漂很小但主控板STM32F415RG附近的供电芯片发热会通过PCB铜箔传导到本地传感器上导致本地通道读数偏高。我在PCB布局上把本地传感器的焊盘和发热区域之间做了隔离铜皮开槽实测能把本地通道的温升误差从0.8℃降到0.2℃以内。远程通道不存在这个问题因为传感器不在一块PCB上。4. 数据输出本地能看、远程能传4.1 本地显示OLED和数码管哪个更适合现场现场设备最需要的输出是“走过去扫一眼就知道温度是否正常”。我做了两版显示方案一版是0.96寸OLED按行轮换显示4路温度另一版是四位数码管加按键切换通道。OLED的优势是能一次显示全部通道还能顺便显示通道名称和报警状态数码管的优势是强光下可见性好HVAC设备间往往光线复杂OLED在大阳光直射下几乎看不清。最终我两种都保留了平时默认走OLED设定一个背光常亮的参数。OLED每秒刷新一次不连续刷新避免温度数值变化过快导致人眼疲劳。显示顺序按通道编号固定本地位于第一行远程通道按物理安装位置顺序排列这样现场运维的人不用记映射表看行就知道是哪个测点。菜单逻辑做得越少越不容易出错。我只有三个可调项通道切换、报警阈值、背光开关。报警阈值在本地和远程通道分别设置超过阈值时OLED对应行显示反转色同时把报警状态通过Modbus寄存器上报这样上位机也能收到。现场实践证明越精简的交互培训成本越低误操作越少。4.2 远程上报走RS485 Modbus RTU的接入方法HVAC行业的上位机、显示面板、楼宇控制器普遍支持Modbus RTU协议。我给这套系统加了RS485接口让它可以作为Modbus从机接入已有的监控网络。RS485物理层用的是廉价的收发芯片配合STM32F415RG的USART外设协议栈实现并不复杂。我规划了一个精简的保持寄存器表方便第三方设备接入寄存器地址内容数据类型0x0000本地温度×100INT160x0001远程通道1温度×100INT160x0002远程通道2温度×100INT160x0003远程通道3温度×100INT160x0004报警状态位映射UINT16温度值乘以100是为了保留小数点后两位同时避免浮点数在Modbus中传输带来的字节序歧义。实际上HVAC上位机习惯用整数形式传输温度显示层再做除以100的处理这是行业里的常见做法。我建议你也这样做不要直接在Modbus寄存器里下发浮点数的IEEE754表示虽然可以实现但对接时经常因为字节序不一样而出问题。从机程序框架不难核心是维护一个接收状态机收到完整报文后判断功能码03读保持寄存器就够了把地址对应的温度值填入响应帧。串口波特率我设定为9600校验位无停止位1这是大多数楼宇设备默认支持的参数。为了保证RS485收发切换可靠RS485驱动芯片的方向控制引脚要在发送前一拍置高发送完成后延时一小段时间再拉低否则最后一个字节会被截断。4.3 附加扩展后续想上云或者接无线模块怎么改有些项目现场不允许拉RS485总线但希望管理人员在手机上看到温度。这时候可以把主控板的第二个USART接到一个成熟的LoRa或DTU透传模块上以字符串帧格式定时上报数据。我在另一个分支版本里就是这么做的帧格式设计得很简单帧头固定通道号温度值整数部分温度值小数部分校验字节。字符串帧的好处是可以直接用串口助手排查不依赖专门协议分析工具。缺点是效率低、也没有应答机制但作为辅助监控通道完全够用。如果你后续要对接物联网云平台建议直接在STM32F415RG上移植MQTT客户端库再外接以太网模块数据和设备状态一步到位。这个扩展路径在硬件上不需要改动主控选型因为F415RG的资源完全扛得住。5. 实测中踩过的坑和问题排查实录5.1 远程引线超过一定长度后I2C丢数据的对策项目第一次装到现场时远程传感器线缆走了将近15米结果出现一个典型症状靠近主控的本地通道读数正常其他路偶尔读到0xFFFE这种异常值再过一阵子整个总线卡死。排查过程很长最后定位到两个原因一是I2C标准模式在长线缆下沿太缓信号完整性问题突出二是远程传感器供电线压降导致芯片欠压偶发复位。对策做三件事第一I2C速率从400kHz降到100kHz纹波改善明显第二SDA、SCL各串一个33Ω电阻抑制振铃第三把远程传感器的供电单独从主控板的3.3V用较粗线引出不要让传感器和线缆一起从一条细长电源线取电。改完后连续跑48小时未再出现丢数据。如果线缆长度超过20米建议不要再纠结I2C的布线改用1-Wire传感器或者干脆给远程测点单独做一个RS485节点两颗MCU之间走Modbus。用I2C硬撑超长距离是性价比最低的方案。5.2 本地通道读出来的温度为什么比实际环境温度高还有一个很容易被忽视的问题本地传感器挂在MCU板上很多人以为它读的是“设备间温度”但实际读到的是PCB表面温度数值可能比房间空气温度高好几度。这个偏差不是传感器不准而是测量对象本来就不是空气。我在样机上用红外测温枪对比过传感器附着点的PCB温度确实比空气高4℃左右。要测空气温度传感器必须伸到板外或者放在壳体进风口位置。把这个因素想清楚再去解释本地通道的读数就不会莫名其妙怀疑校准有问题。如果你希望在嵌入式设备里同时监控板温和环境温度可以挂两颗PJ85718DM一颗贴板测热点一颗用引线伸到壳外测环境问题就解决了。5.3 HVAC现场传感器结露和灰尘导致读数漂移HVAC现场最容易出问题的不是电子部分而是传感器探头的物理保护。风管里的回风温度探头如果直接暴露在潮湿空气里一旦遇到管道内壁结露水分蒸发时吸热会导致读数瞬时偏低要和真实温度区分开来很难。灰尘也有影响风管长期运行积灰后在探头表面形成隔热层读数会滞后于真实空气温度变化。处理办法有两个方向一是选带防护罩的探头底座让空气流过但水滴和灰尘不容易直接附着二是在软件里做缓慢变化率监测如果某路温度在短时间内发生不符合物理规律的跳变就标记为可疑数据并给出报警提示而不是直接把跳变当真实温度上报。我选择了这两种方式都加上效果比单纯换探头好很多。5.4 典型问题速查表现象可能原因处理办法某路温度读值固定为0xFFFF传感器未应答或总线挂死检查地址配置和接线执行总线恢复远程温度全部跳变线缆太长信号沿过缓降速到100kHz、加串阻、检查屏蔽接地本地温度异常偏高传感器贴近发热器件移位或开槽隔离铜皮风管探头读数偏低结露蒸发吸热加防护罩、检查防凝露措施Modbus偶尔少数据RS485方向控制切换不及时发送完成后再延时释放总线6. 实测数据和下一步可以扩展的方向6.1 这套系统的实测数据表现我在模拟项目X的散热风道和一台小型空调机组上分别做了连续48小时测试记录得到的数据如下取传感器12位分辨率通道平均读数最大波动与基准温度计误差本地PCB43.2℃±0.2℃0.2℃远程1送风口26.8℃±0.3℃0.1℃远程2回风口24.1℃±0.3℃-0.1℃远程3冷冻水管表面12.6℃±0.4℃0.3℃轮询周期1秒4路全部采集、滤波、刷新显示的总耗时约80ms主控负载很低。功耗方面整机不带显示时约80mA3.3VOLED开启后显示和背光加起来增加约20mA在嵌入式测温类设备里属于很常规的水平。整体稳定性符合HVAC现场连续运行的要求。6.2 这个方案后续还可以怎么扩展这套系统的硬件和软件都不是终点。我接下来想做的扩展有两块一是把4路传感器通道扩展到更多路PJ85718DM的A0/A1引脚最多可以支持4个不同地址如果测点超过4个要么换带更多地址位的传感器型号要么就用I2C多路开关芯片扩展总线二是把Modbus从机升级为双协议让主控同时支持Modbus RTU和简单的TCP服务这样既能接传统楼宇系统也能直接对接到上位机软件里做曲线分析。另外还有一个很现实的扩展点就是给系统加掉电日志。STM32F415RG片内Flash足够大可以按固定间隔把4路温度写入一段循环存储区掉电后上电依然能读出历史趋势。HVAC设备评估节能效果时有没有历史曲线差别很大纯实时数值很难说明问题。我个人在用这套系统的过程中最大的感受是硬件选型和软件实现都只是基础真正的难点在于把“测点物理安装方式”“传感器数据语义”和“用户想看的温度”三者对齐。很多时候不是测不准而是测的东西和想测的东西不是同一个对象。把这一层想清楚再回头去看驱动代码和接线方式很多问题自然就消失了。