1. 项目概述:为什么嵌入式和 HVAC 都需要“本地 + 远程”双路测温
做 HVAC 控制的同行应该都有这种体会:一套系统里最让人头疼的不是 PID 参数怎么整定,而是温度到底准不准、稳不稳、能不能在恶劣现场活下来。空调箱、风机盘管、冷站机房这些地方,传感器往往要放到风道深处、盘管回弯处、压缩机排气管附近,线一拉就是好几米甚至十几米,环境里还有变频器和接触器窜过来的共模干扰。你辛辛苦苦搭了一个 NTC 分压电路,换一个批次的热敏电阻回来,B 值漂了、标定表全变,脾气再好也扛不住。所以我在做嵌入式和 HVAC 项目的测温模块时,选型思路就一个字:稳。
这个项目实际做的事,是拿一颗 PJ85718DM 温度采集前端搭配 PIC32MZ1024EFE144 主控 MCU,实现“本地温度 + 远程温度”的双通道监测。本地温度指传感器所在 PCB 位置的环境温度,远程温度指通过外接二极管连接方式监测的远端点位温度。整套系统负责温度读取、换算、校准、滤波,再把数据通过 RS-485 总线上送给 HVAC 集中控制器,同时根据温差输出 PWM 驱动风机或者比例阀。
这个方案适合两类读者。一类是嵌入式工程师,想搞清楚怎么把带远程二极管通道的温度传感器和 32 位 MCU 组合起来做多点采集;另一类是 HVAC 自控工程师,想了解现场测温链路从硬件到协议的完整做法。下文不打算抄数据手册,只讲我在样机调试和现场运行里总结出来的东西,包括关键参数怎么算、坑在哪里踩、固件怎么写才顺手。无论你是从零搭板子,还是想把现有方案升级,都能从里面找到可以直接抄走的套路。
2. 器件选型解析:PJ85718DM 和 PIC32MZ1024EFE144 为什么能搭在一起
2.1 PJ85718DM:一颗芯片搞定两路温度信号
温度采集是整个方案的地基。PJ85718DM 这类芯片最核心的价值,是把本地带隙测温和外接二极管测温集成在一个封装里。本地通道用芯片内部的带隙结构测量自身结温附近的温度,精度通常能做到 ±0.5~1°C 级别;远程通道则是向外部二极管结注入两档不同的偏置电流,通过测量 ΔVbe 来反推绝对温度。
原理上,一个二极管结的压降与温度呈近似线性关系,但单点压测受工艺和器件差异影响很大。采用两档电流比值 N 测量 ΔVbe 的好处是,器件的反向饱和电流和串联电阻项被消掉了,剩下 (kT/q)·ln(N) 这一项,天然与绝对温度成正比。芯片内部再用查表和线性拟合把它换算成摄氏温度,精度可以做得很稳。这个原理理解透了,后面你调试“为什么远程温度总是偏高或偏低”时,就知道该往哪个方向查。
PJ85718DM 的对外接口是标准 I2C/SMBus,从机地址一般可以通过地址引脚组合扩展,一条总线上挂多个传感器非常方便。数据格式方面,温度寄存器通常是高字节加低字节的组合:高字节是整数部分,低字节的高几位是小数部分,常见分辨率有 12 位,对应步进 0.125°C。芯片还带可编程的 ALERT/THERM 输出引脚,可以配置成温度越限中断,直接接 MCU 的 GPIO 做事件触发,主控不必一直轮询。
2.2 PIC32MZ1024EFE144:主控的资源画像
PIC32MZ1024EFE144 属于 PIC32MZ EF 系列,主频最高 200MHz,在同类 32 位 MCU 里属于相当能打的。它内部有 1MB Flash 和 512KB RAM,跑一个完整的上位机通信协议栈,再加上滤波、PID 控制、数据记录,内存空间非常宽裕。尤其是 Flash 采用双面板结构,可以实现运行时在线升级,这对 HVAC 现场设备意义很大——控制器装在吊顶里、几十台设备分布在楼宇各层,挨个断电刷固件是灾难级的运维体验,有了双面板 Flash 就能跑引导加载程序放心升级。
外设方面,这颗芯片的 UART、I2C、SPI 数量都足够用。PJ85718DM 独占一个 I2C,RS-485 用一路 UART,剩余的还能挂 LCD、按键或者别的传感器。部分型号还带 CAN 和以太网 MAC,如果后续要接楼宇自控网络,或者把数据推给物联网平台,这个预留空间就很有价值。我实际选择 144 引脚封装的原因也很朴素:引脚足够多,样机阶段用普通电烙铁配合 TQFP 适配座就能手工焊接调试,后期转到批量贴片生产完全不受影响。
2.3 两者的接口匹配逻辑
选型最重要的不是单看性能,而是看接口怎么握手。PJ85718DM 挂在 I2C 总线上,PIC32MZ 的 I2C 控制器可以直接配置成 400kHz 快速模式,时序兼容性很好。远程二极管通道本身不占用 MCU 的模拟引脚,测温完全由传感器前端处理,主控只需要读写寄存器,这样就把 ADC、参考电压、多项式拟合这些麻烦事全部隔离出去了。
我在最初设计时也考虑过直接用 PIC32MZ 自带的 12 位 ADC 配合模拟温度传感器做方案。后来放弃了,原因有三:一是模拟前端需要额外做恒流源激励和信号调理,HVAC 现场走线长,压降和噪声很难控制;二是软件校准成本高,每一块板子都要跑一遍标定流程;三是 ADC 的温漂在宽温范围下会把测量精度吃光。与其在模拟端跟噪声搏斗,不如让一颗成熟的数字温度前端把这些事干完。
3. 硬件电路设计:原理图关键节点与参数计算
3.1 PJ85718DM 最小系统与供电
PJ85718DM 的供电一般接受 3.0~3.6V 范围,系统里直接和 PIC32MZ 共用 3.3V 电源轨即可。电源要特别注意两点:第一,温度测量本质上是毫伏级信号的分辨,电源纹波会直接影响本地通道精度,所以传感器供电要加一个小磁珠和 0.1µF、10µF 两级去耦电容,别图省事直接接到数字 3.3V 上;第二,传感器尽量远离 MCU 的晶振和 DC-DC 电感,因为高频开关噪声会通过 PCB 走线耦合进测温电路。
芯片的 SDA、SCL 是标准开漏结构,必须接上拉电阻,这里的计算不是随便取一个 4.7kΩ 就完事的,后面单独讲。ALERT 引脚同样建议用上拉电阻接到 VDD,同时串一个几百欧的电阻做保护,避免外部误接导致过流。ALERT 在多传感器场景下可以做成开漏线与方式,任何一个通道越限都能拉低中断线,MCU 再通过读状态寄存器判断到底是哪一颗触发的,这种设计在样板调试时特别省事。
3.2 本地温度通道的布局注意事项
本地温度的准确性往往被低估。很多人以为 PJ85718DM 的本地通道测的是“环境温度”,但实际上它测的是芯片自身结温附近的温度。如果芯片旁边正好躺着一颗大电流 MOSFET 或者开关电源电感,本地读数会比真实环境温度高出好几度。测量点位到底要代表哪个温度,这个逻辑得先理清楚:如果你想测 PCB 附近空气温度,就把传感器放在风的来流方向,不要和发热器件共用同一块铜箔散热路径;如果你就是想测板卡结温用来做保护,那反而应该贴近功率器件,让热路径尽量短。
我踩过的坑是:首版 PCB 把 PJ85718DM 放到了电源电感的背面,结果本地温度读数比红外测温枪实测高了大约 3°C。后续把传感器挪到板边,加了一个通风开孔区域,读数才恢复正常。这种问题在原理图上看不出来,只能在版图阶段解决,所以画板时一定要做热仿真,或者至少目测一下发热源分布再定传感器位置。
3.3 远程二极管通道的连线与 EMI 抑制
远程通道的接线是这套方案最容易出问题的环节。标准接法是:用一颗 PNP 晶体管接成二极管形式,发射极接 D+,基极和集电极短接后接 D-,这样传感器从 D+ 注入电流,经发射结从 D- 返回。选分立 PNP 管而不是普通二极管,是因为它的封装热阻小、能贴到被测物体表面,而且理想因子 n 比较接近传感器内部的默认假设,测量误差可控。
连线方面,D+ 和 D- 必须走双绞线或者紧贴的差分线对,千万不要把这两根线分开拉。因为远程通道是靠差分电压计算的,共模干扰在理想情况下可以抵消,但只要两条线在空间上不平行,共模转差模就会发生,读数就会出现随机跳变。我遇到过最典型的案例:传感器线缆和变频器输出线在同一个线槽里走了三米,温度读数噪声到了 ±2°C,后来把传感器线换成屏蔽双绞线,并在传感器端并联一个 220pF 电容,噪声立刻压回 ±0.2°C 以内。
这个并联电容的作用是滤除高频射频干扰,但容值不能随便加大。过大的电容会拖慢传感器内部的偏置切换,导致 ΔVbe 采样还没稳定就被读取,反而引入测量误差。按我自己的经验,传感器端的并联电容控制在 100pF 到 470pF 比较合适,具体上限以 PJ85718DM 数据手册为准。如果线特别长,与其靠加电容,不如把传感器做成一个小模块,靠近被测点放置后只引供电和 I2C 信号,抗干扰能力会好很多。
3.4 I2C 上拉电阻的计算过程
I2C 上拉电阻的取值很多新手拍脑袋,其实公式就两条。第一条满足低电平输出能力:
Rp(min) = (VDD - VOLmax) / IOL
以 3.3V 供电、标准开漏输出 VOLmax=0.4V、IOL=3mA 为例:Rp(min) = (3.3 - 0.4) / 0.003 ≈ 967Ω,取整为 1kΩ。第二条满足上升时间约束:
Rp(max) = tr / (0.8473 × Cbus)
400kHz 快速模式的上升时间要求 tr 不超过 300ns。如果总线上有传感器加上 MCU 引脚,估算总电容 200pF,那 Rp(max) = 300ns / (0.8473 × 200pF) ≈ 1.77kΩ。所以理论区间是 1kΩ 到 1.77kΩ,取标准值 1.5kΩ 或 1.8kΩ 都能正常工作。
实际项目中我一般这样定:总线上只有一颗 PJ85718DM 且走线很短,用 2.2kΩ;如果挂了多颗传感器或者走线超过 20cm,用 1.8kΩ;如果要兼顾低功耗和超低上升时间,用 1.5kΩ 也可以,只是开漏下拉功耗稍大一点。千万别为了省电选 4.7kΩ,在 400kHz 下波形很容易变圆角,表现就是偶尔丢 ACK,排查起来特别费劲。
4. 固件开发:从寄存器配置到温度换算
4.1 I2C 初始化的标准流程
固件的第一步是把 PIC32MZ 的 I2C1 外设配置成主模式。这里需要设置波特率寄存器,目标 400kHz。按外设时钟 100MHz 估算,BRG 值用公式 baud = FPB / (2 × 400kHz) - 1 计算,大约取 124。这个值只是起点,如果示波器看到 SCL 实际频率偏差超过 5%,就微调 BRG 值。
配置完波特率后,把 I2C1 模块使能,再通过发送起始位和从机地址做一次“假读”,确认总线上设备在线。我习惯在初始化最后加一段总线扫描:依次发 0x00 到 0x7F 的地址,记录返回 ACK 的设备地址并打印到串口。这套诊断逻辑在样机阶段非常有用,能第一时间发现地址冲突,或者某颗传感器没焊好。
下面是一段简化的初始化示例,具体寄存器定义以选用的 MCU 库为准:
void i2c1_init(void) { I2C1BRG = 124; // 400kHz @ FPB=100MHz I2C1CON = 0x0000; // 主模式 I2C1CONbits.ON = 1; } uint8_t i2c1_write_reg(uint8_t addr, uint8_t reg, uint8_t val) { // 发送起始位 + 从机地址 + 寄存器地址 + 数据 + 停止位 // 返回 0 表示成功,非 0 表示无 ACK }4.2 本地温度数据的读取与格式转换
PJ85718DM 的温度寄存器一般按照“高字节 + 低字节”存放。读取时要先写寄存器指针,再连续读两字节。以 12 位分辨率为例,高字节是整数部分,低字节的高 4 位是小数部分,所以原始 16 位值统一右移 4 位后,乘以步进 0.125°C 就是实际温度。下面这段转换逻辑是这类传感器通用的写法,具体寄存器地址请以手头芯片的最新数据手册为准:
uint16_t raw = read16(PJ85718_LOCAL_TEMP_REG); int16_t val = (int16_t)(raw >> 4); // 符号扩展 double temp_c = (double)val * 0.125;要注意的是符号处理。低温场景下寄存器值是二进制补码,如果你直接把 uint16_t 当有符号数去乘,零下温度就会变成一个巨大的正数。我见过不止一次有人把 -5°C 读成 65000 多摄氏度,然后一脸困惑地来问为什么 PID 直接冲顶。解决办法就是上面代码里的强制类型转换:先把符号位正确扩展,再进行右移和乘法。
4.3 远程温度通道的处理与校准
远程通道的读取方式与本地通道类似,但多了一层器件相关校准。外接 PNP 管类型不同,理想因子 n 会有细微差异。传感器芯片内部通常默认一个 n 值,如果你的管子实际值有偏差,在温差大的时候就会出来约 1°C 量级的系统性误差。这种偏差是固定的,用软件补偿非常划算:在常温下标定一次,记录偏差 offset;再在高温或低温下标定第二次,算出增益系数。校正公式就是:
T_corrected = (T_raw - offset) / gain
这两个参数可以存到 PIC32MZ 的 Flash 用户区。我建议在应用程序里做一个小型校准页面,通过串口命令就能修改 offset 和 gain,不需要重新编译固件。现场调试时带一台标准温度校验仪,改两个参数点一下保存,比反复烧录固件快太多了。
除了温度换算,远程通道还要处理“开路”和“短路”故障。PJ85718DM 这类器件一般会在状态寄存器里报告 D+ 对地、D+ 对 VDD 短路等异常。固件里必须每轮巡检都读一次状态字,一旦检测到传感器故障,就把该通道的温度强制置成安全值,同时触发 ALERT 上报。否则故障通道读数一旦失控,PID 可能把风机开到满转,直接把被控对象带飞。
4.4 数据滤波与 HVAC 联动逻辑
现场温度数据的抖动来源很多:气流扰动、压缩机启停、传感器自身噪声。PID 控制对上来的数据要求稳定,但也不能过度滤波导致响应滞后。我的默认策略是三级处理:先做一次 5 点中值滤波,干掉单点毛刺;再做滑动平均,窗口取 10 个样本,压制高频噪声;最后用一个一阶低通,时间常数按被控对象特性设 30 到 60 秒。三个环节叠加后,测量噪声可以压到 ±0.1°C 以内,而对一个 5°C 的阶跃响应,滞后也就十几秒,对 HVAC 场景完全够用。
滤波之后进入联动逻辑。我这边把 PID 计算出的 0~100% 输出映射到 PWM 占空比,由 PIC32MZ 的 Output Compare 模块生成 10kHz 载波驱动风机调速板;同时在温差超过阈值时,通过 GPIO 切换加热器的比例阀开度。PIC32MZ 的定时器和 OC 模块配合很灵活,10kHz 的 PWM 分辨率可以做到 1% 以内,驱动风机时听不到明显噪音,也不会和传感器采样频率产生拍频干扰。采样周期我用 1 秒,PID 周期 5 秒,这个搭配在实测里比较稳定,既不反应过敏,也不会把温度波动放大到执行机构上。
5. 远程通信与上位机集成方案
5.1 RS-485 总线和 Modbus RTU 帧设计
现场数据最终要离开板子,交给 HVAC 集中控制器。我的选择是 RS-485 加 Modbus RTU,原因很现实:楼宇自控领域的既有系统十有八九支持 Modbus,不需要额外写私有协议;RS-485 在 9600 波特率下能拉几百米,抗共模干扰能力比 UART 直连强太多;而且 Modbus RTU 帧格式简洁,用 DMA 收发都不怎么占 CPU。温度数据放在保持寄存器区,每路温度占一个寄存器,单位为 0.1°C。比如寄存器地址 0x0001 放本地温度,0x0002 放远程温度,0x0003 放本地与远程的温差。
读取帧格式为:设备地址 1 字节,功能码 0x03 占 1 字节,起始地址占 2 字节,寄存器数量占 2 字节,最后跟 2 字节 CRC16。应答帧把数据区按高低字节返回。CRC16 用查表法实现,PIC32MZ 跑 9600 波特率毫无压力,即使升到 115200 也没问题。设备地址管理上,推荐用拨码开关加默认地址的组合:拨码设 1 到 247,开机时读取地址并写入全局变量;同时保留一个串口命令可以在运行时修改。这样几十台测控终端挂在总线上,每台的地址一目了然,现场维护时不用拆盖子就知道是哪台设备。
5.2 数据上送与报警处理
光有寄存器轮询还不够,越限报警得主动推送。我的实现方案是把 ALERT 中断和 Modbus 结合起来:PJ85718DM 的 ALERT 引脚接 PIC32MZ 的外部中断输入,温度越限时芯片拉低引脚,MCU 在中断服务程序里置一个“报警标志”。主循环检测到标志后,读取状态寄存器确定是哪一路越限,然后通过自定义功能码向主站推送报警数据包。主站不用高频轮询,也能在几秒内知道现场异常,比纯查询方案及时得多。
报警阈值不要写在软件里写死。我在配置寄存器里留了一组参数:本地高温报警阈值、远程高温报警阈值、远程低温报警阈值、回差。这些参数都可以通过 Modbus 写寄存器在线修改,方便调试时试探不同设定值。回差这个参数很多人忽略,但它在 HVAC 现场非常重要——没有回差的阈值切换,风机在阈值附近会反复启动停止,接触器寿命直线下降。我的经验是回差至少设 2°C,既不能频繁切换,也不能让超温幅度太大,这个平衡点要用现场数据慢慢调。
5.3 与 HVAC 控制器的联动实例
最后说一个实际跑通的联动场景。某个项目的测控终端管理一组空调箱:PJ85718DM 的本地通道测回风温度,远程二极管贴在送风风道内的盘管翅片上测盘管温度。集中控制器通过 Modbus 每 10 秒读一次两个温度,计算温差,再根据温差查一张风阀开度表。温差大于 5°C 说明盘管换热充分,风阀保持当前开度;温差小于 2°C 说明风量过大或者供能不足,控制器先把风阀收小,同时发出预警。
这套逻辑看起来简单,但实际效果的关键在于远程二极管的安装质量。把二极管贴到翅片上时,必须用导热胶填满缝隙,并确保电学隔离。我第一次现场安装时直接用金属卡扣压上去,结果 D+ 与地之间的绝缘电阻发生变化,读数忽高忽低,现场折腾了半天才定位到是安装方式的问题。后来统一改用带绝缘层的预封装传感器模块,这个问题就再也没出现过。
6. 调试实录与避坑指南
6.1 现场遇到的高频问题
整个项目调试下来,我把踩过的坑整理成一张速查表,分享出来。这些问题的现象千奇百怪,根源往往都很简单,按表排查能省下大量时间。
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| 远程温度读数整片偏高或偏低 | 外接 PNP 管理想因子与芯片默认值不匹配 | 软件加 offset/gain 校正,或换用数据手册推荐型号 |
| 远程温度随机跳动 ±1°C 以上 | 线缆双绞不充分、共模噪声过大 | 换屏蔽双绞线,传感器端并联 100~470pF 电容 |
| I2C 偶发无响应或丢 ACK | 上拉电阻偏大,上升沿过缓 | 按正文公式计算,换 1.5kΩ 或 1.8kΩ 上拉 |
| 本地温度明显高于室温 | 芯片靠近发热源 | 调整 PCB 布局,远离电源电感和功率器件 |
| 零下温度显示成巨大正数 | 温度寄存器符号扩展处理错误 | 将 16 位原始值先强制转为 int16_t 再处理 |
6.2 经验性排查清单
排查的顺序比方法更重要。我在现场一般遵循“先硬件后软件、先隔离后分析”的原则:先把传感器从系统中断开,用电阻箱模拟一个二极管,看读数是否正常,这一步能判断到底是传感器坏了还是主控代码有问题;再把主控从通信总线断开,单独测量板卡的 I2C 波形,确认时钟和数据帧格式正确;最后才把所有设备接起来看整体表现。
远程通道还有一个隐蔽的坑:如果你用的是带插座的分立 PNP 管,插座本身的热电势和接触电阻会给测量带来额外误差。工业现场强烈建议直接用焊盘贴装,或者用已经封装好的传感器模块,不要留插座。另一个坑是远程通道的线材电阻补偿。PJ85718DM 一般有串联电阻补偿功能,默认可能按某个阻值配置,如果你的传感器线细而长,超过 5 米,就一定要开启补偿并填入实际线阻,否则远距离测出来的温度会偏低。这两个问题都是比较难从原理图上发现的,只能靠现场经验和测量来找。
6.3 一个非常实用的自校准流程
每次调试到最后,我都会在固件里保留一个自检功能:上电后连续读取本地温度和远程温度 100 次,把最大值、最小值、平均值打到串口。这样做有三个好处:第一,能在现场快速判断传感器安装是否可靠——如果 100 次读数里最大值和最小值相差超过 0.5°C,说明安装处存在热容不足或者电磁干扰;第二,平均值可以作为出厂校准的数据接入点;第三,这个记录留在调试日志里,日后客户抱怨温度不准时,翻出这个上电自检数据,很容易判断是传感器老化还是机房环境变了。
这个项目做到现在,我个人最深的体会是:温度监测方案的设计重心从来不在 ADC 有多强、MCU 有多快,而在怎么把工程误差压到最小。PJ85718DM 把模拟难题封装掉了,PIC32MZ1024EFE144 把数据加工和通信难题消化掉了,剩下需要你亲手处理的,其实是布局、走线、校准流程这些看起来不起眼的细节。把这层功夫做到位,嵌入式和 HVAC 的绝大多数温度监测需求,基本都能稳稳接住。