PIC18F87J10+PJ85718DM实现1-Wire多点测温系统实战解析 做嵌入式温度采集的都知道测温永远是最基础但也最容易被低估的环节。尤其是在暖通空调HVAC和工业嵌入场景里既要盯控制板自身的工作温度又要实时读取分布在风道、水管、回风口的远程点位这种“本地加远程”的双轨测温需求非常普遍。我最近用 PJ85718DM 数字温度传感器搭配 PIC18F87J10 主控做了一套覆盖这两种场景的测温系统跑了几个月整体稳定。这里把设计思路、硬件参数、固件实现以及调试中踩过的坑完整梳理一遍想抄作业的可以直接参考。这套方案的核心思路并不复杂主控板上放一颗 PJ85718DM 测机箱内部温度作为本地温度外部远程点位通过 1-Wire 总线挂载若干颗同样的传感器PIC18F87J10 负责总线时序解析、温度换算、有时还要承担 Modbus 上报或者报警输出。适合小规模、低成本、快速验证的嵌入式采集项目也适合暖通空调项目的温度点补全比如送风温度、回风温度、水管进出口温度这类测点分散但点数不多的场景。如果你正打算做类似的多点测温系统这篇文章能把硬件、固件和现场布线所有关键点讲透。1. 系统整体设计与测温链路拆解1.1 本地与远程温度的定位差异先说清楚“本地”和“远程”到底差在哪里。本地温度指的是主控板自身环境温度比如控制盒内部、配电箱内、接线端子附近的温度测这种点位的主要目的是保护设备、判断散热是否异常。它的特点是走线短、干扰小、采样周期可以很短传感器可以直接贴在 PCB 上或者用延长线接到面板。远程温度则完全不同它要覆盖的是那些和主控板隔着几米甚至几十米距离的物理点位。HVAC 系统里最典型的就是空调机组回风温度、送风温度、冷水管进出口温度、室外新风温度。这些位置分布散、距离远而且现场环境往往有风机、水泵、变频器的强电干扰。远程测温首先要解决的是“信号怎么传过去不丢、不乱”其次才是精度。我在这套系统里把两种测温点放在同一个 MCU 下没有为远程温度单独加采集模块。原因很简单PIC18F87J10 的资源完全够用CPU 处理 1-Wire 总线时序不费力省掉一个独立采集模块成本和接线复杂度都能降下来。这是小系统里很划算的取舍但如果以后点位几十上百个就要考虑换 RS485 集中采集架构了这个后面再说。1.2 PJ85718DM 为什么适合挂在远距离总线上选 PJ85718DM 作为测温芯片主要看中的是 1-Wire 单总线架构。这种芯片只用一根数据线就能和 MCU 通信而且每颗芯片出厂时都带有一个唯一的 64 位 ROM 序列号一条总线上可以挂多颗传感器MCU 通过序列号就能精确点名读取指定点位的温度不需要为每个传感器单独拉一根信号线。打个比方1-Wire 总线就像一条走廊走廊两侧有很多房间每个房间挂一个门牌号MCU 挨个敲门问温度每个房间依次回答。这就是为什么它能用最少的 IO 和线缆完成多点的分布式测温。在测温精度和范围上PJ85718DM 覆盖 -55°C 到 125°C12 位分辨率模式下温度最小分辨率是 0.0625°C商用级芯片在 -10°C 到 85°C 范围内误差可以做到 ±0.5°C。对 HVAC 这种不需要极高精度的应用场景来说这个指标完全够用而且它的转换时间最大约 750ms采样一轮所有点位也就在秒级完成不会拖慢主循环。另外PJ85718DM 支持两种供电方式外部供电和寄生供电。寄生供电只需要两根线但长期在 HVAC 强干扰环境里并不推荐后面我在抗干扰章节会详细讲。外部供电多加一根 VCC 线稳定性却明显提升这也是我在远程总线上坚持用三线制的原因。1.3 PIC18F87J10 的角色分配PIC18F87J10 是一颗 8 位 MCU片上 Flash 和引脚资源都比较充裕足够承载这颗主控的全部工作。我在系统里分配的任务很明确GPIO 软件模拟 1-Wire 时序完成对总线上所有 PJ85718DM 的复位、ROM 匹配、温度转换和读取定时器中断作为时间基准用于 1-Wire 时序的微秒级延时控制同时驱动主循环进行周期轮询UART 接口用于和上位机通信把本地和远程所有温度点打包成 Modbus RTU 协议帧后上报少数几路 GPIO 用于报警输出和状态指示比如温度越限时驱动继电器或者点亮告警灯。之所以不用硬件 I2C 或者 SPI 接口纯粹是因为 PJ85718DM 是 1-Wire 协议PIC18F87J10 并没有内置 1-Wire 控制器软件模拟是通用做法。软件模拟的好处是引脚选择灵活可以挑一个抗干扰位置好的 IO 口坏处是需要精确控时对中断和延时要求比较高这部分我在第三章节展开。2. 硬件电路设计与关键参数计算2.1 本地测温点的取电与滤波本地这颗 PJ85718DM 放在主控板上走线很短电路最简单VDD 接 3.3V 电源GND 共地DQ 数据线通过一颗 4.7kΩ 电阻上拉到 3.3VVDD 和 GND 之间加一颗 0.1µF 去耦电容让它尽量靠近芯片电源引脚放置。PCB 布局的时候有个容易忽略的细节传感器芯片不能靠近板上发热量大的器件比如电源电感、线性稳压器、功率 MOS 管。如果空间实在有限至少要保持 5mm 以上的距离否则测到的根本就不是环境温度而是热源附近的局部温度。我第一次打样就把一颗传感器放在 DC-DC 电感旁边实测比另一颗同批次传感器高出 4°C后来挪走才恢复正常。本地传感器的 DQ 线上要不要串电阻我建议串一个 100Ω 的小电阻它和总线寄生电容一起构成低通滤波能吸收一部分高频干扰。虽然短线上效果不明显但也不会有负面作用属于“顺手加上”的保护措施。2.2 远程 1-Wire 总线的上拉电阻计算远程总线是这套硬件设计里风险最高的部分因为 1-Wire 总线上的设备都属于开漏输出数据线必须通过上拉电阻拉到高电平。上拉电阻取多少直接决定总线能传多远、信号沿有多陡。先看最小值的约束。PIC18F87J10 的 GPIO 在输出低电平时灌电流能力有限PJ85718DM 的数据引脚也有最大灌电流限制。通常按 4mA 灌电流计算总线低电平时的最大输出电压 VOL 约 0.4V供电 VCC 为 3.3V则最小上拉电阻Rmin (VCC - VOL) / IOL (3.3 - 0.4) / 0.004 ≈ 725Ω所以上拉电阻不能小于 725Ω留出余量我一般不会用到比 1kΩ 更小的值。再看最大值。上拉电阻越大总线 RC 时间常数越大上升沿越缓。总线本身有分布电容双绞线大约 40~60pF/米加上每个传感器的引脚电容后总电容不小。如果上拉电阻太大远程节点的波形上升沿会变得很软超过 MCU 的输入高电平阈值时间点不稳定直接导致读写失败。经验数值是这样的总线长度小于 3 米节点数不超过 5 个用 4.7kΩ 没问题总线长度在 3~15 米节点数 5~8 个推荐用 2.2kΩ总线长度到 15~30 米节点数接近 10 个用 1kΩ 并且尽量缩短分支线超过 30 米1kΩ 上拉也救不了要么加总线中继要么换 RS485 架构。需要特别注意的是上面所有计算和推荐值都以 3.3V 供电为前提。如果远程传感器用的是 5V 供电上拉电阻也要按 5V 重新算而且 DQ 引脚的高电平会超过 PIC18F87J10 引脚的耐压范围这种混压设计一定要加电平转换或者统一改为 3.3V 供电。2.3 电源、接口保护与连接器远程传感器的供电我推荐直接三线制VCC、GND、DQ。VCC 和 GND 从主控板引出每颗传感器旁边就近放一颗 0.1µF 去耦电容条件允许的话再加一个 10Ω 电阻串联到 VCC 上和电容构成一个简单的电源滤波能够明显改善长线上的电源噪声。接口保护在 HVAC 现场属于必做项。远程线缆从室内走到管道井或者室外机附近难免受到静电放电、感性负载启停的干扰。做法是在主控板的远程总线接口处加 TVS 管到地DQ 线上再串联一个 10~100Ω 的电阻这是牺牲很小一点信号余量换取器件安全非常划算。连接器方面建议使用带锁扣的端子排或者航空插头防止现场震动导致传感器点位松动。每个通道的端子位标注好“VCC / DQ / GND”不然施工人员接错线是家常便饭后面排查起来非常痛苦。3. 固件实现从轮询调度到传感器状态机3.1 1-Wire 时序的软件实现PIC18F87J10 没有硬件 1-Wire 外设所以总线时序完全靠 GPIO 加延时函数模拟。时序的关键是写时隙和读时隙每种时隙都有严格的时间窗口复位脉冲主机拉低总线 480µs然后释放并等待 480µs 左右传感器应答信号是拉低 60~240µs写 1 时隙主机拉低总线 6µs然后释放整个时隙长度约 60~120µs写 0 时隙主机拉低总线整个时隙约 60~120µs然后释放读时隙主机拉低总线 6µs释放后在第 15µs 内采样总线电平。软件实现时要特别注意一点整个时隙期间时序必须连续不能被中断打断。如果写时隙执行到一半跑进一个中断函数时间窗口就崩了传感器收到的信号完全错乱。所以我在固件里用了一个全局临界区标志进入 1-Wire 时序操作后暂停一切可能产生较长延时的中断服务只保留定时器计数等时序完成后才恢复中断响应。一个最基本的写时隙函数大概是这样的void ow_write_bit(unsigned char bit) { OW_DQ_LOW(); delay_us(6); if (bit) { OW_DQ_HIGH(); delay_us(60); } else { delay_us(60); OW_DQ_HIGH(); } delay_us(3); }读时隙类似只是释放后要去采样总线状态unsigned char ow_read_bit(void) { unsigned char data; OW_DQ_LOW(); delay_us(6); OW_DQ_HIGH(); delay_us(8); data OW_DQ_READ(); delay_us(55); return data; }这里面 delay_us 的精度很重要。我在实际调试里发现PIC18F87J10 在 3.3V 供电下主频运行延时函数要用定时器或者指令周期精确计算不能随便用循环空转因为编译优化级别不同会导致实际延时不一致。这是新手最容易踩的坑看起来代码没问题读回来的温度却经常是乱码或者固定 85°C。3.2 传感器 ROM 搜索与匹配总线上如果挂了多颗 PJ85718DM固件必须先解决“谁是谁”的问题。每颗传感器都内置了 64 位唯一 ROM 序列号主机可以通过 ROM 搜索命令逐个找出总线上所有设备的序列号。标准做法是比较麻烦的位搜索算法要对 64 位每一位都做三次总线交互。我在这套系统里的实际做法是上电初始化阶段执行一次完整的 ROM 搜索把找到的传感器序列号和对应安装位置写入一个表结构正常运行阶段不再重复搜索而是通过 ROM 匹配命令每次指定一个序列号读取对应传感器的温度。这样做的理由很现实。如果每次巡检所有点位都广播“跳过 ROM”读取温度在总线上只有一颗传感器的时候没有问题一旦挂了多颗传感器所有传感器都会同时应答读回来的温度就是总线上某颗传感器轮流发声的结果数据点位完全错位。比如你以为是读回风温度实际可能是室外温度逻辑控制就会出大问题。ROM 匹配命令的流程是主机发出复位脉冲等待存在应答发送 ROM 匹配命令字节逐位发送某个传感器的 64 位 ROM 序列号发送温度转换命令或者读取暂存器命令读取温度数据。对于点位不超过 10 个的系统这个流程的执行时间可以忽略不计。3.3 温度寄存器解析与 CRC 校验PJ85718DM 的暂存器包含 9 个字节前两个字节是温度值后几个字节包含报警阈值和配置字节最后还有一个 CRC 校验字节。温度数据格式是 16 位补码12 位分辨率下数据左对齐低 4 位为小数部分。实际温度值按下式计算温度 ((MSB 8 | LSB) 4) × 0.0625°C负数需要先判断符号位。如果最高位是 1说明是负温度读取出来的原始值和 0xFFFF 之间有补码关系解析时要按有符号数处理。HVAC 应用里负温场景不多但北方冬季新风系统有可能遇到所以固件里必须兼容负数解析。转换时间的问题也要重点提醒。PJ85718DM 在 12 位分辨率下温度转换时间最长约 750ms。如果固件发送了温度转换命令后只等 50ms 就去读暂存器读回来的大概率是上一次的转换结果或者上电初值。这是另一个我调试时反复遇到的现象尤其在上电瞬间读温度经常读回 85°C这就是芯片刚上电还没完成第一次转换时暂存器的复位值。解决办法很简单发送转换命令后再等待至少 750ms 再读取或者循环检查暂存器的转换状态位。CRC 校验不能省。现场干扰导致一两个 bit 翻转温度数据可能偏差好几度如果没有 CRC 判断脏数据直接进入控制逻辑后果很严重。CRC8 计算可以用查表法这里贴一个精简版unsigned char ow_crc8(unsigned char *data, unsigned char len) { unsigned char crc 0x00; while (len--) { unsigned char byte *data; for (unsigned char i 0; i 8; i) { unsigned char mix (crc ^ byte) 0x01; crc 1; if (mix) crc ^ 0x8C; byte 1; } } return crc; }每次读完整组暂存器数据后对前 8 个字节算 CRC和读到的第 9 个字节比对不一致就整帧丢弃重新发起一轮读操作。这个处理加到固件里之后整个系统的误读数明显下降。4. HVAC场景下的抗干扰与实际布点4.1 机组启停噪声对测温的干扰HVAC 项目现场最难对付的不是温度传感器本身而是各种强电设备。空调机组的风机电机、变频器、水泵启停瞬间会产生很强的电磁干扰如果 1-Wire 总线的线缆和动力线并行走线或者屏蔽层接地方式不对传感器数据就会时不时跳变CRC 校验失败率陡然上升。我在现场遇到过一次很典型的故障室内机组正常运行时所有温度点读数正常只要风机一启动远端某个传感器就开始报错过几秒又自己恢复。示波器抓总线波形能看到风机启动瞬间 DQ 线上叠了一个明显的高频尖峰脉冲直接把时序窗口破坏了。应对措施是从硬件和固件两端同时下手。硬件端远程总线线缆必须用屏蔽双绞线屏蔽层在主控板一侧单端接地绝对不要两端接地否则反而会形成地环路电流。总线信号线和动力电缆要分槽走线实在没办法交叉时也要做到垂直交叉不能平行近距离敷设。固件端对每次温度读取结果都做 CRC 校验失败则延时一个总线周期后重试连续读取三次最终结果取中值而不是平均值。中值滤波在这种尖峰干扰场景下比平均值滤波更有效因为一个异常大的跳变值不会把结果带偏。4.2 布点规范与线缆长度经验温度点位在 HVAC 系统里通常有固定的安装逻辑。回风温度传感器装在回风管道内距离回风口 1.5 倍管道直径以上避免风口附近的涡流影响送风温度传感器装在出风管道直管段不能太靠近加热器或者表冷器盘管水管温度传感器贴装在管道外壁要做保温处理室外温度传感器要装在遮阳通风的位置不能直接晒太阳。这些测点位置的确定直接影响测温数值的可靠性。传感器本身精度再好安装位置不对也是白搭。比如新风温度传感器如果装在阳光直射的墙面中午读到的温度会比真实气温高五六度这种数据送到控制逻辑里新风阀动作就会完全乱掉。总线拓扑上远程 1-Wire 总线最好用主线拓扑所有传感器通过短接线并接到总线上避免很长的分支线。分支线过长会形成反射信号严重时总线上会出现振铃导致读写时序错乱。我调试过一条总线带 8 个传感器的系统分支最长的一条达到了 5 米结果那一路的传感器经常报 CRC 错误把分支缩短到 0.5 米以内后问题立刻消失。给出一个我实测过的经验数据表格不同长度和节点数下的稳定情况总线长度上拉电阻节点数实测状态小于3米4.7kΩ5稳定无重试3~15米2.2kΩ8稳定偶发一次重试15~30米1kΩ10基本稳定有重试发生30米以上1kΩ10不建议建议加中继这个表只是一个参考基准实际还取决于线缆质量、现场干扰强度和接地情况。但方向是明确的远程总线上拉电阻不要照抄数据手册的最小值要根据实际长度和节点数调整。4.3 温度标定与阈值报警PJ85718DM 这类数字传感器出厂前已经做过校准绝对精度在常温段表现不错。但现场安装后探头接触方式不同会带来系统偏差。比如贴在管道外壁的传感器受管壁材质和保温层影响读数和真实水温可能偏差 1~2°C。这时就需要做系统级标定。我的做法是在固件里给每个传感器维护一个独立偏移量字段初始化时通过上位机下发存储在片内 EEPROM 中。现场用一个经过校准的参考温度计作为基准在稳定工况下记录每个点位的偏差然后把偏差写入系统。这样做比改硬件电路简单得多也方便后期运维人员重新标定。阈值报警逻辑放到 MCU 里处理每个温度点可以独立设置上限、下限和回差。比如回风温度超过设定值 28°C 时触发报警低于 24°C 时恢复中间设置 1°C 回差防止继电器反复动作。PIC18F87J10 处理这类逻辑绰绰有余不需要再外挂比较器。5. 实测数据、常见问题与排查实录5.1 一组实测数据这套系统在某项目现场连续运行一段时间后我记录了一组代表性数据。机组稳定运行状态室外温度约 24°C 时主控本地温度在 31.2°C 到 31.6°C 之间波动回风温度在 25.8°C 到 26.1°C 之间波动送风温度在 18.2°C 到 18.5°C 之间波动。传感器 12 位分辨率下的最小量化步长为 0.0625°C但实际读数波动 ±0.3°C 主要来自现场气流不稳定和总线干扰并非传感器精度不够。在多次启停测试和连续长时间运行中温度数据没有出现过明显的失控跳变CRC 错误率在可以接受的范围。这个结果说明硬件上的上拉电阻取值、线缆选型和固件里的重试机制组合起来基本满足 HVAC 现场的稳定运行要求。5.2 典型故障速查表把现场调试过程遇到的现象、原因和处理办法整理成一张表格方便后续维护人员定位问题故障现象可能原因处理建议所有传感器都读不到温度复位失败、DQ 没上拉、VCC 没接好示波器抓复位波形检查上拉电阻焊接只读到一个传感器其他点不响应ROM 搜索不完整、总线供电能力不足独立供电逐点测试排除供电瓶颈温度偶尔跳变几度现场干扰、时序被中断打断、接插件氧化加屏蔽层单端接地延长延时加 CRC 重试读数恒定在 85°C上电后立刻读暂存器、转换未完成发出转换命令后等待 750ms 再读不同点位的温度数据串位没有做 ROM 匹配总线广播读取按序列号点名读取建立点位映射表远端几个点始终超时线缆过长、分支线过多、上拉电阻偏大缩短总线减小上拉电阻或者加中继本地板温度明显偏高传感器靠近发热器件重新布局远离功率器件和电感这个表看着简单但每一条背后都是真实的调试经历。尤其是“读数恒定 85°C”这个现象很多人误以为是芯片坏了其实是芯片上电后的默认暂存器值等它完成第一次转换就正常了。5.3 排障实录有一个项目现场让我印象很深。客户反映远程送风温度点总是时好时坏运行时看监控曲线温度值有时候突然变成 0 或者跳到 100°C 以上过几秒又恢复。我去现场排查首先用示波器挂在远程总线接口上看波形发现传感器正常应答时波形清晰但设备启动时总线信号出现明显振铃。顺着布线路径检查发现施工方把远程总线信号线和风机动力电缆绑在了同一个线槽里而且线槽还没有分隔板。动力电缆启停瞬间的大电流变化在信号线上感应出干扰脉冲。后来把信号线改走独立线槽同时把上拉电阻从 4.7kΩ 调整为 2.2kΩ增强总线驱动能力再观察一天所有温度点读数恢复稳定CRC 重试次数也降到了零。这个案例给我的教训是方案设计时不能只画原理图还要把现场布线规范写进施工要求里。1-Wire 总线在实验室台面上怎么折腾都稳到了现场就不一样线槽、动力电缆、接地、屏蔽每一个细节都会影响最终效果。另外还有一个不是传感器本身的问题却同样折腾了我挺久。PIC18F87J10 是 3.3V 供电的 MCU有段时间同时挂了几个 5V 供电的传感器虽然 DQ 开漏信号看着能通信但长期使用后 MCU 的 IO 口引脚出现异常温度时读时不读。后来统一把远程传感器改成 3.3V 供电MCU 和传感器电平完全一致问题才彻底消除。这个教训提醒我设计之初就要确定供电电压体系不要在不清楚电平匹配风险的情况下去省一根线。如果让我重新做一遍这个项目我会在需求阶段就把点位布局图、线缆路径和上拉电阻计算表全部确定下来而不是等到现场调试时再改。测温系统的工程量不大但“细节魔鬼”特别多原理图上的一个电阻、图纸上的一条布线路径、固件里的一个延时都可能决定这套系统到底稳不稳。这套 PJ85718DM 加 PIC18F87J10 的方案在十来个测点的小规模 HVAC 应用里性价比很高维护起来也简单。规模再往上走我可能会引入 RS485 采集网关或者改用无线温度节点但小系统中这种“一颗 MCU 管一条总线”的做法确实让人用得很顺手。