☰
STM32F107VCT6与PJ85718DM结合:本地远程温度监测系统实战
2026/10/22 6:39:04 网站建设 项目流程

做嵌入式的朋友应该都有过这种经历:需求到手第一版往往不是算法,不是 UI,而是先把温度测准。我最近跑了一套环境监测的样机,核心就两样东西:一颗 Cortex-M3 内核的 MCU——STM32F107VCT6,加上一颗 I2C 接口的数字温度传感器——PJ85718DM。这套组合用在 HVAC(暖通空调)和一般嵌入式项目里做本地加远程温度监测,成本可控,代码量不大,稳定性也够用。这篇就聊聊我实际摸板子、调协议、跑联调的全过程,给准备做类似采集终端的同学一个可以抄作业的参考。

先说清楚这套系统能干什么:本地温度由主控板上的 PJ85718DM 直接采集,远程温度通过 RS-485 总线把分布在现场各处的传感器节点数据汇聚到主机,再经以太网把汇总数据上报到监控平台。HVAC 场景里就是测回风温度、送风温度、盘管温度,再加上远程几个房间的区域温度;嵌入式场景里则可以当通用的 IoT 温度采集终端用。无论你是刚接触 MCU 开发的新手,还是已经在做楼宇自控、工业数据采集的工程师,这套方案的硬件选型、软件架构和排障思路应该都能给你一些启发。

1. 项目整体设计与方案选型

1.1 为什么是 STM32F107VCT6

STM32F107VCT6 是 ARM Cortex-M3 内核,主频 72MHz,Flash 256KB,SRAM 64KB。选它不是因为性能有多逆天,而是这颗芯片自带 10/100M 以太网 MAC,还带 USB OTG、多路 UART/SPI/I2C、CAN 等外设。做远程温度监测,最关键的需求就是和外部通信,片上自带 MAC 能省掉一颗外部 MAC 芯片,硬件成本直接下降一块。

F1 系列的资料多,用的人多,出了问题也好查。我实际工程里用了 I2C1 接本地传感器,USART3 接 RS-485 收发器,ETH 接局域网,还剩不少资源可以扩展。如果项目后面要加多路 PID 控制、数据记录、人机界面,这个 Flash 和 RAM 也能撑住,不用换平台。

选型时另一个考量点是封装和温度等级。VCT6 是 LQFP100 封装,引脚多,方便扩展;我用的是 -40~85°C 的工业级版本,项目放在 HVAC 现场,夏天机柜里温度能到五十多度,工业级更稳。

1.2 PJ85718DM 传感器选型思路

PJ85718DM 是一颗数字温度传感器,走 I2C 或 SMBus 接口。相比传统 NTC 热敏电阻,最大的好处是不用做非线性校准,直接读出温度数值;相比 PT100,不用额外的 ADC 和信号调理电路,一颗芯片就搞定。

这颗传感器的精度在 ±0.5°C 级别,分辨率为 0.0625°C,量程覆盖 -55°C 到 +125°C。HVAC 场景主要测 -20°C 到 60°C 这一段,余量非常充足。工作电压 3.3V,静态电流很小,适合长期挂机。

我选它还有一个原因:寄存器结构比较常见,和主流数字温度传感器的操作逻辑很像,驱动代码移植和调试周期短。后面如果在量产阶段想换料,只要地址、寄存器偏移、数据格式调整一下,不用推翻整个驱动重写。

1.3 本地与远程温度的架构划分

标题里的“本地与远程”我拆成了两层含义。第一层是本机传感器直接读取,叫本地温度;第二层是远端的传感器节点,通过 RS-485 总线或以太网汇聚到主机,叫远程温度。

具体方案我做成这样:主机板(STM32F107VCT6 + PJ85718DM)负责本地温度采集和逻辑控制;远程节点板用同样的传感器加上 RS-485 收发器组网,主机通过 Modbus RTU 轮询各个节点,拿到所有温度数据。同时主机通过以太网把汇总后的数据上报到监控平台,实现“本地显示 + 远程看数”。

这个选型的理由很直接:RS-485 抗干扰强,最远能到 1200 米,适合 HVAC 现场多点分布;以太网上报方便和上位机或者云端对接。如果现场没有网线,还可以换 4G 网关或者 LoRa,但 RS-485 作为底层总线是最稳的选择。

1.4 方案对比:I2C 直连与总线组网怎么选

很多人会问,为什么不直接把所有传感器都挂到 I2C 总线上?I2C 总线确实可以挂多颗器件,但它适合板级通信,线缆一长、现场干扰一大,波形就会失真。所以板内用 I2C 没问题,跨机柜、跨房间就必须上 RS-485 或以太网。

我对比过三种方案:

方案通信距离抗干扰能力成本适用场景
I2C 总线直连1 米以内弱最低同一块板子上多路采集
RS-485 组网1200 米强低HVAC 现场多点分布
以太网组网100 米以上强较高需要接入局域网或云平台

结论就是:本地用 I2C 省成本,远程用 RS-485 保可靠,再叠加以太网上报给监控端。这套组合基本覆盖了绝大多数嵌入式温度监测需求。

2. 硬件电路设计要点

2.1 最小系统与电源设计

STM32F107VCT6 的最小系统不多展开,重点说几个容易踩坑的位置。电源用 5V 输入,经过 LDO 转 3.3V 给 MCU 和传感器供电。LDO 选低噪声型的,输出端要放 10uF 和 0.1uF 电容组合,靠近 MCU 的 VDD 引脚再放一个 0.1uF。ADC 采样稳不稳,很大程度取决于电源纹波。

复位电路用简单的 RC 复位:10K 电阻加 0.1uF 电容,按键可选。主晶振用 8MHz,并联一个 1M 电阻可以加快起振,两个负载电容按晶振手册选 18pF 左右。RTC 晶振我用 32.768KHz,如果不需要日历功能可以省掉。

关键提醒:I2C 引脚虽然有 5V 容忍特性,可以直接和传感器 IO 相连,但不能随便接其他 5V 信号。务必核对数据手册的 GPIO 结构描述,避免烧引脚。

2.2 PJ85718DM 接口电路

PJ85718DM 的 SCL/SDA 引脚必须接上拉电阻,4.7K 到 3.3V 是常规值。如果总线上只挂一颗传感器,这个阻值没问题;如果挂多颗,建议降到 2.2K,保证上升沿时间满足 400KHz I2C 速率的要求。

地址引脚按手册配置,一般有 A0/A1 引脚,可以组合出多个地址,这样一条 I2C 总线上能挂多颗传感器。HVAC 项目里一个板子要测好几路温度,比如回风温度、送风温度、盘管温度,这个特性非常实用。

PCB 布局上,传感器要远离 MCU 和电源芯片这些发热源。我第一版样机把传感器放在板边,旁边就是 LDO,结果温度读数凭空高了 3°C。后来把传感器挪到板边悬空区域,读数才恢复正常。这个自热干扰问题很多人会忽略,但实际影响非常大。

注意:PJ85718DM 的 VDD 引脚和 GND 之间一定要放 0.1uF 去耦电容,且尽量靠近传感器引脚放置。否则电源线上的高频噪声会影响转换精度,读数会出现周期性跳动。

2.3 RS-485 远程通信接口

远程采用 RS-485,收发器用常见的半双工芯片,接在 USART3 上。除了 A/B 两根线,还要把 RE 和 DE 合起来,用一个 GPIO 控制方向。A/B 线在总线最远两端要加 120Ω 终端电阻,中间节点不要重复加。上拉电阻和下拉电阻可以保证总线空闲时电平确定,避免接收乱码。

还要考虑防雷和静电。A/B 线对地各接一个 TVS 管,对电源再接一个。我有一版板子没加 TVS,现场有一次雷击浪涌,直接打坏了两块从机板。从那以后所有 RS-485 电路都默认加 TVS,成本不高,省心很多。

以太网接口用 RMII 模式接 PHY 芯片,STM32F107 自带 MAC,外部只需要一颗 PHY 和 50MHz 参考时钟。RMII 比 MII 少很多信号线,PCB 好布线,引脚占用也少。注意 REF_CLK 的产生方式要和 PHY 匹配,要么由 PHY 提供,要么由 MCU 提供,选一种,不要混。

2.4 PCB 布局与抗干扰处理

整体布局上,我把数字地和模拟地做单点连接,传感器和 RS-485 部分用模拟地或保护地分开铺。RS-485 接口放到板边,走线尽量短,避免和 I2C、以太网等高速信号平行。以太网差分对要按 100Ω 阻抗控制走线,等长更重要,弯折处用圆弧或 45°。

HVAC 现场常有水泵、变频器这些大干扰源,所以整板底部的铺地要完整,尽量不要被信号线切断。MCU 的 VDDA 引脚单独走线,再接一个磁珠到 3.3V。AD 基准稳了,温度读数的跳动会小很多。

传感器位置还要考虑实际风道方向。如果是测送风温度,传感器要对着气流方向,PCB 上留出开孔位置,不要让外壳挡住风道。这个细节在现场安装时经常让人头疼,设计阶段就要想好结构怎么配合。

3. 软件架构与核心实现

3.1 工程结构与任务划分

软件我不喜欢一个大 while 循环里塞满 if,而是按模块拆分。目录分驱动层和应用层:

/drv_temp_i2c.c /drv_rs485.c /drv_eth.c /app_local_monitor.c /app_remote_poll.c /app_network_report.c

驱动层只做寄存器操作和原始数据读写,应用层负责轮询、上报、报警。这样调试时可以用串口直接打印某一层的数据,不用翻整个工程。驱动层的函数命名也要统一,比如temp_i2c_init()、temp_i2c_read()、rs485_send_frame()、eth_publish(),后续维护一目了然。

系统初始化顺序也固定:关中断 → 时钟配置 → GPIO/外设 → 传感器初始化 → 以太网协议栈 → 应用任务 → 开中断。传感器初始化失败不要直接挂死,可以打印错误并继续启动,等下次轮询再尝试恢复。

3.2 I2C 读取温度的寄存器操作

PJ85718DM 温度读取的基本流程是:先写配置寄存器,设定分辨率和工作模式;然后读状态寄存器,判断数据是否更新;最后读温度寄存器的两个字节,拼成 16 位,再除以分辨率系数得到实际温度。

关键代码示例:

#include "drv_temp_i2c.h" #define PJ85718_I2C_ADDR 0x48 // 根据地址引脚配置 #define REG_CONFIG 0x01 #define REG_TEMP_MSB 0x02 #define REG_TEMP_LSB 0x03 static I2C_Handle *hpi2c; void temp_i2c_init(I2C_Handle *hi2c) { hpi2c = hi2c; uint8_t cfg = 0x60; // 12-bit 分辨率,持续转换模式 i2c_write_register(PJ85718_I2C_ADDR, REG_CONFIG, &cfg, 1); } float temp_i2c_read(void) { uint8_t reg = REG_TEMP_MSB; uint8_t buf[2]; int16_t raw; i2c_write(PJ85718_I2C_ADDR, &reg, 1); i2c_read(PJ85718_I2C_ADDR, buf, 2); raw = ((int16_t)(buf[0] << 8) | buf[1]) >> 4; // 右移4位对齐12位 return (float)raw * 0.0625f; }

注意点:读温度前要确保数据更新完成,否则会读到上一次的数据。如果发现读数一直不变,多半是配置寄存器没写进去,或者 I2C 通信被中断打断。用逻辑分析仪抓波形,能立刻看出来是不是应答位异常。还要注意低温下的代码规范:buf[0] << 8如果 buf 是 uint8_t,左移后会变成 int,需要显式转成 int16_t,否则负温度会算错。

3.3 远程节点数据采集:RS-485 + Modbus RTU

远程节点采用 Modbus RTU 协议,每台从机有独立地址。主机轮询流程:发送请求帧 → 等待从机应答 → CRC 校验 → 解析温度。超时时间我设为 50ms,通讯波特率 9600bps,这个组合在现场最稳定。

Modbus RTU 帧格式:地址码 1 字节、功能码 1 字节(读保持寄存器用 0x03)、起始地址 2 字节、寄存器数量 2 字节、CRC16 2 字节。

CRC 计算代码:

uint16_t crc16_modbus(const uint8_t *data, uint16_t len) { uint16_t crc = 0xFFFF; for (uint16_t i = 0; i < len; i++) { crc ^= data[i]; for (uint8_t bit = 0; bit < 8; bit++) { if (crc & 0x0001) crc = (crc >> 1) ^ 0xA001; else crc >>= 1; } } return crc; }

RS-485 方向控制是最大的坑点。发送前要把 DE 拉高,发送完最后一字节后要延时一小段时间再拉低,否则最后一个字节的后半段会被打断,对端 CRC 必然出错。延时时长和波特率相关,9600 波特率下一字节大约 1.04ms,我一般延时 2ms 再切换方向,留出足够余量。

轮询多台从机时,还要处理从机无应答的情况。连续三次超时后把该节点标记为离线,不要卡死整个轮询循环。HVAC 项目里节点掉线是常有的事,能自动重连比什么都强。

3.4 以太网上报与远程监控

STM32F107 片上以太网 MAC 配合 LWIP 协议栈,跑 MQTT 客户端把温度数据上报到本地服务器或者云平台。LWIP 的内存配置很关键,内存池太小会导致丢包,温度数据如果丢几包,上位机曲线会出现缺口。我调过的最小可用配置:PBUF 池 16 个,TCP 同时连接 4 个。

MQTT 上报的数据格式用 JSON:

{ "device": "AHU-01", "local_temp": 24.31, "remote": [ {"addr": 1, "temp": 24.12}, {"addr": 2, "temp": 23.98} ], "timestamp": 1717459200 }

MQTT 主题按设备划分,报警消息单独走一个主题。这样监控平台可以订阅报警主题,第一时间触发告警。我还在本地做了掉线缓存,网络断开时数据先存 Flash,等恢复后批量补传。这个功能在 HVAC 现场很实用,因为现场网络经常波动。

3.5 报警与数据处理逻辑

温度报警不能简单用一个固定阈值,我做了两级报警:软报警和硬报警。软报警是指温度连续 5 次采集超过设定值,但还没有到危险程度,只上报事件;硬报警是指温度超过二级阈值,或者连续 10 次超过一级阈值,立即触发报警输出,同时控制继电器动作。

从机制上要防止传感器单次毛刺引起误报,所以报警判断必须基于连续多次采样。如果一次读到 80°C,下次又变成 25°C,这种跳变应该被丢弃,而不是直接触发报警。我代码里加了简单的滑动滤波,取最近 5 次采样的中位值,能有效滤掉干扰脉冲。

4. 联调过程与性能测试

4.1 本地温度采集与精度验证

先把本地温度调通,串口打印温度值,和数据手册上已知的参考温度做对比。我用冰水混合物做 0°C 参考、沸水做 100°C 参考,但实际 HVAC 场景一般只用到 0~60°C,所以重点测的是 20~30°C 段。

实测 PJ85718DM 在 25°C 环境下,读数稳定在 25.06~25.12°C 之间,跳动范围 0.06°C,这个表现比我预期好。上电瞬间会有一个较大的跳变,那是传感器自身热平衡还没建立,软件里做了上电后 2 秒的无效数据丢弃。

对比不同位置的传感器时,要注意传感器之间的一致性。我在批测时发现,同一批次的 PJ85718DM 最大偏差大约 0.3°C,属于正常范围。如果项目要求高精度配对,可以在生产线上加一步校准,把每颗传感器的偏移量写进 Flash,开机时自动补偿。

4.2 总线组网与长距离传输实测

RS-485 总线我挂了 8 个从机节点,总线长度大约 300 米。用 9600bps 轮询,单节点响应时间大约 20ms,轮询完 8 个节点耗时 500ms 以内,完全满足需求。总线末端加 120Ω 电阻后,波形明显改善,以前偶发的 CRC 错误基本消失。

如果总线超过 500 米,建议把波特率降到 4800 或者 2400,传输更稳。还有一种方法是使用屏蔽双绞线,屏蔽层单端接地,能进一步降低共模干扰。我试过一边走变频器电缆一边跑 RS-485,不屏蔽时数据直接乱跳,换了屏蔽线就好了。

在并联多个从机时,还要注意每个从机的偏置电阻不要太多。有些模块自带上拉下拉电阻,如果 8 个节点都带,并联阻值会太低,导致总线负荷过大,波形变差。最好只在主站端加偏置,从机端只用终端电阻。

4.3 系统稳定性与功耗

连续运行 48 小时,设备没有死机,温度数据连续,网络没有断线。我开着独立看门狗,喂狗放在主循环,如果某个任务卡死 3 秒以上,系统自动重启。喂狗的位置很讲究,不能放在中断里,否则主循环卡死时看门狗照样被喂,起不到保护作用。

功耗方面,这套系统整体电流大约 180mA@5V。对固定供电的设备来说不算问题;如果要用电池供电,就需要做低功耗模式:把传感器和 RS-485 收发器都通过 MOS 管控制断电,MCU 进入 STOP 模式,每隔 30 秒唤醒一次采集。我做的一版低功耗样机,平均电流降到 15mA 左右,4 节 18650 电池可以支撑很久。

4.4 高低温环境测试

HVAC 设备经常要在极端环境下工作,所以我做了简单的环境箱测试。温度从 -10°C 升到 60°C,每 5°C 记录一次读数,和设备内部参考传感器对比。结果发现 PJ85718DM 在高温段偏差略大,60°C 时偏差约 0.4°C,但仍在规格范围内。

这里有个小技巧:环境箱里的设备要提前一小时开机预热,让整个板子达到热平衡后再记录数据。否则 PCB 和外壳的热容量会影响读数,得到的变化曲线会滞后于环境箱实际温度。

5. 常见问题与排查技巧

5.1 温度读数跳变或读到 0xFF

  • 检查 I2C 地址是否正确,用 I2C 扫描程序枚举所有地址,看能否扫到设备。
  • 检查 SCL/SDA 上拉电阻,没有上拉或者阻值太大时,波形上升沿变缓,时序不稳定。
  • 检查传感器供电是否稳定,某些 LDO 在负载突变时输出电压有纹波,会影响转换结果。
  • 检查是不是中断把 I2C 时序打断了,如果系统里有高频中断,建议在 I2C 传输期间关中断或用 DMA。

5.2 远程节点掉线或数据错误

  • 先确认从机地址不冲突,多台从机不能重复地址。
  • 检查 CRC 校验,把收到的原始数据用 CRC 工具对比,确认是发送端还是接收端的问题。
  • RS-485 方向切换要留足够时间,发送结束后 delay 2ms 再接收。
  • A/B 线极性接反,表现是收不到任何正确数据,交换两根线试试。
  • 用示波器看 A/B 线的差分波形,正常时应该是清晰的方法,如果波形变形严重,大概率是终端电阻或偏置问题。

5.3 以太网偶发断开

  • 检查 PHY 复位电路,复位引脚上一定要有上拉电阻,否则复位不彻底。
  • RMII REF_CLK 频率必须准确,用示波器看是否稳定在 50MHz。
  • 网线用超五类以上,长度超过 50 米时建议用屏蔽工业网线。
  • LWIP 的 TCP 超时时间可以适当放宽,避免现场网络抖动导致频繁重连。
  • 检查 DHCP 获取地址是否超时,如果现场没有 DHCP 服务器,要改成静态 IP,否则上电后要等很久才能连上网络。

5.4 HVAC 现场特有的干扰问题

HVAC 现场最典型的干扰源是变频器和电磁阀。变频器启动瞬间,RS-485 总线上会出现大幅度的共模电压跳变,严重时直接打坏收发器。对策是:RS-485 隔离。用带隔离的收发器模块,或者加数字隔离器,把 MCU 和总线彻底隔开。我后来在关键项目里都用了隔离方案,现场可靠性明显提升。

电磁阀通断产生的火花干扰会影响 I2C 排线,解决办法是传感器线缆用屏蔽线,屏蔽层单端接地,并且尽量避免和强电走同一个线槽。

调试工具组合建议:逻辑分析仪抓 I2C 波形、串口助手打印 Modbus 帧、示波器看 RS-485 差分波形和以太网 REF_CLK。这三个工具能覆盖 90% 的故障场景。

最后说说我个人在实际操作中的体会。做这类温度监测项目,最容易翻车的不是代码,而是硬件布局和通信细节。传感器离热源太近、RS-485 方向切换太快、以太网复位不彻底,这些问题实验室里很难复现,一到现场就全冒出来了。所以我现在做项目的顺序是:画板子时就考虑散热和隔离,然后写驱动并配两级串口打印,最后才接入协议栈。排查问题的时候先把链路拆开,一段一段验证,不要上来就怀疑协议栈,多数问题都出在物理层。

还有一个很实用的小技巧:如果现场需要做高精度温度测量,可以在设备启动后先测 10 分钟数据,取平均值作为基准偏移,之后每次读数减掉这个偏移。这个方法比单纯依赖传感器出厂精度更靠谱,尤其是长期运行的老化漂移,可以通过定期校准来消除。这套 PJ85718DM 加 STM32F107VCT6 的组合,我目前还在扩展多通道采集和 PID 联动,等新版本跑通了再来更新细节。

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

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

立即咨询