
干过暖通控制系统开发和嵌入式板卡自检的人应该都碰过一类问题系统明明没坏但温度数据就是不好看要么掉线要么跳变要么偏差好几摄氏度。这篇博文围绕一套很具体的组合展开——PJ85718DM 这颗测温前端芯片配 STM32L4S5ZI 这颗低功耗主控统一去采集嵌入式板卡和 HVAC 场景里的本地温度与远程温度。文章会把现场测点梳理、选型理由、硬件接线、寄存器配置、软件实现、低功耗调度以及实测中踩过的坑完整讲一遍也适合正在做空调控制器、机房监控、冷链设备这类项目的开发者参考。1. 现场到底要测哪些温度先把测点定位清楚再谈芯片我在做暖通控制器这段时间最大的感受是很多人一开始就纠结用哪种温度传感器、选多少位 ADC却没先想清楚一个更基础的问题——你要测的温度物理上分布在哪些位置每处的温度变化有多快精度要求到底是多少。1.1 暖通侧的六个核心测点一套典型 HVAC 系统温度测点绝对不会只有一个。拿常见的风冷模块机来说至少能拉出这么几个位置测点位置典型温度范围反映什么测量需求冷媒管路气液分离器-10~15℃蒸发压力对应的饱和温度趋势敏感精度 ±0.5℃ 够用冷凝器风侧出风30~55℃散热效果、高压保护趋势反应慢普通 NTC 即可送风总管10~25℃供冷能力用户直接感受尽量准确回风温度20~30℃机房/房间负载长期稳定最重要冷水进出水管7~15℃换热效率温差计算两个点必须同一基准室外环境温度-20~50℃工况判断、除湿逻辑要防太阳直射和风扰这些点的共同特点是探头离主控板可能隔着好几米甚至几十米线缆而且分布在强电、压缩机和风机旁边干扰大。你不可能把每个探头都做成高成本数字传感器也不可能让 MCU 自己一根根去采电阻信号否则光是 ADC 通道和滤波算法就够你忙的。1.2 嵌入式侧到底测的是什么温度嵌入式应用里的本地温度通常不是环境空气温度而是主控板自身的结温。STM32L4S5ZI 这类 MCU 内部集成了一颗温度传感器它感受的是硅片附近的温度跟板卡散热条件、负载电流、外壳温度都有关系。我用它的用途主要有两个。一个是做板级健康监测。如果 MCU 结温持续超过 85℃说明板卡散热出了问题——可能是风扇停转、环境异常高温、或者某个功率器件把热量导过来了。这时候不让系统立刻停机至少要在 HMI 上报警。另一个是作为算法补偿的基准。HVAC 控制器里很多判断需要温度一致性比如判断室外机是制冷还是制热、防冻结保护等。这些逻辑不要求绝对温度多准更看重两个传感器读数之间的相对关系因此本地传感器的稳定性和漂移特性反而更关键。1.3 两条测温路径的边界划分既然之前已经梳理出测点设计就自然分成了两条路本地温度STM32L4S5ZI 内部温度传感器直接采样走 ADC1 的通道 17一条点对点的内部链路。远程温度PJ85718DM 承担多点前端采集挂在 I2C 总线上主控只通过总线定时读取结果。这样划分有一个明显好处把脏活——模拟信号调理、探头断线检测、多点切换——全部丢给前端芯片主控不参与电阻测量过程既省了 ADC 输入引脚也减少了采样过程中被打断引入的错误。2. 为什么把测温的脏活交给 PJ85718DM主控只留 STM32L4S5ZI选型这件事我把约束条件分成三层电气性能、开发成本和长期可靠性。2.1 STM32L4S5ZI 在这里扮演的角色STM32L4S5ZI 最吸引我的不是主频 120MHz 的 Cortex-M4 内核而是它的功耗特性和外设种类。HVAC 控制器往往需要 7×24 小时运行大面积停机和待机时功耗直接关系到运营成本。L4 系列有完整的低功耗模式STOP2 模式下可以保持 RAM 内容和后备域 RTC电流能做到很低对电池供电的无线温控器、冷链记录仪这类设备非常关键。再说外设。内置 14 位 ADC 支持内部温度传感器多路 I2C、LPUART、SPI 足够覆盖和 PJ85718DM 通信之余还能再接显示屏、RS485 网关、Wi-Fi 模组。这意味着整套系统不需要额外加第二颗单片机去做上位通信代码上也好组织。有一段时间我尝试过用普通 8 位 MCU 配合 GPIO 模拟时序来驱动测温前端省是省但现场出现总线异常时排查成本太高系统越复杂越明显。2.2 PJ85718DM 把远程测温的硬骨头啃掉了PJ85718DM 在我这版设计里承担的就是多点模拟前端这个角色。它支持多个两线制或三线制阻性探头输入可以挂 NTC 热敏电阻也能接 PT100/PT1000 铂电阻。内部集成调理电路和 ADC把传感器的电阻值转换成一串原始数据主控通过 I2C 去取。常用配置是四通道输入每通道可以独立设置转换使能和转换周期。它还有一个很有用的功能——断线检测。HVAC 现场的 NTC 探头最容易出现的故障就是线缆折断、端子氧化和插头松脱PJ85718DM 的驱动电路可以在测量电阻的同时识别出开路状态并把故障标志放在状态寄存器里主控不用靠读数是否异常去猜。从精度上看这类前端芯片能做到 16 位 ADC 的分辨率配合查表或者 Steinhart-Hart 方程在 -20~60℃ 范围内把误差收敛到 ±0.3℃ 是可以做到的。对暖通应用来说这已经比合格线高出一截。2.3 和一个点位一颗数字传感器对比之后的取舍有人会问为什么不每个探头都配一颗单总线数字温度传感器比如常见的 DS18B20 这类方案简单直接。我之前也这么干过但后来放弃了原因有三个。首先单总线方案在长线上时序要求不友好线稍微一长、分布电容一大上拉电阻选择就很难受容易出通信错误。其次一颗数字传感器只能测一个点八个点位就要八根总线或者一根单总线上挂多颗地址管理和掉线定位都会增加软件复杂度。第三很多现场已有的探头就是两线制 NTC你要全换数字传感器物料的采购和改造成本都得算进去。PJ85718DM 这种方案的好处是现场可以继续用便宜耐用的 NTC 探头只在前端集中做数字化主控看到的是一个稳定的 I2C 从设备。设备老化后换探头容易不改主控软件逻辑。3. 硬件连接与总线参数照着焊就能用的接线方案软件写得再好硬件底子不行也白搭。这里把关键接线和参数列出来是针对我这边实际跑通的一版其他板子可以对照调整。3.1 接线图和引脚清单主干结构是这样的STM32L4S5ZI 的 I2C1SCL 在 PB6SDA 在 PB7电平 3.3V。PJ85718DM 的 VDD 接 3.3VGND 共地。SCL/SDA 各自对 3.3V 接 4.7kΩ 上拉电阻。INT 脚接 STM32L4S5ZI 的一个 GPIO比如 PB4配置为下降沿中断用于前端芯片上报转换完成或故障。PJ85718DM 的 4 路探头端子分别接 NTC/PT1000 探头。注意一个容易忽视的地方STM32L4S5ZI 工作在 3.3V而现场探头线可能经过湿度很大的区域接口端最好加 PTC 自恢复电阻和 TVS 管。PTC 串在每路探头供电端TVS 管并在线缆入口防止雷击、感应静电损坏前端。我这里第一版就是省了这两颗元件结果梅雨季节坏了好几个前端。3.2 I2C 总线段上拉电阻、速率与地址I2C 总线速率我实际上跑的是 400kHz但初始化时先降到 100kHz 做握手等确认通信稳定再切高速。上拉电阻不要一味追求小阻值。4.7kΩ 在几十厘米的板内走线没问题但如果 PJ85718DM 被引到单独的小板上、通过排线连接线缆电容变大4.7kΩ 会导致上升沿变慢。这时候改成 2.2kΩ或者把速率降到 200kHz 更可靠。PJ85718DM 的从机地址我这边通过 ADDR 引脚设置为 0x667 位地址写地址就是 0xCC读地址就是 0xCD。如果板上挂了两颗前端可以分配 0x66 和 0x68 两个地址。3.3 探头输入前端保护电路每路探头端子建议这样处理从端子进来的线先串联一个 1kΩ 限流电阻再接前端芯片输入。输入到地之间并联一个 100nF 电容滤除高频干扰。芯片供电端 VDD 对地加 10μF 100nF 双电容去耦。NTC 探头本身电阻值比较大流过电流要控制得很小不然自热会带来明显测量误差。PJ85718DM 内部激励电流设置在 100μA 左右比较合适10kΩ NTC 上产生的压降是 1V 左右既在 ADC 量程内自热耗散也只有 0.1mW可以忽略。4. 软件实现一条总线和两个温度域软件部分我拆成两条路来讲。它们共用同一条 I2C 总线但读本地温度和读远程温度的时序、校准方式完全不同。4.1 本地温度读取内部传感器、出厂校准和软件滤波STM32L4S5ZI 内部温度传感器是连接到 ADC1 的通道 17。调用 HAL 库可以很方便地拿到原始 ADC 值再换算电压。核心公式是这样的T(°C) (V_SENSE - V_25) / Avg_Slope 25其中 V_SENSE 是当前采样到的电压V_25 和 Avg_Slope 是两个器件的特征参数。手册会给出典型值但更好的做法是读出厂校准参数。STM32L4S5ZI 在生产时会在两个温度点写入校准值对应高低两个温度从系统存储区读取后做线性拟合比直接用典型值准不少。我常用的一段初始化代码大致是这样void bsp_internal_temp_init(void) { adc_handle.Instance ADC1; adc_handle.Init.ClockPrescaler ADC_CLOCK_SYNC_PCLK_DIV4; adc_handle.Init.Resolution ADC_RESOLUTION_12B; adc_handle.Init.ContinuousConvMode DISABLE; adc_handle.Init.DiscontinuousConvMode DISABLE; adc_handle.Init.EOCSelection ADC_EOC_SINGLE_CONV; HAL_ADC_Init(adc_handle); } float bsp_read_local_temp_c(void) { uint16_t raw; float vsense; float temp; HAL_ADC_Start(adc_handle); if (HAL_ADC_PollForConversion(adc_handle, 100) HAL_OK) { raw HAL_ADC_GetValue(adc_handle); } HAL_ADC_Stop(adc_handle); vsense (float)raw * 3.3f / 4095.0f; temp (vsense - ts_cal1_v) / (ts_cal2_v - ts_cal1_v) * (ts_cal2_c - tis_cal1_c) ts_cal1_c; return temp; }校准参数在初始化时从 flash 系统区读一次存到全局变量。这样不同批次芯片的个体差异可以被抹平。注意本地温度采样不需要很频繁1 秒钟采一次、取最近五次中间值就足够但每次采完要丢一次结果因为 ADC 刚启动时的第一笔转换往往不稳。4.2 远程温度读取PJ85718DM 寄存器操作流程PJ85718DM 的寄存器组织比较直观我这版固件里封装成下面这样寄存器地址名称说明0x00DEV_ID芯片型号和版本0x01CTRL1全局使能、转换周期配置0x02CTRL2每通道使能、激励电流挡位0x03INT_CFG中断使能、断线中断选择0x04STATUS各通道断线标志、转换完成标志0x10~0x13CH1~CH4_DATA各通道原始 ADC 转换值0x20~0x23CH1~CH4_RES各通道电阻计算值读取流程并不复杂我先发一个软复位命令然后配置 CTRL1 和 CTRL2。转换周期我设置成 250ms——暖通温度场本来就慢没必要 10ms 刷一次低频转换还能降低电磁干扰影响。启动后我在主循环里定时查询 STATUS 寄存器的转换完成位。读到完成标志后一次性把四个通道的 0x10~0x13 数据读出来再对每个通道根据探头类型换算温度。4.3 处理转换、滤波与通道失效标记NTC 探头换算温度我用的方法是查表加线性插值。编一个电阻-温度分度表采样电阻落在哪两个表项之间就按比例插值速度快也没有指数运算的精度风险。这里要特别注意通道失效的情况。STATUS 里的断线标志拉起来后这条通道的温度数据就不能再进控制逻辑了。我把它变成三个阶段处理第一次读到断线标志不立刻报警继续读下一次排除接触不良的瞬时抖动。连续三次确认断线才把该通道标记为 Fault。Fault 通道不再参与 PID 或保护逻辑同时往状态帧里打一条故障码。这个处理方式是被一次现场误报警教训出来的。有颗探头端子紧固螺丝没拧紧车辆经过震动导致读数瞬断如果没有重复确认直接报警维护人员白跑一趟。5. 低功耗调度与现场实测从实验室到暖通机房的落差这一节想讲两个关键点长期运行的系统如何省电以及实测中数据看起来不对的原因。5.1 STOP2 模式与事件模式的调度STM32L4S5ZI 支持 STOP2 模式在停止工作时电流很低。PJ85718DM 也可以配置为低功耗转换模式转换完成后通过 INT 脚唤醒主控。调度上我采用一个简单的 1 秒基线。RTC 定时 1 秒唤醒 MCU读取本地温度和远程温度做完滤波和控制算法再回到 STOP2。远程温度的转换周期可以比 1 秒更长但为了保持状态机简洁我统一在整秒时刻触发读取只要 PJ85718DM 的转换已经完成就能拿到新数据。低功耗模式有一个坑I2C 外设进入 STOP2 后需要重新初始化。我在恢复流程里重新调用 HAL_I2C_Init 和 PJ85718DM 的初始化函数而不是傻乎乎地沿用之前的句柄状态。另外刚唤醒的瞬间供电可能还不稳我加了一个 2ms 延时再操作 I2C实测下来通信错误率明显下降。5.2 一组来自现场的实测数据读一组之前的实际记录时间本地温度冷水进水冷水出水送风回风室外09:0039.2℃9.8℃11.3℃13.6℃24.1℃31.0℃10:0039.8℃9.6℃11.0℃13.2℃24.5℃31.8℃11:0041.1℃9.5℃10.8℃13.0℃24.8℃32.5℃可以看到本地温度随负载升高在缓慢爬升而水温和风温相对稳定。从长期趋势判断这套数据是符合物理预期的。但如果只看某一刻的瞬时值你会发现送风温度和回风温度的总在上下跳 0.3~0.5℃这是正常的因为气流本来就存在湍流和分层。真正的异常是另一种形态某个通道读数不跳了稳定在一个完全不变的数值。这通常不是传感器坏了而是前端芯片在某一轮转换中自检到异常却还在输出旧值。所以我在状态检测逻辑里加了超时看门狗——如果连续读取到完全相同的温度值超过十分钟就强制复位前端并重新初始化。5.3 坑一探头线缆引入的噪声第一个坑是线缆。NTC 探头用两芯线如果现场布线跟压缩机电源线走同一个桥架干扰会很大。最初的板子在实验室里很干净一上机组温度读数就开始有 ±2℃ 的毛刺。我的解决方法是把探头线缆换成屏蔽双绞线屏蔽层单端接地。每路探头输入端并联一个 10nF 电容把高频毛刺砍掉。软件上把每次读取得多点平均从 4 个采样取平均提高到 16 个采样取平均。改完之后毛刺基本消失。这条经验后来复制到所有项目里不再依赖实验室环境的干净。5.4 坑二NTC 查表和精度边界第二个坑是精度边界。NTC 探头的 B 值批次差异时有时能到 1%在 -20℃ 以下误差会放大。如果项目要求低温段也要准最好选 1% 精度 B 值或直接上 PT1000。另外NTC 探头线缆本身也有电阻。几十米线缆有几欧姆的电阻对于 10kΩ NTC 来说影响不大但对于 PT100/PT1000 这类低阻测温元件线阻会直接叠加进去。如果必须用长线前端芯片选三线制或四线制接法并在接线端子处做线阻补偿。PJ85718DM 支持三线制输入我后面这个项目就全改成三线制数据明显比两线制更稳。5.5 坑三本地温度传感器的认知误区第三个坑是对 MCU 内部温度传感器的认知错位。很多人以为 STM32L4S5ZI 上读出的本地温度就等于环境温度其实它反映的是芯片结温附近的热状态会受板卡功耗、外围器件发热直接影响。有一次我把板卡放在空调出风口正下方开机一段时间后 MCU 内部温度读数比旁边外置环境传感器高了 6℃原因不是传感器坏了而是板上的稳压器和功率器件把热量都集中在芯片周边了。从此我定了一条规则本地温度只用来做板级保护和热补偿环境温度一律以远程探头为准。6. 最后分享两个能长期用的细节先说探头的安装工艺。不管软件做得多好传感器位置不对数据就是没有参考意义。暖通现场装探头要让测温头充分接触被测介质比如水管测温要插到套管里并填导热硅脂风管测温要把探头伸到气流中间而不是贴管壁。我见过很多温度异常的工单最后查下来都是探头绑在管道外表面测的是保温层温度。再说一下移植性。这套软件里把本地温度和远程温度都封装成独立的驱动模块对外统一提供float temp_get(ChannelId ch)接口。以后再换 MCU 或者换测温前端只需要替换底层实现上层的报警、显示、控制逻辑完全不用动。这也是当初坚持划分两条测温路径带给我的最大回报。如果你正在做一个同时要求板级自检和多点环境温度采集的嵌入式项目PJ85718DM 加 STM32L4S5ZI 这套组合值得试一下主控专注低功耗和业务逻辑前端专心做模拟测量边界清晰出问题也好定位。