news 2026/10/22 6:37:22

PIC18F96J94+PJ85718DM双链路温度监测HVAC控制方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PIC18F96J94+PJ85718DM双链路温度监测HVAC控制方案

做嵌入式和 HVAC 温控的朋友应该都有体会:测温本身不难,难的是把温度测准、传得出去、并且在本地和远程两头都能稳定看到同一份数据。前阵子我完成了一个基于双链路温度监测的 HVAC 控制方案,主控选的是 PIC18F96J94,传感器端是 PJ85718DM,整体覆盖了设备面板本地实时显示和 RS485 远程上报两条路径。这篇文章把需求拆解、硬件接口、软件状态机、协议设计和调试踩坑完整复盘一遍,给正在做温控、环境监测或者楼宇自控相关项目的同学做个参照。

1. 先别急着画板:先把“本地和远程”这件事拆明白

1.1 HVAC 场景里,温度从来不是单点数据

HVAC 指的是供热、通风与空调系统,常见于楼宇自控、机房环境控制、新风机组、风机盘管这类设备。这类设备的温度监控几乎从来不是单点的:一台空调箱至少要关注送风温度、回风温度,有的还要叠加冷冻水进出水温度和室外补偿温度。为什么这么较真?因为控制策略依赖的是温度差值、变化趋势和热惯性。回风温度只能反映房间整体热负荷的滞后结果,送风温度直接决定人员舒适度,两者偏差过大,说明风量分配或者盘管换热出了问题。

所以项目标题里强调“本地与远程温度”,本质上是在说两种空间维度的数据:本地是设备面板旁现场人员肉眼可见的温度,远程是数十米甚至数百米外监控中心或上位机需要汇总的温度。这两类数据的采集链路、传输方式和可靠性要求都不一样,放在同一个项目里处理,最先要做的是分清职责边界。

1.2 本地和远程监测,技术路线的分水岭在哪

本地监测的核心诉求是直观、稳定、低延迟。设备面板上能看到当前送风温度和回风温度,刷新周期一两秒完全够,关键是显示不能闪烁、数值不能乱跳,不然现场维护的人看两眼就想拆机器。远程监测则完全相反:数据要能长距离传输,要能抵抗现场强电干扰,要能被上位机轮询,最好还能兼容已经存在的楼宇自控通讯习惯。

所以我的方案里,本地链路用 PIC18F96J94 直接驱动段式 LCD,远程链路走 RS485 总线,以类 Modbus 的协议上报温度寄存器。两条链路共享同一份经过滤波和标定的温度数据,不会出现现场 LCD 和上位机各读一套温度、数值对不上的情况。这个拆分思路是最重要的一步,硬件和软件的架构都围绕它展开。

1.3 为什么选 PIC18F96J94 当主控

选型阶段我对比过好几颗常见的 8 位机,最后锁定了 PIC18F J94 系列。核心原因有三个。

第一,这系列自带段式 LCD 驱动模块,可以直接推玻璃液晶,省掉外部的显示驱动芯片,BOM 成本和 PCB 面积都好看。第二,3.3V 供电搭配多种低功耗模式,在 24V AC 供电的 HVAC 控制盒里发热控制得很好,整机温升对传感器读数的影响可以压到很低。第三,外设接口齐全,I2C、UART、SPI、ADC 都有,“本地传感器采集 + 远程通信 + 段码显示”这三类任务不需要拼凑资源。

这里多说一句它的内部振荡器。J94 系列的内部时钟精度在校准后足够支撑 RS485 在 9600bps 下稳定运行,省掉一颗晶振和一个起振电容,PCB 又能干净一点。当然,如果你手头的具体型号是 J94 系列里其他容量或封装的变体,只要确认 LCD 驱动和 UART 资源在位,这套方案可以直接平移过去。

2. 硬件方案选型与接口设计

2.1 PJ85718DM 传感器模块的接入方式

PJ85718DM 这边我当成一颗数字温度采集模块来用。它内部已经把敏感元件、信号调理和数字转换做在一起,对外走 I2C 接口,主控读寄存器就能拿到温度。采购时一定要让供应商提供数据手册,几个关键参数必须逐项确认:供电电压范围、I2C 从机地址、温度寄存器地址与数据格式、测量精度、转换时间。

以我这边用的配置为例,3.3V 供电,I2C 总线速率 100kbps,上电后首次转换完成大约需要几十毫秒,之后工作在连续转换模式,每次读寄存器拿到的都是最新值。硬件上,SCL 和 SDA 必须各加一颗上拉电阻,I2C 是开漏结构,取值在 4.7k 到 10k 之间,总线电容偏大时用小一点的上拉。电源引脚旁 0.1uF 陶瓷电容要贴着放,PCB 入口再放一颗 10uF 钽电容吸收现场电源波动。

如果某个批次拿到的 PJ85718DM 是模拟输出版本,方案也不用推翻:把它当作电压输出型传感器,输出端直接进 PIC18F96J94 的 ADC 通道,把后面第 3 节的数字读取流程换成 ADC 采样加查表换算就行。两种形态我都测过,代码上预留一个编译开关就能同时兼容。

2.2 传感器远端布线和 RS485 的关系

这里要专门强调一个很多人容易搞错的点:I2C 不适合长距离传输。有人图省事,想从几十米外的风管里把 PJ85718DM 直接通过 I2C 拉回控制板,结果要么通信不稳定,要么抗干扰差。I2C 是给板级通信设计的,超过一两米就开始冒风险。

所以这个项目里,PJ85718DM 只负责本地就近测量,位置就在控制板附近,最多一两米的柜内线缆。真正需要“远程测点”的场景,我分两种方式处理:一种是远端传感器和一个小采集板放一起,采集板完成转换后通过 RS485 把数值打包上报;另一种是 PJ85718DM 作为本地基准温度,远程温度数据由 RS485 总线上挂载的其他远程采集站点提供,主控汇总后一起显示、一起转发。对应到标题,就是“本地温度由 PJ85718DM 直接读,远程温度通过 RS485 总线上的远程站点合并数据”,这套组合在现场跑下来最稳。

2.3 电源、隔离与保护电路

HVAC 现场最不缺的就是干扰。控制盒里通常有继电器、接触器、压缩机启动回路,温度传感器这种小信号最容易遭殃。我的做法是:24V AC/DC 进板后先过防反接二极管和自恢复保险丝,再走 DC-DC 降到 3.3V,DC-DC 输出侧加 LC 滤波;传感器供电从滤波后的 3.3V 单独引一路,避免和继电器驱动、LCD 这类瞬态负载共用同一根电源线。

RS485 侧必须加 TVS 管和共模扼流圈,A/B 差分线对之间并 120Ω 终端电阻。这个终端电阻不是随便加的,它是用来匹配总线阻抗、消除反射的,只能加在物理总线最远的两端设备上,中间的设备不要并,否则总线负载变重、通信反而变差。

本地链路和远程链路的硬件要点差别不小,我做成了一张速查表:

设计项本地链路(LCD 显示)远程链路(RS485 上报)
核心器件PJ85718DM + PIC18F96J94 LCD 驱动PIC18F96J94 UART + 485 收发器
传输介质板级 I2C,线长控制在 1~2 米内双绞屏蔽线,理论可达数百米
抗干扰手段电源滤波、地线隔离、传感器单独供电共模扼流圈、TVS、120Ω 终端电阻
数据可靠性CRC 校验可省略,重读即可必须带 CRC16 和超时重试机制
刷新要求1~2 秒刷新,无闪烁轮询周期 100ms~1s,可配置

3. 软件架构与温度采集实现

3.1 温度采集链路:采样、滤波、标定三步走

软件上,温度采集不能“读一次就用”。我把它拆成采样、滤波、标定三个环节。

采样环节要保证读到的数据是干净的、有节奏的。用 PIC18F96J94 的定时器产生一个 50ms 的中断节拍,每次中断里对 PJ85718DM 发起一次 I2C 读取。不要在主循环里靠 delay 去读,那样一旦被其他任务打断,采样间隔就乱了。

滤波环节用的是“滑动平均 + 去毛刺”组合。滑动平均窗口取 8 次,把测量噪声压掉;去毛刺是维护一个上下限,当前值和上一次合法值之差超过 3 个 LSB 就丢弃,防止继电器吸合瞬间的脉冲干扰直接进入数据链。

标定环节解决的是精度问题。数字传感器出厂精度一般在正负 0.5 到 1 度,但对 HVAC 控制来说还不够好,尤其是变风量机组希望做到正负 0.3 度以内。我通常做两点标定:用恒温槽或冰水混合物提供一个 0 度基准点,再用精密温度计在 40 度左右提供一个高温点,测出实际偏差后算出 offset 和 gain 两个系数,写入 EEPROM。每次上电读系数,换算温度时套进去。这个做法成本低、效果好,比换更高精度的传感器划算得多。

3.2 主循环调度与状态机设计

整个固件我跑的是一个简单的状态机加时间片轮询,没有上 RTOS,8 位机资源没必要那么铺张。状态分为四态:采集、换算、显示、通信。

  • 采集态:定时器节拍触发,执行 I2C 读取,读到的原始值放入环形缓冲。
  • 换算态:从环形缓冲取数据,滑动平均,套标定系数,换算成带一位小数的温度值。
  • 显示态:把温度值拆成段码,更新 LCD。LCD 刷新放这里,保证和采集解耦,显示永远不会因为通信忙碌而卡住。
  • 通信态:检查 RS485 接收缓冲区,有完整帧就解析,有查询请求就组帧回复。

这四个状态由主循环轮询,每个状态函数执行时间控制在 1ms 以内,外部中断只置标志位,绝不在中断里做耗时处理。实测下来 CPU 占用率不到 20%,剩下的余量留给以后扩展 PID 算法或者多路传感器。

3.3 LCD 驱动与刷新策略

段式 LCD 和以前用的数码管完全是两个脾气。数码管你不停地刷新没问题,段式 LCD 如果刷新频率不对,或者驱动波形不对称,就会出现对比度变浅、闪烁、甚至“烧屏”一样的残留。J94 系列自带 LCD 驱动模块,只要把 LCD 配置寄存器设对,用内部时钟生成驱动波形,液晶由硬件自己周期性刷新,软件只需要在数据变化时更新段码寄存器。

我的刷新策略是:温度值 1 秒更新一次,中间完全不碰 LCD 寄存器。这样段码数据稳定,驱动波形稳定,液晶寿命和观感都有保障。如果暖气设备要求更快响应,可以把刷新周期调到 500ms,但不要低于 200ms,段式玻璃液晶真没必要追那个数字。

4. 核心代码与协议设计

4.1 I2C 读取和温度换算的参考实现

PIC18F96J94 的 MSSP 外设做 I2C 主机非常顺手。读取 PJ85718DM 的流程是:发从机地址加写位,写寄存器指针,再发从机地址加读位,连续读两个字节得到温度数据。参考代码如下:

// I2C 读取 PJ85718DM 温度寄存器(16位数据) uint16_t pj85718dm_read_temp_reg(uint8_t reg) { uint16_t val = 0; I2C1_Start(); I2C1_Write(PJ85718DM_ADDR << 1 | 0); // 从机地址 + 写 I2C1_Write(reg); // 寄存器指针 I2C1_Restart(); I2C1_Write(PJ85718DM_ADDR << 1 | 1); // 从机地址 + 读 val = (uint16_t)I2C1_Read(1) << 8; // ACK val |= I2C1_Read(0); // NACK I2C1_Stop(); return val; }

如果 PJ85718DM 的数据格式是补码的 0.01 度每 LSB,换算就很简单:

int16_t raw = (int16_t)pj85718dm_read_temp_reg(PJ85718DM_TEMP_REG); float temp_c = raw * 0.01f; // 原始温度 temp_c = temp_c * gain_coef + offset_coef; // 两点标定补偿

要注意的是 I2C 读操作必须带超时。如果在现场传感器线被老鼠咬断或者接插件氧化,I2C 总线可能一直卡在等待 ACK 的状态,没有超时的代码会让整机看起来像是死机。我的做法是在发送和接收两边各加一个计数器,超过 100 次循环没完成就强制发 Stop 释放总线,并置一个传感器错误标志,显示界面上出现“Err”而不是一个骗人的固定数值。

4.2 Modbus 风格寄存器映射与 CRC16

远程通信我采用的是 Modbus RTU 风格的实现,没有用完整协议栈,只实现了功能码 03(读保持寄存器)和功能码 06(写单个寄存器)。这样做的好处是上层上位机、组态软件基本都能直接对接,不用另外写驱动。

寄存器映射设计如下:

寄存器地址内容说明
0x0000本地温度PJ85718DM 实测值,单位 0.1 度
0x0001远程温度RS485 远程站点上报值,单位 0.1 度
0x0002温差本地与远程温度差,单位 0.1 度
0x0003状态字bit0:本地传感器故障,bit1:远程通信超时

CRC16 Modbus 的实现网上版本很多,我直接贴一个自己验证过的查表版本:

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

组帧的时候 CRC 低字节在前、高字节在后,这是 Modbus 的固定顺序,踩坑的人很多,别搞反。

4.3 看门狗和低功耗调度的搭配

HVAC 设备常常要求无人值守,看门狗是必须的。J94 系列自带看门狗,我给看门狗设了 2 秒溢出。关键在于“喂狗”的位置:不能在主循环开头喂,而是放在状态机所有分支都跑完之后喂,这样任何一路逻辑卡死,狗都会把芯片拉回来。我还把 EEPROM 里的标定系数做了双备份,主备份和副备份各带一个校验和,一旦主备份损坏,自动切到副备份并置标志位,避免现场设备因为掉电丢标定数据而测出离谱温度。

5. 调试实录与常见问题排查

5.1 温度读数跳变,八成是电源和接地的问题

调试阶段最容易遇到的现象是:LCD 上温度数值稳定,但只要旁边继电器一吸合,数值立刻跳 1 到 2 度。很多人第一反应是传感器坏了,其实大概率是电源被污染。我排查的顺序是:先看 3.3V 电源纹波,继电器动作瞬间有没有尖峰;再查传感器地线是不是和继电器驱动回路共用了走线;最后才去怀疑传感器本身。解决办法就是第 2 节说的,传感器独立供电、独立地线、电源加 LC 滤波。这三点都做到之后,我实测温度数值的抖动幅度从正负 0.3 度降到了正负 0.05 度以内。

5.2 RS485 远程丢帧和误码的处理实录

远程通信的问题集中在三处:波特率误差、终端电阻、地电位差。

J94 内部振荡器虽然出厂校准过,但温度和电压变化后还是会有偏差。我调试时遇到过上位机偶尔收错帧,用示波器量波形发现波特率差了将近 2%,当即改成使用 UART 模块的内部高精度时钟源,偏差降到 0.5% 以内,9600bps 下再没丢过帧。终端电阻的问题前面说过,现场施工队伍经常把每台设备都加上 120Ω,结果总线负载太重,通信距离和带负载能力直线下降。地电位差的问题要靠共模扼流圈和 TVS 管解决,如果现场两端设备相隔很远地电位不一致,宁可把两端的信号地断开,只靠差分信号传输。

5.3 常见问题速查表

现象可能原因检查顺序
温度读数周期性跳变电源纹波、地线共用示波器看 3.3V 纹波,再查布线
I2C 读不到数据上拉电阻缺失、地址错误、线序接反量 SCL/SDA 静态电平,确认地址位
LCD 对比度淡LCD 偏压配置不对、刷新率过低检查 LCD 配置寄存器、供电电压
远程偶尔丢帧波特率偏差、终端电阻位置错误示波器量波形,检查总线两端
整机偶发复位看门狗超时喂、电源跌落查喂狗位置,检查 DC-DC 输出跌落
标定后温度仍然偏标定系数没写入 EEPROM、写错地址上电读系数打印核对

每个问题我在现场都真实遇到过,尤其是“看门狗把整机拉复位”那个,排查了很久才发现是一个 I2C 读取函数在传感器异常时没有超时退出,主循环卡死导致喂狗超时。所以我在代码规范里定了一条死规矩:任何外设操作必须配超时,任何状态机分支必须保证能回到主循环。

结尾

这个项目做完之后,我最大的体会是温度监测项目真正的技术含量不在“读温度”本身,而在数据可信度和链路鲁棒性。一把示波器、一组可靠的标定数据、一条带超时的软件逻辑,比换更高规格的传感器更能解决现场问题。

最后再分享一个小技巧:如果你手头的 PJ85718DM 数据手册写得不详细,最笨也最有效的办法是上电后遍历一遍 I2C 地址,把应答的设备地址打印出来确认,避免因为默认地址和手册标注不一致而浪费一整天。这套基于 PIC18F96J94 加 PJ85718DM 的双链路监测方案,后续还可以直接扩展出湿度监测、PID 控温输出和故障预警日志,骨架已经打好,剩下就是往里面挂功能的事了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 6:36:46

【SLAM】DSO SLAM编译

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 6:34:54

轴向磁通电机电控系统设计:低电感与高极对数带来的挑战与对策

做电机控制这些年&#xff0c;各类永磁同步电机经手了不少&#xff0c;轴向磁通电机&#xff08;AFPM&#xff09;这几年确实火——扁平结构、高转矩密度、适合轮毂驱动和航空电推进这类场景。但真正把它从“看着厉害”变成“跑得稳”的&#xff0c;是后面那套电控系统。我见过…

作者头像 李华
网站建设 2026/10/22 6:34:54

AI重构科研与开发:数学证明、PC架构与代码审查的范式转变

2026年10月8日午后&#xff0c;三个消息几乎同时砸进科技圈&#xff1a;某前沿AI实验室一口气公开了377项数学相关成果&#xff0c;争议立刻刷满学术群&#xff1b;软件巨头与芯片大厂宣布联手把个人电脑整个重做一遍&#xff1b;代码托管平台放出统计&#xff0c;平台上大约三…

作者头像 李华
网站建设 2026/10/22 6:34:53

输电标准化作业平台二次开发实战:从源码到部署避坑指南

输电标准化作业平台这类项目&#xff0c;在电力行业里属于“看着不起眼、做起来极其磨人”的典型。几年前我带团队做某地区供电公司的运检信息化改造时&#xff0c;接手过一套编号55390的输电标准化作业平台源码&#xff0c;后来在这个基础上做了大量二次开发。这套平台的核心价…

作者头像 李华
网站建设 2026/10/22 6:34:51

C++移动语义实战:从拷贝开销到完美转发与性能验证

搞C写了这些年&#xff0c;我越来越觉得 move 语义是一个“入门容易、吃透难”的知识点。说容易&#xff0c;是因为std::move这个函数名摆在那&#xff0c;看两眼就能在代码里写上&#xff1b;说难&#xff0c;是因为你真要搞清楚它为什么能提升性能、什么时候不生效、什么时候…

作者头像 李华
网站建设 2026/10/22 6:33:52

A星与DWA融合:机器人全局最优与动态避障的实用方案

做机器人导航的朋友一定遇到过这种尴尬&#xff1a;全局规划算出来一条好好的路径&#xff0c;结果走两步就被一个突然窜出来的障碍物堵死&#xff0c;要么原地打转&#xff0c;要么一头撞上去。反过来说&#xff0c;如果全靠局部规划实时躲&#xff0c;又容易在复杂环境里绕远…

作者头像 李华