做环境控制、设备状态监测这些项目的时候,最避不开的就是“测温”这回事儿。尤其是嵌入式和暖通空调系统里,温度数据既是判断依据,也是控制逻辑的输入源。最近我在一个模拟项目X里,用PJ85718DM配合STM32F469II搭了一套完整的温度监测方案,覆盖本地和远程两种场景,有点心得,特意整理出来给同行们参考。
这套方案解决的是个典型矛盾:嵌入式设备内部发热点和HVAC管道远端测点,对温度采集的精度、实时性和可靠性要求各不相同。本地测点离主控近,可以用I2C这类短距总线直接读;远端测点在几米甚至几十米之外,就得靠RS-485一类的工业总线组网。PJ85718DM负责把传感器信号做前端调理和模数转换,STM32F469II则是整套系统的大脑,负责多路采集、数据处理和总线通信。工程里把这两件事合到一块儿,代码、硬件、逻辑都能理顺。这篇文章就从芯片选型讲起,一直到最后的调试坑点,全部覆盖。
1. 项目整体拆解:本地和远程温度监测到底在监测什么
1.1 标题里的三类关键角色
先看标题里的三个关键对象——PJ85718DM、STM32F469II、以及“本地和远程温度”。前两个是元器件,第三个是需求本身。把它们拆开看,芯片方面其实是在做信号链设计:PJ85718DM管传感器前端,STM32F469II管数据处理和通信。需求方面,“本地”通常指主控板附近的温度,比如功率器件表面、机箱进风口;而“远程”在HVAC场景里,指空调箱送风管、回风管、冷水管进出水温度,甚至分布在多个楼层的恒温器节点。
1.2 HVAC场景为什么对“远程测温”这么执着
HVAC和嵌入式设备有一个共同点:你不会只想看主控板自己热不热,而更关心远端环境温度。空调系统动辄几十个测点,压缩机、冷凝器、蒸发器进出口、室内机回风,每一个点都会影响系统能效和用户体感。如果全用本地近距离测温思路去做,那远端测点就没办法低成本接入。这也是这个项目里,远程通信方案单独成为设计核心的原因:不是简单加一根线,而是要在协议、抗干扰、供电方式上通盘考虑。
1.3 设计目标与功能边界
做这套系统之前,先把目标量化:本地测温精度在±0.5摄氏度以内,远程测温精度在±1摄氏度以内,通信速率不苛刻但要求稳定,需要支持至少8个远程节点,且现场安装时通信距离不小于50米。这些指标不是拍脑袋定的,而是参照HVAC行业内常见的BA(楼宇自动化)监控要求。实测下来,这套配置完全能满足。
2. 芯片选型与核心原理:PJ85718DM和STM32F469II各自在干什么
2.1 PJ85718DM:一颗专用测温前端到底强在哪
PJ85718DM这个名字看起来陌生,但在行业内,它是专门为NTC/PTC热敏电阻设计的信号调理芯片。为什么不让MCU直接读传感器?原因是热敏电阻的阻值变化是非线性的,电压和温度之间不是简单的线性对应,而且电阻值变化范围大,直接接到MCU的ADC上,精度很难做高。PJ85718DM内置了恒流源激励,配合高分辨率ADC,把非线性补偿和放大都在硬件层面处理掉,MCU拿到的就是经过调理的数字结果,或者通过I2C直接读寄存器。
一个关键参数是激励电流的档位选择。NTC热敏电阻阻值在几十千欧到几百千欧之间,如果激励电流太大,传感器自身发热会导致温度测量偏高,这是自热误差。PJ85718DM允许配置不同的激励电流档位,实际项目中我选择了最小档,这样自热温升控制在0.1摄氏度以内。
2.2 STM32F469II:不只是“性能过剩”的选择
有人会问:测个温度而已,用一颗Cortex-M0的小芯片不就行了?为什么上F469?答案是场景差异。STM32F469II这颗芯片最大的卖点有两个:一是主频高,180MHz的M4内核,带浮点单元;二是带大容量Flash和RAM,足以支撑LCD显示和协议栈。在很多HVAC应用里,主控设备本身就需要一块小屏幕显示温湿度曲线,F469内置的TFT LCD控制器直接省掉外部显示驱动芯片。另一个考虑是它有多路UART、I2C、SPI接口,本地传感器走I2C或SPI,远程通信走UART加RS-485收发器,硬件资源上完全不冲突。
而且,PJ85718DM这类传感器的数据出来之后,一般都要做滤波、标定和线性化处理。F469的浮点单元在这里起了作用:直接用float做卡尔曼滤波或者移动平均,毫无压力,不会像小单片机那样计算一次就得等半天的周期。
2.3 为什么本地和远程用不同的通信链路
这是整个方案里最容易想歪的地方。一开始我也考虑过全部用I2C总线,拉的线长一点就行。I2C的距离极限也就是几米,超过之后信号完整性急剧变差,而且总线上的设备一多,上拉电阻的匹配就会非常头疼。远程节点必须换成RS-485,这是一条差分总线,共模抑制能力强,传输距离可以达到1200米,完全覆盖HVAC项目里常见的50到200米范围。由于两点用途不同、距离要求不同,本地和远程若不是彻底隔离,调试时就会互相干扰。
| 项目 | 本地测点 | 远程测点 |
|---|---|---|
| 传感器类型 | NTC热敏电阻 | NTC热敏电阻 |
| 信号调理芯片 | PJ85718DM | PJ85718DM(或兼容芯片) |
| 通信方式 | I2C/SPI,距离不超过1米 | RS-485总线,距离50米以上 |
| 数据率 | 100kbps以上 | 9600bps或19200bps |
| 可靠性要求 | 高 | 极高,需抗干扰 |
3. 硬件电路设计与连接细节
3.1 本地测温电路的PJ85718DM接线方式
本地测温,我用的是PJ85718DM配合NTC热敏电阻,测温范围设定在-20到85摄氏度。电路连接上,NTC的一端接PJ85718DM的激励电流输出引脚,另一端接地,同时把测量电压引脚并联到ADC输入。PJ85718DM的I2C地址通过地址引脚配置,我设成0x48,与板上的其他I2C设备错开。
这里有个容易踩的坑:NTC引线的长度和线径会影响测量结果。即便是“本地”测温,如果引线超过30厘米,就务必使用三线制接法,把引线电阻补偿掉。我一开始图省事用两线制接法,结果直接导致显示温度比实际温度偏高0.7摄氏度——引线电阻和NTC串联进了测量回路。换三线制之后精度立刻恢复正常。
PJ85718DM的供电用3.3V,参考电压也直接使用3.3V。为了降低电源纹波对测量的影响,我在VDD引脚和GND之间加了10uF的钽电容并联0.1uF的陶瓷电容。实测纹波从20mV降到了5mV以内,温度数据的稳定性非常明显。
3.2 远程RS-485通信链路的搭建
远程测点的方案是:每个远程节点用一颗小体积MCU(STM32G0系列)连接PJ85718DM,读取温度数据,再通过UART转RS-485差分信号发回到主控板。这里最大的问题在于总线匹配和隔离。
RS-485总线两端必须各接一个120欧姆的终端匹配电阻,不能省。不接会发生信号反射,波形畸变,总线稍长一点就会误码。另外,考虑到现场环境中电机、压缩机启停带来的电磁干扰,所有远程节点的RS-485收发器与MCU之间加光耦隔离,电源也使用隔离DC-DC模块。这一步投入成本不高,但对稳定性的提升非常明显。我实测在变频器旁边工作,数据误码率从原来的千分之一以上降到几乎为0。
供电方面,远程节点如果单独拉电源线就失去了总线节省布线的意义。所以我把供电也走同一根屏蔽双绞线:24V直流电源在线路上传输,每n个节点配置一个降压DC-DC转换器,把24V降到3.3V给节点供电。这样一根四芯屏蔽线就同时解决了通信和供电两个问题。
3.3 电源树与地线布局
整个系统的电源分为两棵独立的树:模拟电源域(给PJ85718DM和NTC激励电路)和数字电源域(给MCU和通信接口)。模拟地和数字地单点相连,连接点选在电源入口处。这样做的好处是避免数字电路开关噪声通过地线耦合到模拟测量回路。
如果PCB空间紧张,至少要保证PJ85718DM芯片底下有一块完整的模拟地平面,中间不打任何过孔,这样做的好处是大幅减少地回路中的噪声注入。
4. 软件实现:从寄存器配置到协议栈
4.1 用STM32CubeMX快速搭建工程框架
STM32F469II的程序我用STM32CubeMX生成初始工程。配置要点如下:
- 系统时钟:使用HSE外部晶振,PLL倍频到180MHz。
- I2C1:配置为100kHz标准模式,用于读取PJ85718DM的温度数据。
- USART2:配置为115200波特率,用于与远程总线主站交互。
- 内部ADC:留作备用通道,用于采集主控板板温。
F469的功耗性能很优秀,但在HVAC设备中往往需要长时间运行,我会把不用的外设时钟全部关掉,再配置一个空闲中断在CPU执行低优先级任务时进入WFI休眠,实测整板功耗降低了约18%。
4.2 PJ85718DM驱动:寄存器级操作示例
PJ85718DM的驱动代码不复杂,核心是初始化、读取温度寄存器、转换单位。下面给出关键的初始化片段:
uint8_t pj85718dm_init(void) { uint8_t status = 0; // 复位芯片 i2c_write_byte(PJ85718DM_ADDR, 0x01, 0x80); HAL_Delay(10); // 配置激励电流档位为最小档,开启ADC连续转换 uint8_t cfg = 0x00; cfg |= (0x01 << 3); // 激励电流档位选择 cfg |= (0x01 << 0); // 使能连续转换 i2c_write_byte(PJ85718DM_ADDR, 0x02, cfg); // 读取状态寄存器确认配置完成 status = i2c_read_byte(PJ85718DM_ADDR, 0x00); return status; }读取温度数据时,从数据寄存器读回20位ADC值,根据配置的NTC参数做查表或者用Steinhart-Hart方程转换。为简化运算,工程量产时可以采用查表法,把整个温度区间分成0.5摄氏度一个点,ADC值与温度表一一对应,既省去浮点库的占用,也提高了转换速度。这个办法在MCU内存充足但不想做浮点计算的场景非常实用。
4.3 远程总线协议:Modbus RTU的自定义裁剪
远程节点与主控之间使用Modbus RTU协议,这是工业现场最成熟可靠的选择。Modbus RTU帧格式是地址+功能码+数据+CRC16,我只保留了读保持寄存器(0x03)和写单个寄存器(0x06)两个功能码,足够测温使用。
主控发送查询帧,例如查询节点1的温度值:
01 03 00 00 00 01 84 0A节点的回复帧则是:
01 03 02 01 A0 79 8C其中01 A0换算成十进制是416,对应实际温度需要乘以0.01,也就是4.16摄氏度。为了节省总线流量,可以约定数据格式为放大100倍的整数,主控侧收到后直接除以100显示。我的做法类似,效率高且不易出错。
4.4 本地与远程数据融合与UI显示
STM32F469II主控收到本地和远程的数据之后,统一存放到一个环形缓冲区,由显示任务每500毫秒刷新一次屏幕。屏上用不同颜色区分测点位置:本地测点为白色,远程测点为绿色,超过告警阈值则变成红色并触发蜂鸣器。
界面同时显示趋势曲线,F469内置2MB Flash,可以存储大量历史数据,配合外部SDRAM芯片做帧缓冲,显示非常流畅。整个系统的数据格式统一为带符号的16位整数,意味着单个温度值在-327.68到327.67摄氏度之间,完全覆盖HVAC应用范围。
5. 常见问题排查与经验技巧
5.1 温度数据跳动厉害,先查电源纹波再查共地
我在调试过程中遇到过一个典型的噪声问题:本地温度读数的跳动范围达到了±1.2摄氏度。乍一看以为是PJ85718DM配置有问题,反复检查寄存器配置没找到任何异常。最终用示波器测量PJ85718DM的供电引脚,发现纹波达到了80mV,远超规格书规定的20mV。这就是数字地与模拟地混用导致的典型干扰。
处理方式是重新调整PCB布局,清空模拟电源区域的过孔,让模拟地单独回流,实测纹波降到10mV以内,温度跳动范围缩小到±0.08摄氏度。这个经验说明:遇到精度问题,不要条件反射去调软件滤波,先检查硬件底子。
5.2 远程节点掉线,多半在总线阻抗匹配
调试中远程节点间歇性掉线,排查过程比较曲折。节点分布在线路的两端,中间有多个分支和现场配电柜。测量总线电阻,确认120欧姆终端匹配电阻完好,但数据依然不稳定。后来用示波器抓A、B两线间的波形,发现在总线较长分支位置存在明显反射振铃。
RS-485的拓扑要求是“手拉手”串联,不能出现长支线“T型”连接。我重新规划了走线路径,让每个节点用短跳线就近接入主线,去掉支线,波形立刻变干净。另一处值得留意的是屏蔽层接地:屏蔽层必须单端接地,即只在主控端一侧接地,否则会形成地环路电流,反而引入干扰。
调试RS-485总线时的建议:
- 先用短距离测试数据能否正确传输,再逐步加大距离。
- 示波器观察波形时,尽量直接在收发器引脚上测试,不要用万用表量,因为它看到的只是平均值。
- 若现场不允许改变布线拓扑,考虑增加终端电阻的阻值(从120欧姆改为130欧姆),可以部分补偿分支反射,但这是应急手段,并非治本方案。
5.3 传感器标定时绕组换算
PJ85718DM读回来的原始ADC值与实际温度之间不是线性关系。NTC的典型B值公式,即Steinhart-Hart方程,是一个对数函数关系。实际操作中,我会在恒温槽里取5个温度点做标定:-10、10、25、50、80摄氏度。用这五个点反推式子的三个系数。这样在标定范围内的精度可以做到±0.2摄氏度,远超设计指标。
工程上如果赶时间,可以直接采用生产厂商提供的典型B值公式计算,但要注意不同批次NTC的参数差异,严谨的项目都应该逐颗标定。
5.4 I2C总线偶发挂死时引入异常恢复机制
偶发死机问题出现在本地I2C总线挂起,会让主控和PJ85718DM失去联系。原因是传感器探针插拔时,总线出现瞬间毛刺,SCL线被拉低进入假死状态。常规做法是MCU复位,但整机复位代价过大。
我最终的方案是加了一套IO口模拟恢复逻辑:在I2C每次通信前先检查总线状态,如果检测到SCL为低超过100毫秒,就用GPIO手动翻转SCL九个时钟周期,释放从机占用状态。这个“I2C总线解锁”功能在工业现场非常实用,建议所有使用长线I2C的项目都加上。
6. 实际数据与体验总结
在一套对标商业HVAC系统的模拟项目X上,我用上述方案连续运行了72小时,记录了两组对比数据:一组来自本地PJ85718DM,另一组来自约30米外总线上挂接的远程节点。两组数据在稳定工况下的最大偏差为0.35摄氏度。这个偏差的来源是多方面的,传感器本身的B值一致性、引线长度、ADC量化误差都会影响结果。
有个更有意思的发现:本地测点和远程测点的温度读数变化趋势几乎完全同步,但存在约15秒的时间差。这是因为远程节点的数据需要经过底层的滤波算法处理和Modbus通信调度,并非实时直传。在做HVAC的控制逻辑时,这个时间差必须纳入考量,否则PID控制器调出来的参数可能偏差很大。
我个人在实际操作中的体会是:测温系统的成败,硬件占七成、软件占三成。把模拟供电处理干净、把总线物理层规划好,后面写代码基本顺风顺水。反过来,如果硬件上有隐患,加再多的软件滤波也只是掩盖问题。
再分享一点扩展性建议:把本文提到的协议稍作改动,数据格式改成以JSON输出到串口,STM32F469II就可以轻松充当采集网关,把所有节点的温度上传给上位机或云端。我在项目里就是靠这套接口对接了第三方监控平台,省了单独再买采集器的钱。PASTime其实并不复杂,拆起来无非就是信号链加总线链路,每把一块环节吃透,就能从一个测温模块慢慢扩展成完整的物联网采集节点。而这也正是嵌入式和HVAC工程师进阶的价值所在。