1用结构体,把空调模块的“散沙数据”聚成“砖块” 新手写空调风机控制,会定义一堆孤立的全局变量:风机方向、转速、故障标志、运行时间,每个变量单独存在,改一个牵一发而动全身。 大神的做法,是把同一个空调模块的所有数据,打包进一个结构体,也就是我们常说的“句柄”。比如空调风机模块,先定义风机的状态(停止、正转、反转、故障),再把风机的编号、当前转速、目标转速、故障码,全部装进结构体里。 然后对外只暴露接口,比如初始化风机、设置目标转速、获取风机状态,内部实现全部隐藏。这样一来,所有和风机相关的数据,都在一个“箱子”里,不会乱飘。 2用数据池,解决空调模块间的“沟通难题” 串口模块本来只负责收发数据,现在却要知道“有压缩机、有LCD”,这就是强耦合——哪天不用LCD了,删掉LCD的代码,串口模块就报错,编译都通不过。 大神的解法:搞一个统一的“数据池”,相当于空调系统的“公共消息板”。串口模块解析完调温指令,只把指令写到数据池里,就完事了;压缩机模块在自己的任务里,去数据池看有没有调温指令,有就执行;LCD模块在刷新任务里,去数据池拿当前温度,刷到屏幕上。 3三个模块互相不认识,只和数据池打交道,哪怕删掉LCD模块,串口和压缩机照样正常工作,彻底解耦,后期维护、加功能,都不用动原有模块代码。 分三层,记好这一点,新手也能避开坑: 第一层,硬件抽象层(驱动层):只负责和寄存器打交道,比如配置GPIO、控制串口收发,绝对不写任何业务逻辑,比如“调温到26度”这种代码,绝不能出现在这里。 第二层,中间件层:负责空调具体模块控制,比如风机的PID调速、按键消抖、温度传感器采集,调用底层驱动接口,但不关心整体业务流程。 第三层,应用层(业务逻辑层):把中间件组合起来,实现空调的具体功能,比如“按下调温键→串口接收指令→控制压缩机→LCD显示温度”,这里绝对不能出现直接操作寄存器的代码。 举个反面例子:如果在应用层直接写“操作GPIO寄存器点亮LED”,哪天把空调MCU从STM32换成GD32,所有应用层代码都要推倒重写;而规范的写法,是调用“LED点亮接口”,底层驱动改了,应用层一行不用动,可移植性直接拉满。
00:00 / 06:53
连播
清屏
智能
倍速
点赞8
00:00 / 23:02
连播
清屏
智能
倍速
点赞2
空调里有风机、压缩机这些强电设备,一工作就会产生电磁干扰,再加上温湿度传感器本身的信号噪声,导致ADC采样值不是稳定的数值,而是在设定阈值附近来回波动。 很多新手会用“单阈值判断”——比如设定26℃触发制冷,采样值超过26℃就开机,低于就关机。这种方式没有抗抖动能力,一点干扰就会让采样值跳变,压缩机、风机频繁启停,既费电,又伤设备,这是我刚做空调项目时,最常犯的错误。 解决这个问题的核心技术,就是「滞回处理」,简单说就是“双阈值+状态锁存”,比单阈值靠谱10倍。 举个空调温湿度采集的例子,一看就懂: 我们不设一个阈值,而是设两个:上限阈值(触发阈值)26℃,下限阈值(复位阈值)25℃,两者的差值就是滞回电压,通常设为噪声的2-3倍,刚好能过滤干扰。 逻辑很简单:采样值从低往高升,必须超过26℃,才触发制冷;采样值从高往低降,必须低于25℃,才停止制冷。哪怕采样值在25-26℃之间来回跳,只要没低于25℃,就保持制冷状态,不会频繁切换——这就是状态锁存的作用,完美解决阈值跳动导致的误动作。 我当年就是用这个方法,解决了空调压缩机频繁启停的问题,之前调试了3天,加了滞回处理后,一次就稳定了。 但要注意,只靠基础滞回处理,还不够! 如果空调系统有强干扰,偶尔出现瞬时的干扰脉冲——比如采样值突然跳到27℃,又瞬间回落,这时候仅靠双阈值,还是会误触发。这时候就需要两种方法组合,适配大多数空调场景。 第一种,采样滤波(最常用):多次采样取平均值,或者用滑动窗口中值滤波,压制瞬时干扰,让采样值更接近真实温度、电压。比如温湿度采集,每100ms采5次,取中间3次的平均值,干扰直接被过滤。 第二种,触发延时判断:设定一个延时时间(通常10-100ms,空调场景建议30ms),只有采样值持续超过上限阈值30ms,才触发操作,瞬间的干扰脉冲就被过滤了,不会误启动压缩机。 这两种方法组合,既能过滤干扰,又不影响空调的正常响应速度,是我做空调ADC采样最常用的实操方案。 还有一种特殊情况:如果ADC采样的是脉冲信号,比如空调的故障检测脉冲、传感器脉冲输出,处理起来要注意,不能过度滤波,否则会漏掉有效脉冲。
00:00 / 05:54
连播
清屏
智能
倍速
点赞7
00:00 / 00:23
连播
清屏
智能
倍速
点赞0