1. 项目缘起与整体设计思路嵌入式温度监测这件事说起来简单做起来全是细节。我最早接触这个方向是在一个环境控制类项目里当时的需求很朴素一块主控板要同时盯着本地机箱内的温度还要通过远程传感器采集几个不同位置的温度数据最终汇总上报并触发相应的控制逻辑。听起来像是教科书里的入门实验但真正落地的时候从传感器选型、通信协议、采样时序到数据校准每一步都有坑。这次要聊的方案核心是两颗器件PJ85718DM和PIC32MZ2048EFM064。前者是一颗远程温度传感器支持本地和远程双通道测温通过 I2C 或 SMBus 接口与主控通信后者是 Microchip 的 PIC32MZ 系列高性能 MCU2048KB Flash、512KB RAM带 FPU主频可以跑到 200MHz用来做温度采集、数据处理和通信调度绰绰有余。为什么选这个组合先说需求背景。嵌入式和 HVAC暖通空调场景下的温度监测有几个硬性约束第一测温点往往不止一个本地板载温度要测远程的管道温度、回风温度、出风温度也要测第二远程传感器通常离主控有一段距离走 I2C 的话距离受限所以很多远程温度传感器会采用二极管接法或者 BJT 接法把感温元件放在远端通过走线连回传感器芯片第三HVAC 场景对可靠性要求高温度数据不能跳变、不能丢采样频率和滤波策略要合理。PJ85718DM 这颗芯片正好覆盖了这些需求。它支持本地温度传感和远程温度传感远程端可以接二极管连接的晶体管或者 CPU/FPGA 内置的热二极管测温范围覆盖 -40°C 到 125°C 左右精度在关键区间可以做到 ±1°C 以内。通信接口是标准的 I2C/SMBus地址可配置方便挂多个传感器。PIC32MZ2048EFM064 这边I2C 外设资源丰富多个 I2C 模块可以并行工作DMA 也能减轻 CPU 负担配合定时器做周期性采样非常顺手。整体设计思路可以拆成三层感知层负责温度数据的原始采集包括 PJ85718DM 的本地通道和远程通道处理层由 PIC32MZ 完成数据读取、校准、滤波、越限判断通信层则根据具体应用把处理后的温度数据通过 UART、CAN 或者以太网送到上位机或云端。这个三层结构的好处是解耦传感器换型不影响上层逻辑通信协议调整也不影响采集时序。注意远程温度传感器的走线是整套方案里最容易被忽视的环节。走线过长、走线太细、旁边有开关电源或者 PWM 驱动都会让远程测温数据出现明显偏差。我在早期项目里就吃过这个亏远程通道读数比实际高了七八度排查了半天才发现是走线经过了一个 DC-DC 模块旁边。从影响范围来看这套方案适用的场景其实很广。HVAC 里的新风机组、风机盘管、冷热源监控工业控制里的机柜温度监测、电机绕组温度监测甚至一些医疗设备的环境温度记录都可以用类似的架构。区别只在于传感器的通道数、精度要求和通信方式。PIC32MZ2048EFM064 的性能冗余比较大如果只是做温度监测其实用不了这么多资源但它的优势在于扩展性——后面要加湿度、压力、流量传感器或者要跑一些简单的控制算法这颗 MCU 都能扛得住。2. 核心器件解析与选型考量2.1 PJ85718DM 的功能特性与适用边界PJ85718DM 是一颗双通道温度传感器本地通道测的是芯片自身所在的 PCB 温度远程通道测的是外接感温元件的温度。它的核心价值在于把远程感温元件和信号调理电路分开了——感温元件可以是一颗便宜的三极管放在远离主控的地方而信号调理和 ADC 转换都在 PJ85718DM 内部完成通过 I2C 把数字量读出来。这颗芯片的几个关键参数需要重点关注。测温分辨率方面本地通道和远程通道通常都是 0.125°C 或者 0.0625°C 的 LSB具体看配置寄存器怎么设。转换速率可调从每秒几次到每秒几十次都有速率越高功耗越大噪声也会相应增加。远程通道的测温范围一般比本地通道宽一些因为远程二极管可以放在高温区域而芯片本身要待在常温环境里。地址配置是 I2C 器件的老话题。PJ85718DM 通常有 3 个地址引脚可以配置出 8 个不同的 I2C 地址这意味着同一条 I2C 总线上最多可以挂 8 颗同型号芯片。如果测温点更多要么换用多路复用的 I2C 开关要么用多路 I2C 总线。PIC32MZ2048EFM064 有多个 I2C 模块我一般会把本地传感器和远程传感器分到不同的 I2C 总线上避免一条总线出问题导致所有温度数据都丢失。实操心得PJ85718DM 的远程通道在出厂时通常有一个默认的二极管理想因子配置如果外接的感温三极管型号和默认配置不匹配读数会有系统性偏差。我一般会在初始化阶段写一个校准流程用一个已知温度点比如冰水混合物或者恒温槽去反推理想因子把校准值写回配置寄存器。2.2 PIC32MZ2048EFM064 的资源分配与优势PIC32MZ2048EFM064 是 Microchip 的 MIPS M-Class 内核 MCU200MHz 主频带浮点运算单元2048KB Flash 和 512KB RAM。这个资源量对于温度监测来说是很奢侈的但它的价值在于“留余量”。温度监测往往只是系统的一个功能模块后面可能还要加显示、通信、控制、数据存储如果 MCU 资源刚好够用后面加功能就会很痛苦。I2C 外设方面PIC32MZ 系列通常有 5 个以上的 I2C 模块每个模块都支持主从模式、7 位和 10 位地址、标准模式和快速模式。我一般会把 I2C 时钟设到 400kHz这个速率下 PJ85718DM 的读写时序完全跟得上同时也不会因为速率太高导致信号完整性变差。如果走线比较长可以降到 100kHz牺牲一点采样速度换稳定性。DMA 是 PIC32MZ 的一个亮点。温度采集如果做成定时器触发、I2C 读取、数据存入缓冲区的流程用 DMA 可以把 CPU 从频繁的中断里解放出来。具体做法是配置一个定时器周期性触发 I2C 读取I2C 接收寄存器满的时候触发 DMA 搬运DMA 把数据搬到内存缓冲区攒够一批数据再通知 CPU 处理。这样 CPU 的占用率可以压得很低留给其他任务的时间就多了。2.3 本地与远程测温的架构差异本地测温和远程测温在硬件架构上有本质区别。本地测温的感温元件就在芯片内部测的是芯片结温或者封装温度响应快、噪声小但测的不是环境温度而是芯片附近的 PCB 温度。如果芯片旁边有发热元件本地读数会偏高。远程测温的感温元件在外部测的是目标位置的温度响应速度取决于感温元件的热质量和走线的热传导噪声也更容易受干扰。在 HVAC 应用里本地通道通常用来监测控制板自身的温度防止板子过热远程通道用来监测风道温度、水温、回风温度这些真正需要控制的对象。两者的数据处理策略也不一样本地通道可以做快速越限判断一旦超过阈值立即触发风扇或者降频远程通道需要做更多的滤波和校准因为走线干扰和感温元件的个体差异都会影响精度。3. 硬件设计与信号链细节3.1 远程感温元件的选型与连接方式远程感温元件一般用二极管连接的三极管比如 MMBT3904 或者类似的小信号 NPN。把基极和集电极短接发射极和基极之间形成一个 PN 结这个 PN 结的正向压降随温度变化PJ85718DM 就是通过测量这个压降来反推温度的。选三极管的时候要注意几个点第一理想因子要接近 1.0偏离太大会导致测温偏差第二封装要小热质量小响应才快第三要放在目标测温位置用导热胶或者金属壳固定好。连接方式上三极管的基极-集电极短接点接到 PJ85718DM 的远程正端发射极接到远程负端中间串一个小电阻限流。走线要用差分走线尽量靠近远离高频开关信号。如果走线超过几十厘米建议用屏蔽线或者双绞线屏蔽层单点接地。我见过一个案例远程三极管的走线和电机的 PWM 线捆在一起温度读数直接跳了十几度后来把走线分开就好了。3.2 I2C 总线的上拉电阻与滤波I2C 总线的上拉电阻取值是个老生常谈的问题但温度监测场景下尤其重要。上拉电阻太大上升沿变缓高速通信时容易出错上拉电阻太小功耗增加低电平时的灌电流可能超过器件的承受能力。标准做法是根据总线电容和通信速率来算公式是 R tr / (0.8473 × C)其中 tr 是上升时间C 是总线电容。400kHz 快速模式下上升时间要求小于 300ns如果总线电容是 100pF上拉电阻大概在 3.5kΩ 左右。实际项目中我一般先用 4.7kΩ 试如果波形上升沿太慢就降到 2.2kΩ如果功耗敏感就升到 10kΩ 但把速率降到 100kHz。PJ85718DM 的 I2C 引脚通常有施密特触发器输入对缓慢的上升沿有一定容忍度但不要依赖这个特性波形该修还是要修。滤波方面I2C 的 SDA 和 SCL 线上可以各串一个几十欧姆的电阻再并一个小电容到地组成低通滤波。电阻不能太大否则会影响低电平的噪声容限电容也不能太大否则会拖慢上升沿。我一般用 33Ω 电阻加 100pF 电容实测对几十兆赫兹的干扰有不错的抑制效果。3.3 电源与地平面的处理温度传感器的精度对电源噪声很敏感。PJ85718DM 的供电电压一般是 3.3V 或者 5V具体看型号。供电引脚旁边要放 0.1μF 和 1μF 的退耦电容尽量靠近芯片。如果板上还有开关电源传感器的供电最好用 LDO 单独稳一路或者至少在电源入口加一个 LC 滤波。地平面的处理同样关键。模拟地和数字地要分开布局最后在一点汇合。PJ85718DM 的接地引脚要接到模拟地I2C 的上拉电阻接地也要接到模拟地。如果地平面被分割得乱七八糟地电流会在地阻抗上产生压降这个压降会叠加到温度读数上表现为低频漂移或者随机跳变。4. 固件架构与采样时序设计4.1 I2C 驱动层与传感器抽象层固件这边我习惯把 I2C 驱动和传感器操作分开。I2C 驱动层只负责基本的读写时序提供i2c_write、i2c_read这样的接口不关心具体接的是什么器件。传感器抽象层则封装 PJ85718DM 的寄存器操作提供pj85718_read_local_temp、pj85718_read_remote_temp、pj85718_set_config这样的接口。这样分层的好处是如果后面换用其他型号的温度传感器只需要改传感器抽象层I2C 驱动层不用动。PIC32MZ2048EFM064 的 I2C 外设配置有几个关键点。时钟源要选对一般用外设总线时钟分频得到 400kHz。中断优先级要设好温度采集的中断优先级可以设得高一点但不要高过系统关键中断。如果用了 DMADMA 通道的优先级和触发源要配置正确否则会出现数据搬运不及时导致 I2C 接收溢出。4.2 采样周期与滤波策略采样周期怎么定取决于被测对象的温度变化速率和系统的响应要求。HVAC 里的风道温度变化比较慢采样周期可以放到 1 秒甚至更长电子设备的板载温度变化快一些采样周期可以放到 100 毫秒。采样太快没有意义反而会增加功耗和数据处理负担采样太慢又可能错过温度突变。滤波策略我一般用两级第一级是硬件滤波靠 I2C 线上的 RC 和传感器内部的数字滤波第二级是软件滤波用滑动平均或者一阶低通。滑动平均的窗口长度取 8 或者 16对随机噪声抑制效果好但会引入滞后。一阶低通的公式是y[n] α × x[n] (1-α) × y[n-1]α 取 0.1 到 0.3 之间兼顾响应速度和稳定性。注意如果被测温度本身有周期性波动比如压缩机启停导致的风道温度波动滑动平均的窗口长度不要取成波动周期的整数倍否则会把真实波动滤掉。我一般会先录一段原始数据看看波动周期大概是多少再决定滤波参数。4.3 越限判断与报警逻辑温度监测的最终目的是在温度异常时做出响应。越限判断的逻辑看似简单其实有很多细节。首先是阈值设定不能只设一个上限要设预警阈值和报警阈值两级。预警阈值触发时系统可以降频、开风扇、记录日志报警阈值触发时系统要采取更激烈的措施比如停机或者切断负载。其次是回差设计。如果温度在阈值附近来回波动没有回差的话报警会频繁触发和解除形成抖动。回差一般设 2°C 到 5°C具体看应用。比如上限设 85°C回差设 3°C那么温度超过 85°C 触发报警降到 82°C 以下才解除报警。最后是报警延时。温度瞬间超过阈值可能是干扰导致的不一定是真实过热。我一般会加一个确认时间温度连续超过阈值达到一定次数或者一定时间才真正触发报警。这个确认时间取 3 到 5 个采样周期比较合适。5. 实操过程与关键环节实现5.1 硬件连接与上电检查先说一下硬件连接的具体步骤。PJ85718DM 的 VCC 接 3.3VGND 接模拟地SDA 和 SCL 分别接 PIC32MZ 的 I2C 模块引脚同时各接一个 4.7kΩ 上拉电阻到 3.3V。远程感温三极管的基极和集电极短接后接 PJ85718DM 的 D 引脚发射极接 D- 引脚。如果用的是 CPU 内置的热二极管连接方式类似但要注意理想因子和串联电阻的配置。上电之后先不要急着读温度先用示波器看一下 I2C 的波形。SCL 和 SDA 的空闲电平应该是高上拉电阻有没有焊、阻值对不对一眼就能看出来。然后发一个简单的 I2C 读操作看从机有没有 ACK。如果没有 ACK先查地址对不对再查供电和地有没有问题。5.2 寄存器配置与初始化流程PJ85718DM 的初始化流程大概是这样先写配置寄存器设置转换速率、分辨率、远程通道的二极管配置然后写阈值寄存器设置本地和远程通道的报警上下限最后写一次单次转换命令或者启动连续转换模式。配置寄存器的具体位定义要看数据手册不同型号的位定义可能不一样不要凭记忆写。PIC32MZ 这边的初始化包括配置 I2C 模块的时钟和引脚配置定时器用于周期触发配置 DMA 通道用于数据搬运配置中断优先级。初始化顺序很重要先配时钟再配外设先配外设再开中断。如果顺序反了可能会出现外设还没配好中断就来了导致异常。5.3 温度读取与数据校准温度读取的流程是发 I2C 起始条件写从机地址加写位写寄存器地址发重复起始条件写从机地址加读位读两个字节的温度数据发停止条件。温度数据的格式一般是高字节在前低字节在后高字节的某些位可能包含标志位要按数据手册的格式解析。校准是保证精度的关键。本地通道的校准相对简单用一个已知温度的环境读出生值算出差值写到偏移寄存器。远程通道的校准复杂一些因为涉及二极管理想因子和串联电阻。我一般用两点校准一个低温点比如 0°C 冰水混合物一个高温点比如 100°C 沸水或者恒温槽根据两个点的读数反推理想因子和偏移再写到配置寄存器。5.4 通信上报与数据记录温度数据处理好之后要通过通信接口上报。如果是有线通信UART 最简单配置好波特率、数据位、停止位把温度数据打包成帧发出去就行。CAN 总线适合多节点场景每个节点上报自己的温度数据主节点汇总。以太网适合数据量大的场景可以用 TCP 或者 UDP 上报UDP 实时性好但可能丢包TCP 可靠但延迟大。数据记录方面如果系统有外部 Flash 或者 SD 卡可以把温度数据按时间戳存下来方便事后分析。存储格式我一般用二进制比文本节省空间读取也快。每条记录包含时间戳、本地温度、远程温度、报警状态固定长度方便索引。6. 常见问题与排查技巧实录6.1 温度读数偏差大的排查思路温度读数偏差大是最常见的问题排查思路可以按下面的顺序来。先确认传感器本身有没有问题把传感器放到已知温度环境里看读数对不对。如果传感器本身没问题再查走线和连接远程三极管的引脚有没有接反、走线有没有断、焊点有没有虚焊。然后查电源和地供电电压对不对、退耦电容有没有焊、地平面有没有分割。最后查配置寄存器理想因子、串联电阻、分辨率这些参数有没有设对。下面这个表格整理了几种典型偏差现象和对应的可能原因方便快速定位。现象可能原因排查方法读数整体偏高理想因子配置偏大、自热效应重新校准理想因子、降低采样率读数整体偏低理想因子配置偏小、走线漏电重新校准理想因子、检查走线绝缘读数随机跳变电源噪声、I2C 干扰、地环路示波器看电源和 I2C 波形、加滤波读数缓慢漂移温度补偿不足、器件老化定期校准、检查补偿算法远程通道无读数三极管接反、走线断、配置错误万用表测通断、检查配置寄存器6.2 I2C 通信失败的常见原因I2C 通信失败的原因很多我按出现频率排个序。第一是上拉电阻问题没焊、阻值太大、阻值太小都会导致通信失败。第二是地址冲突同一条总线上挂了两个相同地址的器件或者地址引脚配置错了。第三是时序问题时钟速率太高、上升沿太慢、建立保持时间不够。第四是电源问题从机没供电或者供电电压不对。第五是总线锁死某个器件把 SDA 拉低不放导致总线无法恢复。总线锁死有个经典的恢复方法把 SCL 手动切换成 GPIO发 9 个时钟脉冲让从机把 SDA 释放然后再重新初始化 I2C。PIC32MZ 的 I2C 模块支持总线超时检测可以配置超时时间超时后自动复位 I2C 状态机。6.3 远程测温受干扰的抑制方法远程测温受干扰的表现是读数跳变或者有规律地波动。抑制方法分硬件和软件两个层面。硬件层面走线用双绞线或者屏蔽线远离高频开关信号必要时加共模扼流圈。软件层面增加滤波强度用中值滤波剔除明显的异常值或者用限幅滤波把超过物理可能范围的读数直接丢弃。还有一种干扰是来自被测对象本身的。比如远程三极管贴在电机外壳上电机启停时外壳温度快速变化这时候读数跳变是真实的不是干扰。区分方法是看跳变有没有规律如果和电机启停同步那就是真实温度变化不应该滤掉。6.4 低功耗场景下的优化技巧如果系统是电池供电的低功耗就很重要。PIC32MZ2048EFM064 本身有低功耗模式可以在两次采样之间进入休眠定时器唤醒。PJ85718DM 也支持关断模式不采样的时候关掉功耗可以降到微安级。I2C 的上拉电阻在休眠期间会持续耗电如果功耗要求很严可以用 GPIO 控制上拉的供电休眠时断开上拉。采样周期也可以动态调整。温度变化慢的时候采样周期放长温度变化快的时候采样周期缩短。这样既能保证响应速度又能降低平均功耗。7. 方案扩展与个人经验体会这套方案的基础架构搭好之后扩展方向其实很多。比如增加湿度传感器用同一路 I2C 总线地址不冲突就行。增加多点测温用 I2C 多路复用器扩展总线或者用多个 I2C 模块并行采集。增加本地显示用 SPI 或者并口接一个小屏幕实时显示温度曲线。增加无线通信用蓝牙或者 LoRa 模块把数据发到手机或者网关。我在实际项目里踩过的最大的坑是忽视了远程走线的热传导。远程三极管虽然放在目标位置但引脚和走线会导热如果走线经过温度不同的区域读数会被走线平均掉。后来我把三极管的引脚尽量短走线用细线减少热传导读数才准了。还有一个坑是 I2C 总线的电容一开始挂了太多器件总线电容超过 400pF通信不稳定后来加了 I2C 缓冲器才解决。最后分享一个小技巧温度传感器的校准不要只做一次器件老化、环境变化都会导致偏移。我一般会在系统里留一个校准接口定期用已知温度点重新校准把新的偏移值写到非易失存储器里。这样即使运行几年温度精度也能保持住。