PIC18F87K22与PJ85718DM数字温度传感器的I2C多点测温实现

发布时间:2026/10/22 1:12:15

PIC18F87K22与PJ85718DM数字温度传感器的I2C多点测温实现 做嵌入式温度监测这么久有一个组合我用了很多次一颗 PIC18F87K22 做主控配合两片 PJ85718DM 数字温度传感器把本地板温和远程测点温度一起管起来用在 HVAC 控制器和机箱热管理这类项目里稳定省心成本也可控。这个组合不算新潮但它解决了一个很常见的需求——在同一套系统里同时拿到“设备自身的温度”和“远端环境的温度”而且不需要引入模拟前端、长线补偿那一堆麻烦事。这篇内容会把整个方案的来龙去脉讲清楚为什么选这两颗芯片、硬件怎么接、软件怎么读、现场会踩哪些坑。适合正在做 HVAC 控制器、嵌入式机箱监测或者想用单片机挂多路 I2C 温度传感器的开发者参考即使你没用过 PIC 也完全能看懂思路。1. 方案整体思路一颗主控两条链路板温与远端温度分开测先说说这个项目当初的需求。一个 HVAC 控制器需要监测三类温度控制板本身的温度、回风口附近的温度、以及室外机组附近的温度。前一个是“本地”后两个是“远程”远程测点离控制器少则两三米多则一二十米。这种需求在嵌入式系统里非常典型不只是 HVAC像机房动环、配电柜、种植箱、冷库控制器都会遇到。当时选 PIC18F87K22 而不是更大牌的 ARM 系列考虑很直接整个系统工作电压是 5V外设的继电器、阀门驱动器、显示屏逻辑都是 5V 电平MCU 直接放在 5V 系统里不需要电平转换PIC18F87K22 的 Flash 有 128KBRAM 接近 4KB对温度采集、PID 调节、液晶显示、按键处理来说完全够用更重要的是这颗芯片在 HVAC 行业有长期供货保证批量成本低抗干扰能力也经过很多现场验证。传感器选了 PJ85718DM它是典型的 I2C/SMBus 数字温度传感器测量范围覆盖 -55°C 到 125°C典型精度可以做到 ±0.5°C 以内自带 12 位 ADC结果直接通过寄存器读出不需要校准电路。它跟 PIC18F87K22 搭配很顺手5V 供电直连I2C 接口只需两颗上拉电阻就能工作OS 报警输出引脚还能直接接到 MCU 的外部中断。整条链路是数字信号不会出现模拟温度传感器那种长线衰减和 AD 采样误差叠加的问题。本地和远程分开测还有一个隐藏好处诊断方便。如果整个系统温度数据异常对比本板和远端两个测点就能快速判断是传感器故障、线缆问题还是设备本身真的过热。以前在项目里见过只测一个点的设计报警之后根本分不清是控制板自己热还是外部环境热排查起来很被动。架构上也很简单PIC18 的 MSSP1 模块做主 I2C 控制器本地 PJ85718DM 挂在板内总线上地址固定远程 PJ85718DM 做成一个小板放在测点处通过线缆把 I2C 总线拉过去。两块传感器寄存器结构一样软件处理逻辑完全复用只是设备地址不同。这样选型、备料、写驱动都省了一圈事。2. 硬件连接细节引脚很少陷阱不少2.1 本地传感器的标准接法PJ85718DM 的引脚非常少电源、地、SCL、SDA、OS 报警输出还有一个地址引脚 A2-A0部分封装是 A0-A2 三个地址脚具体看封装。本地传感器放在主板上靠近 MCUI2C 走线不超过 3 厘米这个距离几乎不需要考虑信号完整性。电源去耦要注意。传感器虽然功耗很低但如果它和继电器驱动共用一个电源继电器动作瞬间的压降会导致传感器读数跳变。项目里我在传感器 VDD 脚放了一个 0.1uF 陶瓷电容要求布局时尽量靠近电源引脚如果板上空间允许再加 1uF 的钽电容兜底效果更好。VDD 和 GND 之间不能省这个电容我有一次就是偷懒没布电容结果每次继电器吸合温度都会诡异地跳一两度。上拉电阻的值要按总线长度和挂载数量算。板内只有两片传感器本地和远程总线不长我用的是 4.7kΩ 上拉到 5V。如果远程线缆很长总线电容变大上拉电阻可以适当改成 2.2kΩ 甚至 1kΩ否则上升沿太缓会导致通讯错误。不过这里有个矛盾上拉电阻太小正常工作时总线电流会增大功耗和电磁干扰都会上来。所以不要盲目改小应该先测波形再决定。2.2 远程传感器走线与抗干扰远程传感器小板和主板之间我一开始图省事直接用普通排线拉结果现场调试直接翻车3 米不到的线数据就开始偶发错误。后来换成了双绞线问题立刻消失。I2C 总线本身不抗干扰长线传输时 SCL 和 SDA 之间的串扰、外部电机启停带来的共模干扰都会破坏时序。正确做法是SCL 和 GND 一对双绞SDA 和 VDD 一对双绞或者用四芯屏蔽线屏蔽层单端接地。距离再远一些比如超过 10 米直接拉 I2C 总线就不太可靠了。我见过有人在 20 米长线上用 400kHz 跑完全是碰运气。合理的方案有两类一是把 I2C 速率降下来比如降到 10kHz 或更低的“标准模式以下”牺牲速度换可靠性二是在远端加总线缓冲/中继芯片这类芯片能把 I2C 隔离成两端驱动能力大幅提升还能解决电平偏移问题。HVAC 项目里对采样速率不敏感温度变化本来就很慢所以我倾向直接用低速率加屏蔽双绞线不加中继也够用。还有地电位问题这是远程传感器最容易踩的坑。主板和远端模块如果分别接了不同的地两边的地存在电位差轻则读数偏移重则 I2C 通讯直接乱掉。所以远程传感器的电源和地必须从主板单独引过去不能依赖现场其他设备的地。我在现场就遇到过把传感器地接到金属管道上导致通讯卡死的事故原因就是管道对地有零点几伏的感应电压把总线电位抬高了。3. I2C 数据读取与温度换算把寄存器内容变成人能看的温度3.1 MSSP 模块初始化注意事项PIC18F87K22 有两个 MSSP 模块我在项目里用的 MSSP1 做主模式。初始化时必须搞清楚一个计算波特率寄存器 SSP1ADD 的值不是拍脑袋定的它和系统时钟以及目标 I2C 频率的关系是SSP1ADD (Fosc / (4 × Fsck)) - 1比如系统时钟我用内部 16MHz想要跑 100kHz 标准模式算出来就是 (16000000 / (4 × 100000)) - 1 39十六进制 0x27。如果改成 400kHz就是 90x09。这个计算公式在数据手册里写得很清楚但很多人不看手册直接抄例程最后通讯失败也不知道为什么。初始化 MSSP 为 I2C 主模式时需要打开 SCL 和 SDA 对应的第二功能方向把引脚配置为输入开源极然后设置 MSSP1CON1 的使能位MSSP1ADD 写入 0x27MSSP1CON2 的 ACKDT 和 ACKEN 根据是否需要主动应答来设置。用一个辅助函数把这几步封装起来比每次在主循环里从头配置寄存器清晰得多。代码层面要特别注意I2C 启动和停止条件不是靠写电平实现的而是通过给 MSSP 模块一个启动/停止触发位硬件自己产生时序。也就是说你只要往相关控制位写 1然后等待中断标志位置起来就行不需要软件模拟 SCL/SDA。很多人在这里不理解总想自己翻转引脚结果把硬件 I2C 用成了 GPIO 模拟白白浪费了 MSSP 模块。3.2 读取温度寄存器的完整流程PJ85718DM 读取温度的流程是标准的 I2C 寄存器读法先发设备地址加写位发送要读的寄存器指针然后再次发送设备地址加读位连续读两个字节。设备地址最常用的写法是 0x907 位地址 0x48 左移一位如果 A2-A0 引脚接法不同地址会偏移这个后面再细说。我用一个函数封装单字节读和双字节读大体的通讯流程是uint8_t I2C_Start(void); uint8_t I2C_WriteByte(uint8_t data); uint8_t I2C_ReadByte(uint8_t ack); void I2C_Stop(void); uint16_t read_temp_raw(uint8_t dev_addr, uint8_t reg) { uint16_t raw 0; I2C_Start(); I2C_WriteByte(dev_addr | 0); // 写方向 I2C_WriteByte(reg); // 寄存器指针 I2C_Start(); // 重复起始 I2C_WriteByte(dev_addr | 1); // 读方向 raw (uint16_t)I2C_ReadByte(1) 8; raw | I2C_ReadByte(0); I2C_Stop(); return raw; }这里最容易出错的是重复起始条件有些 I2C 设备不认重复起始非得先停止再启动。PJ85718DM 的手册写明支持重复起始但我在调试中还是碰到过兼容性问题——换批次之后偶发读不到数据只能把连续读改成“停止-启动”。所以写驱动时最好做一个超时重试机制读不到就重新发一次启动条件对现场应用来说这点冗余非常必要。温度数据换算比较直接。12 位模式下的原始值会左对齐高位是符号位把寄存器值右移 3 位再乘以 0.125就是摄氏度。举个例子寄存器读出来 0x1A00右移三位得到 0x340即 832乘以 0.125 就是 104.0°C如果读出 0xF100右移三位后符号位是 1要按补码转换为 -30.0°C。用整数运算时建议直接写成 (raw 4) * 0.0625 之类根据实际配置选择关键是把符号位处理对不然冬天读出来全是零下 200 度的诡异数值。4. 程序架构轮询、滤波和报警阈值设计4.1 采样轮询状态机我建议不要在主循环里直接阻塞地读 I2C最好用一个定时中断驱动的小状态机。因为温度传感器响应慢整个 I2C 读取过程如果被中断打断太久MSSP 模块的状态会乱掉特别是远程长线状态下通讯时间本身就不稳定。做法是设定一个 1Hz 的软件标志位主循环检测到标志后读取两块传感器的温度每次读之前做超时判断。PIC18F87K22 的 I2C 等待可以用无限循环等待中断位但真实产品里不能无限等万一传感器突然没应答系统就卡死了。我写了一个简单的超时循环uint8_t wait_i2c_flag(void) { uint16_t timeout 0xFFFF; while (!I2C1IF) { if (--timeout 0) { I2C1IF 0; return 1; // 超时 } } return 0; }超时之后要做总线复位——把 MSSP 模块关掉再重新打开释放 SCL/SDA。远程传感器的线缆如果被老鼠咬断或者接头进水总线会被锁死这个复位逻辑是保底手段。我在现场就靠这个功能撑过了好几次接头松动的“意外”。温度滤波方面我用了最简单的滑动平均每 5 次采样取平均。本来想用一阶低通滤波但后来发现在 HVAC 中温度本来就是慢变量5 点平均已经足够。滤波要区分本地和远程不要混在一起算因为远程通道在长线状态下偶发的坏值会影响平均值——可以在滤波前做一次合理性检查判断读数是否在 -60°C 到 150°C 之间超出就丢弃本次值。这一招很土但很有效。4.2 报警阈值和迟滞PJ85718DM 有一个报警输出脚 OS内部寄存器可以设置上限温度 TH 和迟滞温度 TS。把 OS 配置成中断模式当温度超过上限时输出有效信号可以接到 PIC18F87K22 的外部中断引脚上。这样即使主循环卡死超温还是能触发硬件中断这种冗余设计在 HVAC 里用来做风扇联动和超温保护特别合适。但要注意报警寄存器不是写一个值就行还要选比较模式还是中断模式以及输出有效电平极性。我在项目里用中断模式因为我想让处理器每次超温都得到通知而不是报警之后一直保持状态。中断模式下传感器会在每次温度回落穿过阈值时再拉一次需要软件读温度寄存器来清除中断标志不然会一直触发。实际的阈值也不能定得太死。HVAC 控制板的本地温度和环境温度差异很大控制板有继电器和变压器发热夏天可能比环境高十几度远端回风口温度接近真实环境温度。所以我给了两组独立的报警参数一个针对本地传感器一个针对远程传感器生产调试时通过参数表下发到 Flash 存储用户现场可以改。这个设计来自一次惨痛教训最初把两个通道阈值设得一样结果高温天气控制板没报警远端房间已经热到 35 度了。温度监测不能只设一组阈值不同测点的物理含义完全不同一定要分开配置。5. 实测调参记录与现场问题排查5.1 整机校准和现场实测批量生产时PJ85718DM 的理论精度是够的但 PCB 上如果有热的元件靠近传感器自热误差会让读数偏高这个靠芯片本身精度救不回来只能靠布局和校准。我做过一批板子本地传感器离一个降压芯片太近实测读数比标准温度计高了 2 到 3 度。后来在装配工艺里加了一个单点校准每个产品在常温下用恒温槽测温把偏差存到 EEPROM 的校准字段里软件读出来之后统一加偏移量。有人说这样成本高但实际上在 HVAC 行业很多产品出厂本来就有一道高温老化测试顺手多测一个温度点几乎不增加工时。校准模型用最简单的线性修正就够了不要上复杂的插值因为数字传感器本身非线性很小。我测试过从 0 到 60 度区间的偏差最大不超过 1 度线性修正在这个范围内完全够用。装机之后的整机试验比单板测试更有价值。我把整个控制器放在一个可调温箱里模拟了三个场景环境温度从 20 度升到 50 度、远程传感器放在箱外、远端传感器接 20 米双绞线。结果让我印象深刻的是20 米线缆加上屏蔽层接地之后100kHz 速率下读数非常稳定但 400kHz 会偶尔产生坏值。产品对采样速度不敏感所以我最终把 I2C 频率锁在 50kHz留了足够余量。5.2 常见问题速查表做这个项目前后遇到的坑我都整理成了一张速查表后来团队调试新项目也直接拿它当参考。最典型的是通讯时好时坏往往是线缆太长导致上升沿过缓表现为偶发无 ACK解决办法是换双绞线、降速率、减小上拉电阻或加中继。传感器地址冲突如果用了多片同型号传感器A2-A0 引脚必须接不同电平来区分地址否则多个设备会抢总线读到的数据一片混乱。芯片发热误报先检查布局再看校准PB 板布局紧挨线圈或功率器件即使算法再对也救不回来。低温读数卡死远程接口进水或绝缘下降时总线电压不稳要重点加护套和用防水接头。现场经验与后续扩展我个人在实际操作中体会最深的一点是温度监测方案的核心并不在传感器精度而在系统对错误数据的容忍能力。同一个 I2C 驱动放在实验室里怎么读都对一接现场长线就露馅同一片 PJ85718DM放在角落和放在风道口读数能差好几度。所以硬件设计、软件滤波、校准和总线复位这几个环节必须作为一个整体来考虑单独强调任何一环都解决不了实际现场的问题。如果后续要在系统里加更多测点我建议直接用 I2C 多路复用开关芯片把总线分成几路每路拖几条长线而不是把所有传感器并联在同一条总线上。复用开关切换后总线电容变小距离还能拉得更远代码只是多一个写通道寄存器的操作。这个扩展思路在做多房间空调控制或农业大棚多点测温时特别实用能够复用现有框架而不改动传感器驱动。
延伸阅读

更多相关文章

2026/10/22 1:12:15

STM32F412ZG+PJ85718DM:HVAC多点温度监测实战方案

/* 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 1:07:15

从全反射到流速测量:光纤传感器原理与工程实践

/* 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 1:07:15

STM32+单总线数字温度传感器实现HVAC多点测温方案

/* 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 2:07:20

移动电源新国标来了,聊聊GB47372-2026软件升级要点 i

简介书接上文,“移动电源新国标GB47372-2026做了哪些升级?”我们对新国标做了一下解读。本篇主要是针对新国标“6.5 充放电温度控制”、“6.8 智能管理”、“6.9 电压调节”、“6.1 0 异常禁用”等软件相关部分做一下详细的讲解。针对新国标新增的这些功…

2026/10/22 2:07:20

WSL使用Ubuntu 24.04安装Libradtran

/* 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 2:07:20

G-Helper 四种 GPU 模式到底怎么选?

G-Helper 四种 GPU 模式到底怎么选? 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, Expertbook, ROG All…

2026/10/22 2:07:20

FGO-py 实战指南:免配置图像识别,三步连上设备自动刷体力

FGO-py 实战指南:免配置图像识别,三步连上设备自动刷体力 【免费下载链接】FGO-py 自动爬塔! 自动每周任务! 全自动免配置跨平台的Fate/Grand Order助手.启动脚本,上床睡觉,养肝护发,满加成圣诞了解一下? 项目地址: https://gitcode.com/GitHub_Trend…

2026/10/22 2:07:20

TensorData::ShareFrom 接口详解:两个对象如何共享同一块内存

TensorData::ShareFrom 接口详解:两个对象如何共享同一块内存 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints TensorData 是 GE 接口中描述一块张量内存的对象&…

2026/10/22 2:02:19

前端转后端入门实践日志1-配置环境

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

2026/10/21 4:53:08

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/22 0:01:49

电商智能运营体系从0到1:架构设计、落地步骤与避坑指南

前两年我们团队接了一个电商平台的运营中台项目,目标很直白:把过去靠运营拍脑袋做的选品、定价、发券、推活动这些事,逐步用数据算法和自动化流程代替。项目名字内部就叫“电商智能运营体系”。最近有不少朋友问我当时是怎么设计的、踩过哪些…

2026/10/22 0:01:49

若依框架AI代码生成不稳定?用Agent Skill三层结构+五步法搞定

最近一段时间,我一直想把后台管理系统里那些机械重复的增删改查代码交给AI去写。框架用的是若依,按理说这类业务代码模式非常固定,应该是AI最擅长的事情。可真试下来却不是那么回事——你让AI生成一个用户管理模块,它给出的Contro…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑