首页 / 资讯中心 / 文章详情

基于STM32和RS485总线的嵌入式温度监测系统设计要点

基于STM32和RS485总线的嵌入式温度监测系统设计要点 ★ FEATURED ARTICLE
干嵌入式这行有些年头了温度监测这类活听起来简单真正落地的时候坑一点不比通信协议少。最近我完成了一套基于 STM32F746ZG 与 PJ85718DM 的温度监测系统用在集中式 HVAC 设备的控制器上要求同时监控本地机柜内温度和远端风管、回风口的温度既要本地实时显示又要通过总线上送给上层监控。整个项目从需求拆解、硬件设计、固件开发到现场联调前后花了大概三周时间踩了不少坑也沉淀出一套比较顺手的做法。这篇文章就把整个方案的选型逻辑、系统架构、固件实现和现场排查经验完整展开给正在做嵌入式温度采集、HVAC 控制器或者工业现场远程监测的朋友一些可以直接参考的东西。1. 项目需求拆解与核心选型逻辑1.1 HVAC 场景对温度监测的真实需求HVAC 系统里的温度监测远不止“读个数”这么简单。我拆解下来整个需求分三个层面。第一个层面是本地温度监测。控制器本身装在现场电控箱里箱内散热条件差夏天柜内温度可能比环境高十几度MCU、电源模块、继电器长期在高温下工作寿命会明显缩短。所以本地温度监测要盯的是“控制器自己活得好不好”一旦柜内温度超过阈值要能报警或者自动降载。第二个层面是远端温度采样。风管送风温度、回风温度、室内温度都是 HVAC 闭环控制的直接输入量控制器要依据这些温度算阀门开度、风机转速、冷热水流量。这类温度点和控制器主板的物理距离可能从几米到几十米不等没法用简单的模拟量线直接拉过去必须有一个适合工业现场的长距离传输方案。第三个层面是系统集成。HVAC 项目里温度数据不光给自己用还要给楼宇自控系统BAS或者上位机监控平台。这就意味着数据接口要规范要能稳定地往外吐数据最好还支持远程配置传感器地址、校准偏移之类的操作。把这三点想清楚之后方案的基本框架就浮出来了主控负责本地采集、算法处理和对外通信远端分布的温度采集节点通过总线汇入主控。这套“本地远端”的双层架构是我在同类项目里验证过最稳的形态后续所有设计都围绕它展开。1.2 主控选型为什么最终落在 STM32F746ZG项目里需要一个具备以下能力的主控算力足够跑滤波算法和人机界面外设接口要覆盖显示、通信、存储最好还能留出余量做后续功能扩展。当时对比过几类方案低成本 M0/M3 内核芯片、带以太网的 M4 内核芯片以及 Cortex-M7 内核的 STM32F746ZG。前两类在裸机小系统里确实够用但一旦要同时跑图形界面、Modbus 总线管理和温度控制 PID资源就捉襟见肘了。STM32F746ZG 打动我的点有三处。第一Cortex-M7 核心跑到 216MHz带 DSP 指令做温度滤波和 PID 运算几乎不占 CPU 时间。第二片上有 1MB Flash 和 320KB SRAM跑一个轻量级 GUI 界面、Modbus 协议栈和 RTOS 毫无压力。第三外设非常齐全多个 UART 可以一条专跑 RS485 总线、一条做调试、一条给外部扩展硬件 TFT LCD 控制器直接省掉一颗显示驱动芯片加上 Ethernet MAC、SDMMC 接口后续要加历史数据存储或者网络上传都很顺手。实际开发中还有一个容易被忽略的点就是这颗芯片的调试工具链非常成熟。遇到问题的时候不管是 IDE 调试还是逻辑分析仪抓信号参考案例和社区讨论都很多这对项目周期紧张的现场调试来说价值非常大。1.3 远程测温模块PJ85718DM 的角色定位远端的温度采集节点最终选了 PJ85718DM。这颗模块在这个项目里的定位就是“把远端温度变成总线上的数字报文”。PJ85718DM 本身集成了温度传感和总线通信功能支持标准的工业总线协议测温范围覆盖 HVAC 场景绰绰有余分辨率也足够做温控闭环。更重要的是它支持总线供电和组网多个模块可以并联在同一条两线制总线上每个模块独立编号主控用轮询方式逐个读取这和 HVAC 现场多点位采样的需求非常匹配。选型时我还专门考察过它的抗干扰能力。HVAC 现场有风机、压缩机这类大感性负载启停瞬间会产生很强的电磁干扰温度模块如果抗干扰不行数据跳变会让你排查到崩溃。PJ85718DM 在这方面的表现后面实测部分会详细讲。用一句话概括整体架构STM32F746ZG 是大脑负责决策和人机交互PJ85718DM 是分布在现场各处的神经末梢负责感知温度并把数据送回大脑。两者通过总线连接构成一套完整的本地远程温度监测网络。2. 硬件系统架构与关键电路实现2.1 本地温度采集通道的设计要点本地温度采集我优先考虑的是传感器位置和走线而不是先选传感器型号。控制柜内温度监测点要选在“最能代表柜内真实热环境”的位置。我习惯把本地传感器放在主控板的下风侧远离 MCU 和电源模块这些明显热源同时避开散热风道否则读到的不是柜温而是局部热点。PCB 布局上传感器底下不走大电流回路避免地平面噪声耦合进测量结果。本地传感器用的是数字输出形式直接挂 MCU 的 I2C 或单总线接口好处是信号在板内传输受干扰影响小而且不需要额外的信号调理电路。PCB 设计时我在传感器供电脚加了一颗 0.1uF 去耦电容并且让传感器地线单独走一小段到主地平面不要让它的回流路径和继电器驱动电路共用。这个细节不处理好继电器一动作本地温度偶尔会跳 0.3℃ 左右做温控闭环的时候会出现让人摸不着头脑的轻微波动。软件初始化时注意给传感器留足上电稳定时间。很多数字温度传感器上电后需要几十毫秒到上百毫秒的稳定时间如果在 MCU 刚复位、电源还没稳住时就发读指令大概率读到的是无效数据这点我在后面的固件部分会再强调。2.2 远程温度总线拓扑与通信电路设计远程温度采集的物理层用的是两线制 RS485 总线理论上一条总线可以挂数十个 PJ85718DM 节点实际项目挂了 12 个远端点分布在几条风管和不同房间最远距离接近 80 米。RS485 电路设计中几个关键点必须说清楚。第一收发器选型。主控端我用了一颗带失效保护的 RS485 收发器。所谓失效保护就是总线上没有设备发送数据、处于空闲状态时接收端输出一个确定的高电平避免读到随机电平导致数据错乱。这个功能在现场非常实用因为总线空闲时间很多如果没有失效保护偶尔会收到一堆 0xFF 或者 0x00 的乱帧。第二终端电阻。一条 RS485 总线只在最远端并一个 120Ω 终端电阻就够了主控端不需要。很多人误区是首尾各加一个在短距离低成本场景下问题不大但如果总线较长、节点较多首尾都加匹配会造成驱动器负担偏重信号幅值反而下降。我实测下来80 米长线、12 个节点只在远端并一个 120Ω波形干净利落。第三总线偏置。如果现场电磁环境特别恶劣建议在 A、B 线之间加偏置电阻让总线空闲电位稳定在逻辑 1 状态。偏置电阻阻值一般在 390Ω 到 560Ω 之间需要根据总线负载计算不能随手焊一个上去。我一般先不加偏置实测波形如果空闲段有抖动再补。第四接口保护。RS485 走线到接线端子之前串上两个 PTC 自恢复保险丝再在 A、B 对地各加一个 TVS 管。HVAC 现场经常有施工误接线的风险运气不好 220V 窜到总线上保护电路就是最后一道防线。这个成本很低但能让你少烧好几片收发器。2.3 电源、隔离与接口保护的几个细节HVAC 控制器一般直接用现场 24V 电源而 MCU 和数字电路需要 3.3V中间电源拓扑我用了 DC-DC 加 LDO 两级方案。DC-DC 从 24V 降到 5V效率高发热小LDO 再从 5V 降到 3.3V 给数字核心供电纹波控制得不错。DC-DC 的电感摆放离传感器远一点这点容易忽略——电感漏磁会把噪声耦合进高阻抗温度信号路径。要不要做隔离是这个项目里反复考虑过的问题。从成本角度非隔离方案省事省钱从可靠性角度远端传感器和主控之间距离长双方地电位可能不一致一旦有雷击或大电流设备漏电地环路会带来很大风险。最终我做了折中总线侧收发器用了隔离型器件电源侧用了一个小功率隔离模块单独给总线供电MCU 侧保持非隔离。这样既断了地环路又没让整套供电复杂化。还有一个细节是接线端子选型。温度总线的端子我选了带螺丝锁紧的插拔式端子而不是直接焊线。现场调试的时候传感器点位要经常调整接线可插拔端子省了很多事而且锁紧后的接触可靠性比压线帽高很多。别小看这个现场虚接造成的温度数据断断续续排查起来非常痛苦。3. 固件架构与核心代码实现3.1 底层驱动的分层设计思路固件这边我没有上来就写业务逻辑而是先把驱动做成分层结构后面加功能会轻松很多。最底层是硬件抽象层把 I2C、UART、定时器等外设的操作封装成统一接口。以 UART 为例我把 RS485 的收发方向控制也封装在了底层驱动里上层调发送函数时自动切换方向调接收时切回接收模式。这样做的好处是业务代码里完全不需要关心 RS485 半双工的方向切换出问题也只需要在一个地方查。再往上一层是设备驱动层对应本地温度传感器和总线上的 PJ85718DM。设备驱动层对外只暴露三个核心接口设备初始化、读取当前温度、设备状态查询。上层业务逻辑通过这三个接口操作设备不关心底层具体走的是 I2C 还是总线协议。设备状态查询这个接口是我特别习惯预留的。温度传感器这类器件不但要能正常读数据还要能判断“读回来的数据是否可信”。我给每个设备定义了几种状态正常、忙、通信超时、数据无效。上层轮询到非正常状态会做对应的重试或报警处理而不是傻等或者直接采一个不可信的值参与控制。3.2 远程轮询协议的实现与容错处理Bus 上挂着 12 个 PJ85718DM主控采用轮询方式逐个读取。轮询周期我设为 500ms也就是每秒钟能完整扫两轮对 HVAC 温度控制来说这个采样率绰绰有余还能留出大量总线空闲时间做其他事务。轮询逻辑用状态机实现避免在中断里做阻塞式等待。每个定时器中断触发一次轮询步进主控发送无操作请求收到正常响应就更新对应点的温度缓存没收到或者校验错误就记录该节点的错误计数并进入退避状态。退避处理很关键——如果一个节点连续多次无响应先判断是节点故障还是总线故障再做对应处理而不是反复重试把总线占死。数据帧的校验用的是标准 CRC16。这个不能省HVAC 现场总线上的干扰会导致数据误码没有 CRC 校验的话偶尔一个跳变的温度会被当成真实值参与温控后果可能是阀门误动作。CRC 校验成本很低但可靠性提升非常明显。还有一个经验是不要在一条消息里把所有节点的数据都读回来而是每个节点单独交互。这样做的好处是单个节点故障不会拖垮整条链路而且调试的时候能精确知道是哪个节点出了问题。3.3 温度滤波与数据标定的实用算法我实际用到两套滤波按场景分开用。第一套是接入级滤波用在每个远端节点的原始温度数据上。HVAC 现场的电磁干扰偶发性很强单次采样可能离群我用了“中位值滑动平均”的组合先取最近 5 次采样排中位再对中位值序列做 4 点滑动平均。这套组合的好处是既能滤掉脉冲干扰又不会像单纯滑动平均那样被离群值带偏。实测下来温度曲线平滑程度明显改善闭环控制也不会有那种高频的小抖动。代码示意如下/* 远端温度接入滤波 */ #define TEMP_MEDIAN_WIN 5 #define TEMP_AVG_WIN 4 static uint16_t median_wbuf[TEMP_MEDIAN_WIN]; static uint16_t avg_wbuf[TEMP_AVG_WIN]; float temp_filter_stage(float raw_temp) { /* 第一步滑窗更新 */ for (int i TEMP_MEDIAN_WIN - 1; i 0; i--) { median_wbuf[i] median_wbuf[i - 1]; } median_wbuf[0] (uint16_t)(raw_temp * 10); /* 第二步冒泡取中位 */ uint16_t tmp[TEMP_MEDIAN_WIN]; memcpy(tmp, median_wbuf, sizeof(tmp)); for (int i 0; i TEMP_MEDIAN_WIN - 1; i) { for (int j i 1; j TEMP_MEDIAN_WIN; j) { if (tmp[j] tmp[i]) { uint16_t t tmp[i]; tmp[i] tmp[j]; tmp[j] t; } } } uint16_t median tmp[TEMP_MEDIAN_WIN / 2]; /* 第三步中位值滑动平均 */ for (int i TEMP_AVG_WIN - 1; i 0; i--) { avg_wbuf[i] avg_wbuf[i - 1]; } avg_wbuf[0] median; uint32_t sum 0; for (int i 0; i TEMP_AVG_WIN; i) { sum avg_wbuf[i]; } return (float)sum / TEMP_AVG_WIN / 10.0f; }第二套是标定级处理。每颗温度传感器都存在个体偏差PJ85718DM 出厂标称精度能满足一般需求但 HVAC 温控要做得精细的话还是要做两点标定。我准备了一个恒温槽和一个标准温度计分别在 10℃ 和 40℃ 两个点记录每个节点模块的实测偏差然后算出每个节点的线性校准系数存在 MCU 的 Flash 里。这样做完之后整套系统的温度准确度从标称的 ±0.5℃ 提升到了 ±0.1℃ 左右在 HVAC 控制场景里已经非常够用。标定过程有个细节必须提校准量要在线性区间内不要超出传感器 datasheet 给定的量程去标否则拟合出来的系数在极端温度下反而会放大误差。另外标定期间传感器要完全浸入恒温介质中等温度稳定至少十分钟后再读数时间没稳够标出来的系数是虚的。4. HVAC 场景下的联调、实测与问题排查4.1 模拟环境与现场工况的对比测试硬件和固件都完成之后我没有直接上现场而是先在实验室搭了一套模拟环境把整个系统完整跑了一遍。模拟环境分三块一是用电源模拟器模拟 24V 现场供电测试供电波动时系统稳定性二是用一个局部风扇和加热器模拟风管温度变化验证闭环响应三是用一台变频器在旁边运行制造电磁干扰源考验总线通信的可靠性。实验室测试阶段发现的一个问题是变频器启动瞬间总线偶尔出现丢帧。排查时发现是收发器的 A、B 线接到端子板之后线束和变频器输出线缆捆在了一起干扰直接感应进了总线。我把总线线束单独走线远离变频器输出线问题立刻消失。这个经验在实验室里发现的省了现场不少麻烦。现场工况和实验室最大区别是温度变化速率。实验室里我可以控制温度变化速率现场风管里的温度波动受外界环境影响波动幅度更大、更随机。实测下来中位值滑动平均的滤波参数刚好合适温度曲线既平滑又能跟上实际变化没有滞后到影响控制效果的程度。4.2 常见故障与排查经验速查表项目联调过程中遇到过几类典型问题我整理成了一张速查表后续维护的时候直接查表定位。故障现象可能原因排查重点与处理办法单个节点温度长时间不变节点地址配置错误、节点故障、接线松脱先查节点拨码地址是否与主控配置一致再量总线 24V 是否到模块端子总线间歇性丢帧总线线束与动力线共管、收发器方向切换过快、缺少偏置电阻确认线束分离检查 UART 发送完成后是否延时再切接收方向必要时加偏置电阻温度数据跳变剧烈滤波参数未生效、模块受干扰确认接入级滤波开启检查传感器探头是否贴近变频器或大电流线缆本地温度明显偏高传感器靠近热源、PCB 走线耦合热量检查 sensor 周围是否有 DC-DC 电感或功率电阻必要时移到远离热源的位置总线通信完全中断终端电阻短路、总线极性接反、某节点故障拉死总线先断开所有节点逐段排查用示波器量 A、B 间波形判断是否存在设备损坏上电后第一个温度值异常传感器上电稳定时间不足、MCU 复位时读取过早固件延长传感器上电等待时间再发起首次读取排查里面最重要的一条经验是总线级故障永远先做分段隔离。一条总线上挂 12 个节点如果通信全断最忌一个个模块排查。先把总线从中间断开分两段各测一次能快速定位到是哪半段出问题。再在问题半段里逐级断开测试通常几分钟就能找到故障节点。4.3 实测数据表现与优化建议系统在现场稳定运行后的实测数据12 个远端温度节点轮询周期 500ms单轮完成时间约 60ms总线负载率很低。温度分辨率 0.1℃两点标定后的系统准确度在 ±0.1℃ 以内满足 HVAC 舒适性控制的要求。总线在变频器满载运行的条件下实测连续运行一周总线丢帧率低于 0.01%温度数据完整性非常高。丢掉的帧在软件层面有重试机制对控制没有任何影响。整套系统稳态运行时MCU CPU 负载大约 22%主要是 GUI 渲染和温度轮询占用的。如果后续要加 PID 温控回路按现在的余量跑 3 到 5 个控制回路没有压力。RAM 占用大约 90KB还留了很大空间给后续扩展。最后给两个优化建议。第一如果现场节点数继续增加可以把轮询周期从 500ms 拉长到 1 秒温度数据对 HVAC 场景来说不需要那么高的刷新率但总线稳定性会更好。第二如果项目需要更严格的数据追溯建议用 MCU 的 SDMMC 接口挂一张 TF 卡把每个节点的温度历史以 CSV 格式落盘这样维护人员不用到现场就能回溯数据排查故障效率会明显提升。这轮项目做下来我个人最深的体会是温度监测这类看着不起眼的子系统恰恰是最能体现工程细节的地方。传感器放哪、总线怎么走、滤波怎么配、标定怎么做每一个环节的决策都会影响最终系统的稳定性和控制精度。尤其是总线通信那部分反复验证下来RS485 的走线分离、终端电阻和失效保护这几件事做好了现场能少掉一半的排查工作量。如果你手上正好有类似的嵌入式温度采集或 HVAC 控制器项目不妨按这套思路先搭骨架再逐项填细节整个过程会顺很多。
阅读完成 · 觉得有帮助?
咨询建站