☰
PJ85718DM与R7FA4M3AF3CFB144的本地远程温度监测方案
2026/10/22 6:45:08 网站建设 项目流程

这两年做过好几个跟暖通相关的小项目,发现大家最常用的温度方案就两种:一种是 PT100 + 变送器,另一种是 1-Wire 探头 + 单片机。PJ85718DM 就属于第二种,R7FA4M3AF3CFB144 是我一直在用的 M33 核 MCU。把这两颗芯片放在一起做温度采集,比用热敏电阻加 ADC 的模拟方案省去大量调试时间,接入 HVAC 时扩展探头也简单。下面我把这套本地/远程温度监测方案从选型、接线、固件一直写到现场排错,尽量把我踩过的坑一次性讲完。

这套方案要解决的事情其实不复杂:一台嵌入式设备,既要盯住自己所在的控制柜温度,又要顺手采集远处风管、水管或房间里的温度。本地温度用芯片内部传感器,远程温度用单总线探头。选这块 MCU 的好处是资源充足,内部 ADC 可以直接读硅片温度,GPIO 模拟 1-Wire 时序时延迟也压得住,144 脚封装的引脚多,设计一块带继电器和通信接口的控制板时不用缩手缩脚。

先给一个经验:设计文档里把器件型号写完整,对后期维护特别重要。硬件工程师看到这几个字符就能定位到封装和引脚数,固件工程师也能从“本地+远程”推测出数据结构。如果项目文档里只写“温度检测板”,三个月后自己都会糊涂。

1. 先把系统拆开:本地与远程两条采集链路

1.1 本地温度与远程温度分别指什么

很多做嵌入式的同事容易把“本地温度”理解成“探头装在板子上”。严格讲,我在这里把它分成两级:R7FA4M3AF3CFB144 内部自带的温度传感器读到的是硅片温度,能反映芯片发热和周边 PCB 的热环境;如果想把“板载环境温度”测准,还需要在板边放一个外部探头。标题里的“本地温度”我认为就是指 MCU 内部通道或板载传感器,核心是不需要额外接长线,开机就能读。

远程温度则必须通过 PJ85718DM 这类数字传感器,把它放在真正需要监测的位置。HVAC 项目里最常见的远程点位是送风管、回风管、混水箱、冷热盘管或者机房角落。探头到主控板的距离短则几米,长则几十米。如果用模拟热敏电阻,线长带来的压降和干扰会很麻烦;单总线传感器是数字信号,线延长之后仍能保持一致的读数。

我建议产品定义阶段就把“本地”“远程”作为两个独立数据对象来设计,不要放在同一个平均值算法里。机柜发热会影响控制逻辑,所以比较好的做法是:本地温度只做保护判断,远程温度才进入空调控制算法,必要时再把两个数据一起上报给上层系统。后面给代码时会说明这两路数据分开处理的好处。

1.2 方案对比:为什么不用 NTC 和 PT100

我理解大家在 HVAC 项目里最先想到的一定是 NTC 热敏电阻。确实有项目为了省几毛钱用了 10k NTC 加单片机 ADC。NTC 的问题是离散性和非线性。同一批料放一起,B 值和 25℃ 电阻值都有容差,不做两点校准时,±0.5℃ 以内的精度很难保证。到了冬天零下、夏天 50℃ 以上时,整个测量范围被拉长,代码里塞一堆拟合公式,还换不来好效果。

PT100 在暖通里也用得很多,但它需要恒流源或精密电桥,再配 24 位 ADC 或者变送器。精度确实好,不过成本、PCB 面积和布线难度都上来了。PJ85718DM 这类 1-Wire 数字传感器则把感温元件、ADC、接口和序列号都集成在一颗小芯片里,误差通常在 ±0.5℃ 左右,对绝大多数 HVAC 控制足够,每颗有唯一 ID,总线上挂多个也不用担心地址冲突。

我也有特殊场景会考虑 PT100,比如需要 0.1℃ 分辨率、探头要承受高温或长期潮湿环境时。若只做楼宇温控和嵌入式机柜监测,用数字传感器把成本压下去,把产品交期缩短,是更务实的做法。

方案信号类型典型精度远程布线难度成本适用场景
NTC模拟电阻0.5~2℃高,受线阻影响最低消费电子、近距离测温
PT100模拟电阻0.1~0.3℃高,需电桥和变送器高工业、暖通高精度测点
PJ85718DM数字单总线0.5℃级别低,抗干扰强中低嵌入式、HVAC分布测点

1.3 数据流概览

从传感器到控制的完整链路并不长。远程侧 PJ85718DM 采集温度,按 1-Wire 协议把 16 位原始数据回传;MCU 的 GPIO 引脚模拟单总线时序,拿到数据后做 CRC 校验和格式解析;本地 MCU 内部 ADC 采集硅片温度并做两点校准;两路温度经过滤波和异常剔除后,进入控制逻辑或通信接口。

这套流程里最容易出问题的环节是 1-Wire 时序。它本身是低速协议,对微秒级延迟有要求,但对 MCU 主频没那么敏感,关键点在于禁止在忙等期间被中断打断。嵌入式系统如果上了实时操作系统,建议把这部分放在独立任务里,或者在临界区关闭调度,否则中断频繁打断 1us 的时间片,波形就会歪。后面固件部分会专门讲。

2. 硬件选型与电路连接

2.1 PJ85718DM 的远程探头接线

PJ85718DM 是 3 脚封装,VCC、GND、DQ。我推荐用外部供电而不是寄生供电。寄生供电在总线较长或探头较多时,电流不够会导致转换结果异常。虽然规格上支持寄生模式,但工程上我不建议省这根线。现场用四芯屏蔽线比较稳,其中两芯给 VCC 和 GND,一芯给 DQ,剩下一芯备用或接屏蔽层。

上拉电阻按总线长度估算:总线小于 3 米用 4.7k,3 到 10 米用 2.2k,超过 15 米建议先用示波器观察上升沿,很多时候要用 1k 才能把沿拉起来。上拉电源接在 3.3V,水平别直接接 5V,除非确认器件支持 5V 耐压。另外,总线上所有探头共用一根 DQ 线和一根上拉电阻,不要每个探头各接一个上拉并联,否则总等效电阻太小,电平会拉不低。

远程探头决定走线拓扑时,尽量用“主干线 + 短支线”。也就是说,从 MCU 板出来一条总线到末端,各探头就近并接到总线上。每条支线尽量控制在 30cm 以内,支线太长会造成反射,波形会变得很难看。接插件用可插拔端子,方便施工。HVAC 项目里探头经常先装好,控制板后接,所以端子标识要清楚。

2.2 本地温度用的 MCU 内部通道

R7FA4M3AF3CFB144 有内部温度传感器,挂在 ADC 外设旁边,配置对应通道后当普通电压源读。由于裸片温度近似于 PCB 表面,需要给 ADC 足够的采样稳定时间。硬件上,ADC 参考电压引脚必须加滤波电容,100nF 和 1uF 并联放置;如果板上有继电器或功率开关,模拟地和高功率地要单点汇接,否则本地温度 ADC 跳动会很明显。

我做过一个控制板,继电器离 MCU 很近,每次继电器吸合 ADC 读数就跳 2℃。后来把 ADC 参考地的滤波电容加大,并把继电器线圈续流二极管换成了响应更快的型号,跳变才压下去。这里不是芯片的问题,是板级噪声没处理好。做嵌入式温度监测,很多异常其实都出在电源和地,而不是传感器本身。

本地温度通道的校准,需要在软硬件联调时用恒温箱或外接高精度温度计做两点标定。通常厂家数据手册会给出校准公式或内部校准值,我习惯在 Flash 里存两组校准系数,分别是低温和高温点。如果批量生产,每一块板都要单独校准会带来产线成本,所以要看项目精度要求。HVAC 保护用途允许 ±3℃,出厂统一校准足够了;科研或计量用途则需要逐台标定。

2.3 电源、上拉、ESD 与线缆细节

温度传感器和 MCU 共用 3.3V 电源时,要观察电源纹波。单总线在转换瞬间会有脉冲电流,虽然不大,但在远端探头容易被干扰。最稳妥的做法是给传感器单独加一个 LDO 或用 RC 滤波给 VCC 脚,DQ 信号线上再串一个小电阻,比如 100Ω,以抑制反射和 ESD 电流。

户外或潮湿风管安装时,ESD 和浪涌比室内更严重。DQ 线上加一个 TVS 管到地,靠近端子放置。如果没有 TVS,一个 10k 下拉电阻也能降低静电击穿概率,但会影响上拉电平,实际用下来 4.7k 上拉加 330Ω 串联的方案最省事。屏蔽线单端接地还是双端接地要按现场做判断:一般建议总线控制器端接地,避免屏蔽层两端同时接导致地环路电流。

我特别提醒一件事:不要把远程温度信号线和 220V 供电线走同一个线槽。看起来只是“温度信号”,但在空调机房、风管井里,施工师傅经常把所有线归拢在一起。强电启动时感应电压会把 1-Wire 波形打乱,轻则读数跳变,重则烧引脚。宁可绕远路单独走一根屏蔽线,也别图省事。

3. 固件实现:从驱动到可用的温度值

3.1 最小工程配置

用这块 MCU 时,我先配一个最小工程:时钟外部晶振 16MHz,锁相环到芯片允许的最高主频,系统时钟出来之后,把 DQ 接到一个普通 GPIO,配置为开漏输出和输入共用。开漏输出很关键,因为 1-Wire 协议要求主机释放总线让上拉电阻把电平拉高,如果用推挽输出,两根设备同时拉低时会打架。

ADC 配置为单通道扫描,选择内部温度传感器输入,参考电压选内部基准。采样时间尽量大于规定的最小值,我通常会设置到 10us 以上,这样本地温度读数的稳定性明显好。符号库、串口打印和基于 tick 的延时也要先跑通,因为调试时全靠串口看信息。

有些人会嫌内部温度传感器麻烦,直接用外部 NTC 当着本地温度。我不反对,但标题既然写了“本地与远程”,先掌握内部通道没有坏处。我实际测试下来,内部通道在稳定环境下能保持 ±1.5℃ 左右的重复性,用于机柜过热保护足够了。只要不把它当计量级数据就行。

3.2 单总线时序与多探头访问

1-Wire 是从机多挂协议,所有通信都由主机发起。第一步是复位脉冲:主机把 DQ 拉低至少 480us,释放总线,然后读取从机的存在脉冲。如果从机存在,它会在释放后 15us 到 60us 内把总线拉低 60us 以上。我在代码里写过一版简化逻辑,实测是能用的:

static uint8_t onewire_reset(void) { uint8_t present = 0; DQ_LOW(); delay_us(480); DQ_HIGH(); /* 释放总线 */ delay_us(70); /* 等待存在脉冲开始 */ if (DQ_READ() == 0) /* 从机拉低总线 */ present = 1; delay_us(410); /* 等待复位周期结束 */ return present; }

总线释放后必须靠上拉电阻拉高,所以 GPIO 要配成开漏模式。如果复用功能把引脚配置成推挽,复位脉冲之后主机和从机可能同时驱动总线,逻辑冲突。单总线的读和写都是靠拉低时间的长短区分,常见规则是:写 0 需要拉低 60us 以上,写 1 只需要拉低 1~15us 然后释放。读数据时,主机拉低 1~6us 后立即释放,延时 10us 左右读电平,这样能得到下一个 bit。

多个探头的访问方式是 ROM 搜索。每颗 PJ85718DM 出厂都有一个 64 位 ROM 码,里面含家庭代码和 48 位序列号,最后 8 位是 CRC。主机可以通过搜索命令 0xF0 逐位读取 ROM。程序角度讲,搜索算法不复杂,但需要维护一个分支路径栈。实际项目如果探头数量固定,我建议一个更省事的办法:初始化时把所有探头的 ROM 码读出来,存到数组里,之后直接用匹配 ROM 命令 0x55 选择指定探头。

温度转换命令序列如下:

/* 选中指定探头 */ send_byte(0x55); send_byte(rom[i] >> 0); send_byte(rom[i] >> 8); send_byte(rom[i] >> 16); send_byte(rom[i] >> 24); send_byte(rom[i] >> 32); send_byte(rom[i] >> 40); send_byte(rom[i] >> 48); send_byte(rom[i] >> 56); /* 启动温度转换 */ send_byte(0x44); delay_ms(750); /* 12 位分辨率转换时间 */ /* 读暂存器 */ send_byte(0x55); /* 再发一次 ROM */ send_byte(0xBE);

转换时间要按最大分辨率的规格值来,不要只给一个经验值。如果读取太快,芯片会返回一个未完成转换的值,最典型的现象就是读到 85℃ 固定值。我第一次调试时就踩了这个坑,最后查了手册才发现是转换时间不够,不是芯片坏了。

3.3 温度转换与本地校准

PJ85718DM 的温度数据是 12 位二进制补码格式,低 4 位为小数,所以 1 LSB 是 0.0625℃。代码如下:

int16_t raw = (byte1 << 8) | byte0; /* byte1 为高字节 */ if (raw & 0x8000) /* 负温度处理 */ { raw = (raw & 0x7FFF) + 1; /* 取绝对值 */ temp = -raw * 0.0625f; } else { temp = raw * 0.0625f; }

读回的数据里还有高位字节的符号位。很多新手只把两个字节拼起来,负数温度直接变成大正数,控制逻辑判断全乱。负温度在空调机组的冬季工况很常见,风管进风在北方经常低于 0℃,调试时一定要用冰水混合物验证一次负温度链路。

本地 MCU 内部温度传感器的校准思路也是两点斜率。先通过 ADC 读取内部通道原始值,然后用外接恒温源作为参考,记录两个点的原始值和实际温度,最后计算斜率:

float local_temperature(uint16_t adc_raw) { const float raw1 = 2235.0f; const float temp1 = 25.0f; const float raw2 = 2730.0f; const float temp2 = 85.0f; return ((float)adc_raw - raw1) * (temp2 - temp1) / (raw2 - raw1) + temp1; }

不同板子上 raw1、raw2 会不同,所以不要把这段代码写死。把校准参数放到配置文件里,产测时写入特定区段,固件运行时读取。内部温度测的是芯片,外部恒温箱校准时要让板子等足够久,等温度平衡。我曾等了一个小时才稳定,过程很无聊,但数值确实准了一些。

3.4 简单滤波与异常剔除

HVAC 环境里温度变化本来就很缓慢,完全没有必要把每次原始值都直接当作控制输入。我常用一个滑动窗口:每 200ms 采一次,取最后 8 个值求平均,平均结果送入控制逻辑。这样既能滤掉传感器线缆附近的开关噪声,又不会让控制响应慢到无法接受。

窗口长度要配合应用需求。如果是风管温度做 PID 控制,建议窗口 8~16 个点,平滑程度适中;如果是机房过温保护,窗口 4 个点就够了,要的是快速响应。不要一句“滤波”就把数据锁在一组极慢的均值里,导致保护动作延迟。

异常剔除方面,我会做两个判断:第一,单总线 CRC 校验不过直接丢弃;第二,相邻两次采样温度跳变超过 5℃,丢弃当前值,连续丢弃超过 3 次则报警。这个逻辑虽然简单,却能在实际项目里避免很多误动作。之前有一次现场继电器拉弧,总线上的干扰让探头瞬间读到 -40℃ 满量程值,如果没有跳变保护,整个系统就会像疯了一样乱开乱停。

4. HVAC 部署与调校实践

4.1 现场安装位置怎么定

远程探头装在风管里时,安装位置要避开气流死角。我常看到施工队把探头装在风管弯头内侧,那里形成涡流,温度不代表平均风温。正确做法是装在直管段的中部,探头插入深度至少达到风管直径的三分之一。如果风管内有水管或加热盘管,探头距离热源不能太近,否则测到的是局部热点。

风机盘管机组的回风温度探头更容易被忽略。回风滤网前后温差很大,滤网脏堵后温度会明显分层,把探头装在滤网后容易读高。所以我会在项目图纸上标“回风口上游 30cm,远离滤网”的安装位置。这些细节不是芯片能解决的,但对系统控制效果影响很大。

外露探头的防护套也要提前准备。风管里高速气流带灰尘,长期吹会改变散热条件,导致误差变大。较好的做法是用不锈钢探头套管,把 PJ85718DM 封装在里面,用导热胶填充。市面上有很多成品防水探头,直接买成品比自己灌封省事。

4.2 温差控制与机柜自保护

本地温度和远程温度分开之后,可以用它们设计两种逻辑。第一种是保护逻辑:如果本地温度超过 70℃,说明控制板所处环境恶劣,即使远程温度正常,风扇也要强制开启,或者继电器降载。第二种是控制逻辑:远程温度参与 PID,目标是让送风温度维持在设定范围。

我个人很喜欢把本地温度作为“板级健康”指标而上报。很多设备的故障不是传感器坏了,而是安装环境太热,导致电解电容老化、接插件氧化。有了本地温度,运维系统可以在故障发生前预警。比如机柜顶部排风扇坏了,远程温度可能还没明显变化,但 PCB 附近温度会先上升,本地温度就能提前报警。

机柜里同时有动力电源和控制板时,本地温度读数往往会高于实际环境温度。设计保护阈值时不要照抄“环境温度 60℃”这类标准,直接测控制板表面温度,留出 10℃ 左右的余量。否则夏天高温天动不动就触发报警,维护人员就会把报警当狼来了,真出事反而不响。

4.3 整机测试顺序

我把一套完整测试流程总结成六步:先查电源和复位,再测本地 ADC 数据,然后接一个远程探头当基准,用恒温槽标定,接着并接多个探头验证 ROM 搜索,最后放到柜内连续运行 24 小时。每一步都要能打印关键变量,不要急着把控制逻辑都写完才整体调。

恒温槽标定时,要注意传感器和标准温度计不能争同一杯水。把药剂探头用扎带固定在传感器探头旁边,同时读取两块表,每次改变温度设定后等 20 分钟再记录。因为水温和探头导热有滞后,读数没稳定就记录会让校准曲线边歪。

24 小时运行测试是排查可靠性最好的方法。白天和晚上的电网电压不同,继电器切换负载频率也不同,所以干扰问题往往在晚上暴露。记录日志里不仅要存平均温度,还要存每次读数的最大跳变。如果能看到偶发 5℃ 跳变,基本可以断定是电源或者 ESD 问题,而不是采集代码问题。

5. 常见问题与排错记录

5.1 读 0xFFFFFFFF 或固定 85℃

0xFFFFFFFF 是最典型的单总线通信失败,原因是主机没有读到从机的存在脉冲,或者发送波形乱套。先用示波器看复位波形,确认拉低时间是否足够。然后查上拉电阻,引脚配置是否开漏。最容易出现的问题是 GPIO 初始化为推挽输出,导致主机释放总线后信号马上又被拉高或拉低,时序全乱。

固定 85℃ 则是转换未完成时芯片给出的明确标志。解决办法是在发送 0x44 后等待足够的转换时间,12 位分辨率通常要 750ms 左右。如果用的是 9 位分辨率,转换时间会短不少,但精度也会下降到 0.5℃ 级别。HVAC 一般还是用 12 位分辨率,1 LSB 0.0625℃ 看着清爽。

如果读到的数据 CRC 校验失败,可能是总线反射或时序有偏。先缩短支线长度,再调整主机采样点的等待时间。我习惯在代码里加一个调试开关,把每个字节的原始 bit 都打出来,手工比对 64 位 ROM 码和读回的数据,能快速确认位错在哪一段。

5.2 远程探头时好时坏

现场最常见的“时好时坏”原因是接插件氧化和虚接。特别是室外或潮湿风管,端子长期接触冷凝水很容易氧化。我后来统一改用镀金端子,并在安装时涂一层绝缘硅脂,故障率降了非常多。信号线缆如果有中间接头,尽量整个换掉,不要用缠绕胶带修。

上拉电阻选择不当也会导致头几分钟正常,设备发热后就失败。温度升高会改变芯片驱动能力和上拉等效阻值,原来临界的上拉被彻底破坏。我测过一个 10 米总线的项目,4.7k 上拉在 25℃ 时勉强能跑,到 50℃ 时波形上升沿明显变慢,改成 2.2k 后就没有再出现偶发失败。

多个探头中有个别读不到,优先查看总线拓扑。是否是总线上这支探头的支线太长,超过 1 米;是否在主控板附近并联了多余的电容。如果有探头已经焊死在管道里,可以把它断电并接到总线上,看其他探头是否恢复正常,逐个排除。

5.3 本地温度波动大

内部 ADC 数据跳动,先不要怀疑传感器,先查 ADC 参考电压。用示波器戳参考电容两端,能看到持续毛刺就说明地线处理不够。把 ADC 参考电容改成 1uF 和 100nF 并联,并让电容靠近 MCU 电源引脚,通常能解决 80% 的波动问题。

系统只有一块电池供电、没有大功率负载时,本地温度波动还大,就很可能是采样时间不足。ADC 采样电容没有充分充电,转换结果会随机跳。把采样时间从 1us 加到 10us 甚至更久,数据会平滑得多。这个参数在配置工具里直接能改,成本最低。

最后,检查看门狗或 RTOS 任务调度是否在读取时频繁打断。如果 ADC 读取发生在低优先级任务里,其他高优先级任务不断抢占,两次转换之间时间不一致会影响数据一致性。我建议把温度采集放到高优先级短任务中,得到结果后通过消息队列发给控制任务,避免在长任务里慢慢读。

5.4 总线上多个探头的地址和时序细节

1-Wire 协议最烦人的点之一就是搜索 ROM。如果你的代码写得不够严谨,遇到总线上两个探头的序列号接近时就容易死循环或漏读。我在项目里实现时,把搜索过程分成“读第一位”“读互补位”“决策选择”三个步骤,并用一个数组保存当前路径,配合 CRC 校验,否则总线上偶尔会出现幽灵探头。

如果探头数量不超过 8 个,更稳妥的做法是用“读型号匹配 + 跳过 ROM”的粗糙办法吗?不行。只有在只有一个探头时可以直接用 0xCC 跳过 ROM 去读温度。多探头不加匹配就并发响应,总线直接崩溃。

多探头扩展有一个误区:以为把传感器插到总线上就能立刻全部识别。实际第一次下载程序后,建议先跑一次“仅搜索 ROM 并打印”的临时固件。把所有 ROM 码复制到正式配置里,再跑匹配读取。这样比每次都做动态 ROM 搜索简单可靠得多。还有一个好处:如果现场有一颗探头损坏,对比 ROM 列表能在 1 分钟内定位是哪条支路。

调试到这个阶段,我自己养成了一个习惯:凡是接远程传感器的项目,第一版验证固件一定把“读复位脉冲、读 ROM、读暂存器、CRC 校验”拆成四个独立的控制台操作,而不是一次性把整个采集链路跑完。先确认芯片还在,再确认地址能读到,然后解析数据,最后才进入滤波和控制逻辑。这个方法在 PJ85718DM 和 R7FA4M3AF3CFB144 的组合上目前百试百灵,也建议你拿到板子后先花一个小时做这四步验证,再考虑后续的事情。

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

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

立即咨询