☰
基于STM32F303RE与PJ85718DM的单总线温度监测系统设计
2026/10/22 16:58:34 网站建设 项目流程

去年做一套风机盘管控制器的升级项目时,我第一次把 PJ85718DM 和 STM32F303RE 放在同一块主控板上处理温度监测。当时手里可选方案不少:NTC 热敏电阻便宜但一致性让人头疼,PT100 精度高却要额外的调理电路,I2C 数字传感器布线距离又卡得很死。PJ85718DM 这种单总线数字温度传感器,正好绕开了前面几个坑,再配合 STM32F303RE 在模拟采集和实时控制上的底子,一套方案就把“本地温度 + 远程多点温度”全包了。这篇文章会把完整的选型逻辑、电路连接、单总线驱动、HVAC 联动控制,以及调试阶段踩过的那些坑全部整理出来,给准备做嵌入式温控、楼宇自控或环境监测项目的朋友一份能直接照着干的参考。

1. 项目全貌:拆解这套温度监测系统

1.1 标题背后到底对应什么工况

很多人第一次看到“本地与远程温度监测”这个说法,会下意识把它理解成“传感器测到温度然后上传到云平台”。但在 HVAC 和嵌入式现场,这个描述通常更具体,指的是一个控制器同时要管两类温度点:

第一类是本地温度,也就是主控板自己周围的温度。比如控制盒内部温度、进风口温度、功率器件附近的温度。这类温度传感器离 MCU 很近,走线短,干扰小,主要用于设备自身保护和控制器工作环境判断。

第二类是远程温度,指的是分布在远处的温度点。在风机盘管系统里,可能是放在房间墙上的回风温度传感器;在新风系统里,可能是埋在风道里的送风温度传感器;在冷库里,可能是伸进库体内的测温探头。这类传感器的共性是离控制器有一段物理距离,少则几米,多则几十米,需要线缆连接。

PJ85718DM 的单总线结构就特别适合这种场景。它内部自带 64 位唯一序列号,一根数据线上可以挂多个传感器,主机通过序列号就能区别读取每一个节点。这意味着从控制器引出去到各个房间、风道、水箱的测温线,最终可以汇到同一条总线上,极大地减少了接线端子数量和布线工作量。

真正把这套系统用起来的场景,比如一类恒温恒湿机:控制器安装在配电柜里,柜内要测控制盒温度,这是本地;机组出风口、回风口、水管的进出水温度都要实时监控,这些是远程。如果每个远程点都拉一条 I2C 或 SPI 专用线到 MCU,线材成本和抗干扰处理都会让人崩溃。

1.2 器件选型的三个关键考量

选 STM32F303RE 而不是用更便宜的 8 位单片机,是基于三个实际因素。

第一个因素是单总线驱动需要精确的微秒级延时。单总线时序对延时窗口要求比较高,虽然 8 位单片机也能做,但在敲定方案时,我们需要预留以后扩展空气品质传感器、流量计、风阀执行器的通信接口资源,这时候选择一颗带更多定时器、更多串口和 DMA 的 M4 内核芯片更从容。STM32F303RE 主频 72MHz,Flash 512KB,RAM 64KB,执行单总线时序时误差控制容易得多。

第二个因素是 STM32F303RE 的模拟外设在同类 MCU 里属于很扎实的水平:快速 ADC、比较器、运算放大器一应俱全。这意味着后续如果想在温度之外增加压力传感器、电流检测或者热电偶冷端补偿,硬件上不需要再外挂太多芯片。实际项目中,我们后来就用它内部运放做了一个模拟备用温度通道,相当于多了一层冗余保护。

第三个因素是成本和供货稳定性。在 HVAC 行业,控制板的生产周期长,器件选型必须考虑多源替代。PJ85718DM 这类芯片因为引脚兼容、命令兼容,替换成本极低,而 STM32F303RE 作为成熟型号,供应链也相对稳定。

1.3 系统架构总览

整台控制器从功能上可以分成三层:

采集层由若干 PJ85718DM 温度传感器构成,本地总线上挂一颗板载传感器,远程总线上挂多颗外部传感器。为了方便故障隔离,我在软件上把本地和远程分成了两条逻辑总线,物理上使用两个不同的 GPIO 引脚。

控制层由 STM32F303RE 完成:周期性启动温度转换,读回原始寄存器值,做滤波和校准,然后跑 HVAC 控制逻辑。控制输出可以是继电器开关量,也可以是 PWM 驱动风机或无级调节电动阀。

通信层主要负责把温度数据和设备状态上报给楼宇上位机。我们用的是 RS485 Modbus RTU,寄存器表里开放了温度、设定值、报警状态等参数。这样既方便现场触摸屏直接读取,也能无缝对接楼宇自控系统。

2. 硬件设计与电路搭建

2.1 PJ85718DM 的供电方式与引脚处理

PJ85718DM 的典型工作电压是 3.0V 到 5.5V,在 HVAC 控制板上一般直接使用 5V 供电。因为系统里可能有继电器、风机、电动阀,电源环境相对脏,我在传感器供电入口处加了磁珠和 100µF 电解电容,再并联一个 0.1µF 高频旁路电容,这样电机启停造成的电压跌落对传感器的影响会小很多。

这颗芯片支持寄生供电和外部供电两种模式。寄生供电意味着传感器直接从数据线上取电,理论上可以少拉一根电源线。但我做过测试,在远程线长超过 10 米以后,寄生供电在温度转换瞬间会因为电流骤增导致电压崩溃,表现出来就是读到 0xFFFF 或者 CRC 校验错。所以我的建议很直接:远程节点一律采用外部供电,三线制连接,分别是 VCC、DQ、GND。

本地传感器我一般直接焊接在 PCB 上,走线短,接线反而没那么多讲究。DQ 引脚通过一个 4.7kΩ 上拉电阻接到 5V,然后连接到 MCU 的 GPIO。这里有一点要注意,单总线设备在常态下总线是高电平,所有通信动作都是主机把总线拉低特定的时间,所以 GPIO 必须配置成开漏输出加外部上拉。

2.2 本地与远程节点的接线拓扑

本地总线和远程总线虽然使用同一套驱动代码,但物理拓扑我做了不同设计。

本地总线上通常只有一颗传感器,甚至可以考虑焊两颗做冗余。板内走线控制在 5 厘米以内,上拉电阻用 4.7kΩ,时序最稳定。远程总线则由接线端子引出,连接多个外部传感器。远程传感器之间采用“菊花链”或者从总线中段分支都行,单总线本身对拓扑结构不敏感,但要注意不能让信号线形成很长的主干末端悬空,末端最好就近放一个上拉电阻。

远程线建议使用 3 芯屏蔽线,线径至少 0.5mm²,屏蔽层在控制器端单点接地。如果你正好把传感器延伸到强电接触器或变频器附近,屏蔽层必须接好,否则干扰会直接窜进单总线时序。

我在项目中远程总线挂了 8 个传感器,总长度约 60 米,使用 1kΩ 上拉电阻后波形依然干净。上拉电阻阻值怎么选,其实是总线长度和功耗的权衡:4.7kΩ 适合短距离低功耗,长线远距离用 1kΩ 更可靠,代价是常态电流稍大。

2.3 PCB 布线与线缆端接的几个细节

PCB 布局上有一个容易被忽略的地方:温度传感器采集引脚不要放在继电器或者开关电源的干扰源正下方,尤其是远程总线的 DQ 走线,尽量远离高频开关节点。如果板子面积紧张没办法完全避开,可以在 DQ 线旁边加一条地线做包地处理。

另外,虽然 STM32F303RE 的 GPIO 内部有上拉电阻,但内部上拉阻值一般偏大,对长线单总线来说不够用。所以必须使用外部上拉电阻,阻值选择范围我建议:

总线长度上拉电阻传感器数量说明
< 1m4.7kΩ1~3 颗板内本地总线
1~10m3.3kΩ1~5 颗小范围设备
10~60m1kΩ3~8 颗工程现场远程总线
> 60m1kΩ + 末端上拉视情况需注意干扰

线缆端接方面,远程线进入控制器后,我通常会串一个小磁环,能有效抑制共模干扰。传感器端如果是防水的接线盒或探头,最好做整体灌胶密封,防止潮湿环境造成端子氧化和触点接触电阻漂移,这个问题在冷冻水系统中特别常见。

3. 软件驱动与单总线通信实现

3.1 单总线时序与 GPIO 配置

单总线通信其实非常像一段“拉低总线不同时间”的编码游戏。主机通过拉低总线的长度来写 0 或写 1,传感器通过拉低总线的长度来表示响应或读数。PJ85718DM 沿用单总线体系的标准命令集,所以驱动可以直接按这套时序来写。

我在 STM32F303RE 上使用 GPIO 的结构体配置方式,把 DQ 引脚设置为开漏输出模式,输出速度选择中等即可,不需要开最高翻转速度。初始化时默认输出高电平,总线处于空闲状态。

复位时序是最基础也最容易出错的环节。主控先把总线拉低 480µs,再释放总线,传感器收到复位后会在 60µs 到 240µs 内拉低总线,表示存在。主机在释放总线后大约 70µs 时读取电平,如果读到低电平就说明有设备在线。

uint8_t OW_Reset(void) { uint8_t presence; OW_PIN_LOW(); DelayUs(480); OW_PIN_HIGH(); DelayUs(70); presence = OW_PIN_GET() ? 1 : 0; // 0 表示传感器拉低了总线 DelayUs(410); return presence; }

这里有个我调过的坑:复位脉冲时间如果偏短,比如只有 400µs,部分传感器会不响应;但如果太长,超过 960µs,总线会进入强上拉状态,影响后续时序。所以延时函数的精度非常重要。STM32F303RE 主频 72MHz,用 SysTick 做微秒延时是完全够用的,不要在驱动里简单嵌套空循环,因为编译器优化等级不同会直接改变空循环耗时。

3.2 读写位时序与字节收发

写时序的基础单位叫“时隙”。写逻辑 0 时,主机拉低总线至少 60µs,然后释放;写逻辑 1 时,主机拉低总线 6µs 后立即释放,靠上拉电阻把总线拉高。传感器在总线拉低后的 15µs 到 60µs 窗口内采样总线电平,从而判断写入的是 0 还是 1。

void OW_WriteBit(uint8_t bit) { if (bit) { OW_PIN_LOW(); DelayUs(6); OW_PIN_HIGH(); DelayUs(60); } else { OW_PIN_LOW(); DelayUs(60); OW_PIN_HIGH(); DelayUs(6); } }

读时序类似,主机拉低总线 6µs 后释放,然后需要在 4µs 到 15µs 之间的时间窗口内采样总线电平。传感器如果是逻辑 1,总线会保持高电平;如果是逻辑 0,传感器会继续拉低总线。

uint8_t OW_ReadBit(void) { uint8_t bit; OW_PIN_LOW(); DelayUs(6); OW_PIN_HIGH(); DelayUs(4); bit = OW_PIN_GET(); DelayUs(55); return bit; }

写字节和读字节都是低位先出。实际工程中,每次执行完一个完整命令再读数据时,我会把延时稍微放宽到接近时序窗口上限,因为 MCU 主频高,中断如果打断 GPIO 时序,会导致采样点偏移。所以我在单总线收发期间会关掉某些非关键中断,或者用临界区保护整个字节传输过程。

3.3 多设备寻址与 ROM 匹配

单总线系统里每个 PJ85718DM 都有 64 位 ROM 序列号,其中 8 位是家族码,48 位是唯一序列号,8 位是 CRC 校验。主机要读取指定传感器,必须先发送匹配 ROM 命令,把完整 64 位序列号发上总线。

第一次使用这套系统时,可以采用搜索 ROM 命令来枚举总线上所有传感器序列号。搜索算法本质上是二叉树遍历,会反复读写位来判断每个传感器在某一位上的取值和取反情况。实际项目里,如果不是特别必要,我不建议每次开机都做 ROM 搜索,这个流程比较耗时,而且一旦遇上干扰容易漏检设备。

更稳妥的做法是在生产调试阶段把每个传感器序列号读出来,写进配置表烧录到 MCU 的 Flash 里。正式运行时直接按配置表逐一轮询,速度快,流程简单。如果现场要更换传感器,只需要更新配置表即可。这在批量制造里也能简化测试过程:每块控制板出厂前烧录一次地址表,避免每次上电跑搜索。

读取温度时有两种策略。如果总线上有多个传感器,建议先广播启动温度转换命令,让所有传感器并行工作,等待一段时间后再逐个匹配 ROM 读取温度结果。这样做的好处是省掉了串联等待的转换时间。

上面这段涉及命令代码,我把标准单总线指令整理成表格方便对照:

命令名称命令字节功能说明
搜索 ROM0xF0枚举总线上所有设备序列号
读 ROM0x33直接读取唯一设备的序列号
匹配 ROM0x55指定某个系列号设备通信
跳过 ROM0xCC对总线上所有设备广播命令
启动温度转换0x44使传感器开始温度采集
读取暂存器0xBE读取温度值和配置字节

广播启动转换的命令顺序是:复位,发送 0xCC,发送 0x44。然后主机等待最大转换时间。12 位分辨率下典型转换时间约 750ms,如果系统要求响应快,也可以配置到 9 位分辨率,转换时间大幅缩短,但温度分辨率会降到 0.5°C。HVAC 场景一般用 10 位或 11 位就能满足舒适度控制需求,我实际测试下来,10 位模式配合滤波算法比 12 位模式更省电。

3.4 本地与远程温度采集的任务调度

整个温度采集任务,我写成有限状态机而不是简单的顺序阻塞流程。因为在远程总线比较长时,等待温度转换的 750ms 内可以做很多别的事情,比如刷新显示、处理 Modbus 通信、巡检报警输入。

状态机分为三个状态:第一是 IDLE 状态,检查距离上一次采样的时间是否超过周期;第二是 CONVERT 状态,广播启动转换并记录启动时刻,然后直接退出让出 CPU;第三是 READ 状态,等到定时器时间超过转换周期后,逐个读取传感器温度。

这样设计的好处是 CPU 利用率很高,也方便上层控制逻辑随时获取最新的温度数组。在 STM32F303RE 上,我用一个软件定时器周期调度,基本不占用额外硬件定时器。

采集周期方面,HVAC 应用不需要很高的频率。传感器 12 位模式典型转换时间 750ms,即使每 2 秒采一次,控制周期也完全够用。但如果控制对象是电动调节阀或变频风机,1 秒以内的高频采样反而会让控制量抖动。我通常把温度采集周期设在 1 到 2 秒,PID 调控周期设在 500ms 到 1 秒之间。

4. 数据处理、HVAC 联动与应用层设计

4.1 温度解析、滤波与校准

PJ85718DM 的温度寄存器是 16 位,低 4 位为小数部分,每 LSB 对应的温度步进是 0.0625°C。解析时要注意负数场景:当环境温度低于 0°C 时,寄存器值是二进制补码,直接除以 16 会得到错误结果,需要先判断符号位。

我在驱动里统一把原始 16 位值转换成 float 温度值:

float DecodeTemp(uint16_t raw) { if (raw & 0x8000) { raw = (~raw) + 1; return -((float)raw) * 0.0625f; } return ((float)raw) * 0.0625f; }

读回来以后,原始数据还要过一道滤波。温度对象的热惯性很大,本身不会突变,所以我用一阶低通滤波,系数 α 取 0.2 到 0.3。这样既能平滑短期扰动,又不会让控制回路产生明显滞后。

校准是另一个必须做的环节。虽然芯片出厂标称精度不错,但 HVAC 现场往往要求整个测温链路与标准温度计一致。我喜欢用两点校准:将传感器和标准温度计同时放入冰水混合物,得到一个偏移量;再放入 50°C 左右的水浴,计算增益误差。然后把偏移和增益参数储存在 MCU 的 Flash 里,程序里对每个通道独立校准。

4.2 PID 控制与开关量迟滞

温度监测只是系统的眼睛,眼睛看到温度后还要让执行器做动作。在典型 HVAC 温控器中,有两条控制路线:一条是给压缩机、电加热器用的开关量控制,一条是给风机、电动阀用的连续量控制。

开关量控制最怕继电器频繁启停。压缩机如果每小时启停次数超过 6 次,寿命会急剧下降。所以我用迟滞比较实现开关量控制:设定目标温度 24°C,允许偏差 ±0.5°C,温度高于 24.5°C 开启制冷,低于 23.5°C 关闭制冷。这样即使温度轻微波动,继电器也不会跟着乱跳。

连续量控制我用位置式 PID 算法。由于温度变化慢,微分项容易放大噪声,我通常把微分系数调得很小,甚至直接用 PI 控制。前面的滤波已经滤掉了大部分噪声,但积分项还需要做抗饱和限制,否则在传感器异常或执行器卡住时,积分值会积累到一个离谱的程度,恢复时会造成大幅超调。

PID 的输入是设定温度和当前测量温度,输出经过限幅后映射到 PWM 占空比。对于风机盘管,PWM 频率选在 10Hz 左右,输出 0% 到 100% 对应风机低、中、高三速和无级调节。

4.3 远程通信与数据上报

温度数据不仅要在本地显示,还要上报给上位系统。我们使用 RS485 总线加 Modbus RTU 协议,STM32F303RE 的 USART 配合方向控制引脚实现收发切换。波特率通常配 9600 或 19200,楼宇自控系统更偏好低速高稳定性。

Modbus 寄存器表设计要清晰,我最常开放的寄存器是:

寄存器地址读写权限内容
0x00只读本地温度,带一位小数
0x01只读远程温度 1
0x02只读远程温度 2
0x10读写目标温度设定值
0x11读写控制模式开关量
0x20只读报警状态字

温度数据在寄存器里使用整数表示,比如 23.4°C 存为 234。这样上位机解析时不需要处理浮点字节序,对大多数触摸屏和组态软件都友好。报警状态字每一位对应一种异常:传感器断线、超温、低温防冻、通信丢失等。

4.4 扩展与低功耗考虑

这套系统如果做物联网网关或者电池供电的采集节点,还可以加入低功耗逻辑。PJ85718DM 在空闲态电流很小,只有在温度转换时会有一个短暂的电流峰值。远程传感器在非采样时段可以断电,采样前再上电,这样能显著降低总功耗。

STM32F303RE 进入停止模式前,需要先完成温度转换并保存结果。因为唤醒后从 Flash 重新初始化到温度稳定,可能需要几十毫秒,这个时间对于 HVAC 这种秒级控制周期来说完全能接受。

5. 调试经验与故障排查实录

5.1 常见问题速查表

我把调试阶段遇到过的问题直接整理成一张表,照着查会比翻手册快得多:

现象可能原因解决办法
总线上搜不到任何设备上拉电阻缺失或复位脉冲太短检查 DQ 上拉,拉长复位信号
偶尔读到 0xFFFF传感器被干扰,或供电跌落改用外部供电,加屏蔽线
CRC 校验频繁失败线缆过长或采样点偏移换 1kΩ 上拉,关中断收发
最后一个传感器总无响应分支过长或末端反射末端加上拉,或缩短分支
温度读数跳变滤波缺失或传感器接触不良软件滤波,检查接线端子
传感器发热影响精度传感器靠近功率器件或电源重新布置本地传感器位置

5.2 远程线过长导致的时序异常

在项目现场遇到最典型的问题是:远程总线 40 米以上时,偶尔有传感器读不到。用示波器看波形后发现,总线拉低后的下降沿很陡,但释放后的上升沿明显变缓。原因是线缆分布电容太大,上拉电阻阻值偏高,导致总线电压不能在传感器采样窗口内恢复到高电平。

我把上拉电阻从 4.7kΩ 改成 1kΩ 后,上升沿明显改善。另外,我还在总线末端也加了一颗 1kΩ 上拉电阻,相当于并联把等效上拉阻值进一步降低,最终 60 米总线完全稳定。

但上拉电阻并不是越小越好。阻值太小会让总线常态电流增大,如果传感器数量多、供电线长,远端传感器供电端电压反而会被拉低。所以长线调试时一定要同时观察 DQ 波形和传感器供电电压,两边都不能忽略。

5.3 精度校准的具体操作流程

校准听起来复杂,实际操作一次其实很简单。我把远程传感器和一根精度较高的玻璃温度计一起放到保温杯里,等温度稳定后记录芯片读数和标准值。然后在另一个温度点做第二组记录。

假设在 0°C 附近芯片读数为 0.4°C,在 50°C 时芯片读数为 50.3°C。那么偏移项是 0.4°C,增益项是 (50.3 - 0.4) / 50 = 0.998。最终校准补偿公式为:

真实温度 = (芯片读数 - 偏移) / 增益

这个公式和计算过程直接写进上位机调试页面,让产线工人根据标准表输入两个点的实际读数,MCU 自动计算并存储校准参数,不用人为手算,减少出错概率。

5.4 极端环境下的可靠性验证

我在高温和低温两种环境下做了老化测试。高温环境中,板载本地传感器靠近 MOS 管散热片,整个控制器在 60°C 环境下连续运行,本地温度能稳定反映机箱内部温升,与热像仪测量结果吻合。低温环境中,把远程传感器放入 -20°C 环境箱,读数依然稳定,没有出现掉线和漂移。

需要特别提醒的是:远程传感器探头如果用于低温水管防冻监测,传感器本身必须做防水密封处理。我见过有现场探头进水后读数异常的情况,拆开后发现线缆接口处已经锈蚀。后面全部换成灌胶封闭的防水探头,再没出现过这类问题。

我自己调试时的体会是,单总线温度采集本身不难,真正决定系统可靠性的往往是那些跟芯片手册无关的细节:电源干净不干净、线缆粗细合不合适、屏蔽层怎么处理、校准参数有没有办法快速写入。把这些基础工作做扎实了,PJ85718DM 和 STM32F303RE 这套组合,足以在大多数 HVAC 和嵌入式温控场景里长期稳定运行。后面如果你在这个基础上继续扩展湿度传感器、压力传感器,通信架构和控制分层依然不用推翻重来。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询