做嵌入式温控类项目这些年,我最大的感受是:温度本身不值钱,值钱的是“怎么把温度采准、传稳、用明白”。最近我在整理一套 HVAC 控制板方案,主控用了 R7FA2A2AD3CFP,配合 PJ85718DM 做外围接口和采集扩展,目标是同时兼顾本地温度和远程温度监测。折腾了一圈下来,踩了不少坑,也总结了一些可以复用的思路,这篇就把整个设计过程和调试记录完整写出来。
这套方案适用的场景很明确:暖通空调的内外机控制、冷库/冷链监控、机房温控、或者需要多个测温点分散布置的嵌入式项目。如果你正在做类似的东西,并且在纠结“本地温度传感器怎么接、远程节点怎么通信、主控选型怎么定”,这篇文章应该能帮你省下不少走弯路的时间。
1. 项目整体设计与方案评估
1.1 项目背景:HVAC 温控为什么离不开多点温度
先说清楚一个容易被新手忽略的事实:HVAC 系统里的“温度”从来不是一个点。拿一套典型的风机盘管或小型冷库系统来看,你至少要关心送风温度、回风温度、盘管或蒸发器表面温度、室外环境温度,有些项目还需要管到远端房间、冷库纵深或风管末端的温度。每个位置的含义不同,控制逻辑也不同。
比如风盘系统里,回风温度通常作为室温反馈,送风温度用来判断制冷/制热效果,盘管温度用于防冻保护和除霜判断。如果只靠一颗传感器,你会发现冬天除霜动作要么晚要么早,因为看到的是混合后的温度而不是真实盘管温度。所以项目刚定下来的时候,我的第一版设计就明确列出了四个本地采集点和六个远程采集点,全部汇总到主控统一处理。
标题里提到的“本地与远程”,在物理上是一条很清晰的分界线:本地温度指主控板附近、走线在 1 米以内的温度点,直接进主控的模拟前端;远程温度指超过 3 到 5 米、需要单独走线或走总线协议的分布式节点。分界线划清楚之后,后面所有硬件和软件决策都围绕这条线展开,不会出现“到底算本地还是远程”的糊涂账。
1.2 器件选择背后的几个现实理由
器件选型我通常不追求最新最炫,而是看三个指标:够不够稳、好不好买、资料够不够全。R7FA2A2AD3CFP 是 48 引脚的 MCU,Cortex-M23 内核,最高跑到 48MHz,片内 Flash 和 RAM 对温控这种中低复杂度应用已经非常充裕。它吸引我的地方首先是模拟外设比较扎实,做多路 NTC 采集不需要外挂独立 ADC,主板布线能省一圈;其次是封装和引脚间距对双层板很友好,BOM 上不需要太复杂的贴片设备,小批量手工焊接也扛得住。
PJ85718DM 在我这套方案里扮演的角色比较特殊:它是一颗接口扩展与状态汇聚芯片,负责把远程节点的数字温度信号、阀门反馈信号、风机状态信号统一收集,再通过约定接口交给主控。简单说,R7FA2A2AD3CFP 负责“思考”,PJ85718DM 负责“伸手”——一个管大脑,一个管手脚。
当时也考虑过用纯扩展 IO 芯片或者直接上 RS485 从站来做远程采集,但方案评审后放弃了:纯扩展 IO 只能采开闭信号,数字温度还得自己再搭协议;RS485 每个从站都要带 MCU,成本翻倍。PJ85718DM 的单芯片多通道方案在成本和连线复杂度上最平衡,而且它和主控之间是确定性的并行/串行接口,时序上比异步总线更容易把控。
1.3 本地温度与远程温度的边界划分
这条边界是整套系统的骨架,一定要在设计阶段就用文字固定下来,否则硬件布线、软件协议、通讯地址都会打架。我的划分规则如下:
- 本地温度:从主控板引出,线长不超过 0.5 米,直接经过模拟前端采集,不经过任何总线转换。典型点位:回风、送风、盘管、板载环境温度。
- 远程温度:分布在现场各处的数字探头或变送器,通过长线缆汇入 PJ85718DM 的采集通道,再批量上交主控。实测下来最远的节点有 40 米左右。
- 扩展温度:后续如果接冷库远程主机或第三方网关,通过标准通信口走 Modbus 协议接入。这一层不参与毫秒级控制,只负责数据汇聚和联动。
这个三层结构的好处是:紧急控制数据(本地)走的是最短路径,延迟极低;非紧急监测数据走汇聚路径,吞吐量要求也不高;外接数据则完全解耦,来了就算,不来也不影响主循环。后面实际调试也证明,这种“分级采集、统一汇聚”的架构比一把梭全挂总线上要稳定得多。
2. 硬件实现:从电源到信号采集的每一个细节
2.1 主控资源的合理分配
R7FA2A2AD3CFP 的资源分配是这次硬件设计里最值得抠的部分。48 个引脚看着不少,但真正可用 GPIO 也没想象中宽裕。我按功能块做了整体规划:
- 模拟通道:4 个本地 NTC 温度采集,占用 4 路 ADC 输入,每路前面加 RC 滤波;
- 与 PJ85718DM 的接口:1 个 SPI 片选、1 个时钟、1 个数据输入、1 个数据输出,外加 1 根中断线;
- 远程通信口:1 路 SCI 配置成 RS485,半双工模式,外挂收发器,用作远程节点轮询和扩展通信;
- 输出控制:风机高/中/低三档输出阀、电加热继电器、水泵接触器,总共 5 路,全部用光耦隔离;
- 剩余 GPIO 分配给拨码开关、运行指示灯、蜂鸣器、程序下载口。
这样分配完,引脚刚好用完,没有一个浪费,也没有一个不够。主控的工作负载也很清晰:4 路本地模拟采样直接由 ADC 中断或 DMA 完成;PJ85718DM 的数据通过 SPI 查询读取,100ms 周期轮询一次;远程 RS485 节点数量不大,500ms 轮询一轮,完全跑得动。
2.2 NTC 本地温度检测电路
本地温度我选了 10K NTC 热敏电阻方案。理由很直接:便宜、成熟、供应链里随便哪家都能买。关键参数是 B 值,我统一用 B3435。采样电路采用标准的分压结构:NTC 一端接电源正,另一端串联精密电阻后接地,中间节点进 ADC。电源用主控的 3.3V 基准而不是系统 24V/5V,避免电源波动直接串进采样值。
分压电阻的取值有讲究。10K NTC 在 25℃ 时阻值 10K,在 -20℃ 时阻值能到几十 K,在 50℃ 时下降到几 K。为了在常用温度段获得最大分辨率,分压电阻取 10K 比较合适,配合基准电压 3.3V,ADC 满量程 12 位时精度足够。我初期试过 4.7K 和 20K,前者低温段分辨率明显下降,后者高温段压点太低,读数毛刺也多,最后还是回到 10K。
每路 ADC 输入端加了一颗 100Ω 电阻和一颗 1nF 电容构成低通滤波,目的是滤掉脉冲干扰和电源高频噪声。实测下来这个组合对空调接触器吸合瞬间的干扰抑制效果最好。如果布局空间允许,把 NTC 的地线单独拉回主控地端,不要跟继电器地混在一起,这个细节对读数稳定性影响很大。
2.3 远程温度采集的接线布局
远程温度节点是在现场装的数字温度变送器和 NTC 探头,输出统一接成电流环或数字信号的形式,汇入 PJ85718DM 的输入端口。这里有个设计原则:凡是超过两米的模拟信号,一律不要在末端用裸 NTC + 长线直接进 ADC,否则干扰会让你怀疑人生。远程点全部转换成数字量或标准变送器信号再上传。
PJ85718DM 的输入端我按通道规划了防静电保护和上下拉电阻,所有远程线从端子进来,先过保护器件再进芯片。这样雷击或施工时的误接高压不至于直接烧到主板。远程节点采用总线供电或本地独立供电,优先选独立供电,避免一个节点故障把整条总线拉死。
接线端子的选型也值得多说一句。工业现场高温高湿环境多,我用的是带有弹簧压线的可插拔端子,比普通螺丝端子抗震且接触电阻稳定。远程线缆采用带屏蔽层的双绞线,屏蔽层单端接地接在主控端,实测能明显降低共模干扰。
3. 软件设计:温度数据怎么流动和处理
3.1 底层驱动:NTC 读数和数据平滑
软件第一关是把 ADC 原始码值换算成真实温度。NTC 换温度有两种常见做:查表和公式计算。查表省算力、速度快,但表要做得密才准,而且换一种 NTC 就要重新做表;公式计算灵活,但涉及浮点和 log,需要确认主控算力能不能扛。
我这次选择公式计算加软件滤波折中方案。公式就是经典 Steinhart-Hart 简化式,配合 B 值参数:
#define TEMP_NOMINAL 25.0f /* 标称温度 */ #define THERMISTOR_NOMINAL 10000.0f /* 标称阻值 */ #define BETA 3435.0f /* B值 */ #define SERIES_RES 10000.0f /* 分压电阻 */ float ntc_resistance(uint16_t adc_raw, uint16_t adc_max) { if (adc_raw >= adc_max) adc_raw = adc_max - 1; float ratio = (float)adc_raw / (float)adc_max; return SERIES_RES * ratio / (1.0f - ratio); } float temperature_from_ntc(float resistance) { float steinhart; steinhart = logf(resistance / THERMISTOR_NOMINAL); steinhart /= BETA; steinhart += 1.0f / (TEMP_NOMINAL + 273.15f); steinhart = 1.0f / steinhart - 273.15f; return steinhart; }这个函数在 48MHz 主频上跑一轮大约几十微秒,4 路全部算完也不影响主循环。真正需要费心的是采样滤波。我用了两段式:先对连续 8 次 ADC 原始值做冒泡排序取中间值,再对中间值做一阶低通滤波。排序滤波能去掉尖刺,低通平滑能消除抖动。这个组合调参非常简单,几乎没有踩坑风险。
3.2 主控与 PJ85718DM 之间的数据交互
PJ85718DM 与主控的交互我们定义为固定周期的查询模式。主控作为主机,每 100ms 发起一次数据交换:先发送一帧查询命令,PJ85718DM 再回传整包状态。
帧格式是自定义的,参考了工业现场常见的 8 字节短帧结构:
字节0 帧头 固定0xAA 字节1 命令字 0x01=读远程温度组 字节2~3 数据长度+通道序号 字节4~5 两路远程温度原始值 字节6 状态字节 门限跨越标识/通道健康位 字节7 校验字节 前面6字节异或校验用了异或而不是 CRC,说实话在这种短帧场景下够用,而且节省代码量。如果项目后续要经过强干扰环境或更长距离,建议换成 CRC16。数据交换的时序必须严格控制:主控发完命令后延时一小段时间等对方准备好,再拉高片选读取,不能边发边读,我在这里浪费了半天调试时间。
远程节点的门限跨检测也是由 PJ85718DM 完成的。每个通道配置了上限报警和下限报警阈值,温度越限时状态字对应位置 1。这样主控不用逐帧解析温度值就能第一时间知道“哪一路越限了”,只有在状态变化时才需要读详细温度,有效降低了主控的负载。
3.3 控制逻辑与远程上报策略
本地温度喂给控制环之后,我用了带死区的比例控制,而不是上来就上 PID。死区按模式区分:制冷模式 0.5℃,制热模式 0.8℃。实际体验下来,这个宽度既能保证温控稳定性,又不会让风机频繁变档。升温/降温速率再加入一个很小的积分项来消除稳态误差,但限幅严格,防止超调。
远程温度不参与快速控制,但参与报警和联动。例如冷库纵深温度如果连续 3 个周期都高于设定上限,主控会强制启动供液阀;机房远程回风温度如果异常升高,主控会切到应急模式。这个策略的好处是把远程数据当作防御性信息而不是进攻性信息,不会因为单个节点的瞬时波动就做出激进动作。
远程上报我打包成标准 Modbus RTU 从机响应。主控对外只有一个从站地址,对外暴露三组寄存器:本地温度组、远程温度组、系统状态组。上位机或网关只需要按地址读取即可,不用关心底层采集细节。这样做也让我后面接第三方云平台时省了很多事。
4. 实测中的坑与排查方法
4.1 温度跳变和接地环路
第一次整体联调,本地 NTC 读数在压缩机启动瞬间会跳 2℃ 左右,像心电图一样。排查后发现两个原因叠加:一是 NTC 采样地与继电器驱动共地,继电器线圈动作产生的地电位波动直接叠加到基准地;二是 ADC 采样启动时间太短,采样电容还没充满就读取,导致结果偏小。
解决办法分两步:先把所有感性负载的地单独走线,在主控电源输入端单点汇合,切断地环路;再将 ADC 采样时间配置拉到最长档位。改完再测,同一工况下温度波动从 2℃ 下降到 0.1℃ 以内。这个案例说明,模拟采集环节的“稳”首先是地稳,其次才是算法稳。
4.2 远程通信丢包和错位
远程轮询刚上线时出现的现象很诡异:通道 1 显示 25.3℃,但现场实际是 31.2℃,而且间歇性不稳定。数据对比发现,大部分时间通道内容正确,偶发错位,怀疑是数据同步出了问题。单独用逻辑分析仪抓总线信号,才发现远程变送器在上电瞬间会发出一段不确定电平,正好被主控当作一帧有效数据。
修复方式是在协议层加同步锁定:主控连续收到两帧带相同通道序号且校验正确的数据,才认为该通道数据有效;多收一帧的异常值直接丢弃。同时对变送器增加上电延时要求,确认电源稳定后再启动数据发送。处理后丢帧率降到千分之一以下,远端探头在 40 米线长下稳定工作。
4.3 常见问题排查速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 本地温度读数偏大且跳动 | 地环路干扰或采样时间过短 | 分开模拟地与功率地,增大 ADC 采样时间 |
| 温度长时间不变但数值异常 | NTC 线断或分压电阻虚焊 | 先用万用表测 NTC 分压点电压确认是否固定 |
| 远程某通道时有时无 | 线缆接触不良或屏蔽层未单端接地 | 检查端子压接,屏蔽层重做单端接地 |
| 远程所有通道数据滞后大 | 轮询周期太长或波特率太低 | 优化主控查询周期,均衡各通道刷新时间 |
| 校准后温度仍偏差超过 0.5℃ | ADC 基准电压不准或分压电阻精度不足 | 用高精度基准源重新校准,换 0.1% 电阻 |
| 控制动作频繁来回切换 | 死区设置过小或滤波强度不够 | 调大死区,加强温度平滑 |
这些坑其实都很常见,关键是养成“先硬件后软件、先干扰后逻辑”的排查顺序。我见过不少人一上来就翻软件找 bug,结果问题出在接线抖动上,浪费了大量时间。
5. 调试工具与现场经验
5.1 硬件调试工具
做这种多点温度的嵌入式项目,工具清单一定要备全。自认为最有用的是 USB 逻辑分析仪,调试 PJ85718DM 和远程节点通信全靠它,能直观看到时钟和数据线上的毛刺。其次是一个可调线性电源,模拟供电电压波动,用来测试远程节点在欠压状态下的表现。万用表只能做静态检查,动态抓波形还是得靠逻辑分析仪。
5.2 软件调试技巧
固件里我预留了一个临时调试串口,通过在代码里设置断点和打印标记,可以在不打断控制流程的情况下监视关键变量。尤其是远程状态字,每次轮询后立刻打印出来,能快速定位是通信问题还是数据内容问题。这个做法在联调阶段救了多次场,调试完成后把打印开关直接编译关闭即可。
5.3 行之有效的调参顺序
我这几套板子调温控参数的固定顺序是:先不滤波,看 ADC 原始值的稳定水平;再逐步加滤波,观察温度曲线的平滑度;然后从大死区往小死区调,找到不来回切换的边界;最后再加入积分项,一次调增量。这套顺序基本不会把系统调发散,比一边调一边猜来得高效得多。
最后再分享一个小习惯:所有温度通道做校准点时,我不建议只校准 25℃ 一点,有条件的话至少校准 0℃、25℃、50℃ 三个点,画出误差曲线。很多时候传感器误差不是固定偏移而是随温度变化的,单点校准只能保证那个点准,别的位置可能更差。我这次就是在 0℃ 冰水浴和 50℃ 恒温箱里各泡了半小时,把每个通道的校准系数拟合出来之后,整机实测误差控制在 ±0.3℃ 以内,这套方案才算真正收官。