基于STM32的智能空调设计

基于STM32的智能空调设计

一、系统概述与核心功能

1. 系统定位

基于STM32的智能空调以“环境感知-智能决策-精准控制-人机交互”为核心,实现温度/湿度/空气质量监测、自动模式切换、远程控制、节能运行,替代传统机械空调,适用于家庭、办公室、小型商铺等场景,兼顾舒适性与能效比。

2. 核心功能模块

模块 功能描述
环境感知 多传感器融合:温度(DS18B20/DS3231)、湿度(SHT30)、空气质量(SGP30)、红外人体检测(PIR)
智能决策 模式自动切换(制冷/制热/除湿/通风)、温度自适应调节、人走自动待机、故障时自动切安全模式
执行控制 压缩机/风机/导风板驱动:继电器+变频器控制压缩机,步进电机控制导风板角度
人机交互 本地:触摸按键+OLED显示;远程:蓝牙/Wi-Fi控制、手机APP/语音控制(可选)
低功耗设计 待机电流<10mA,人走自动待机,无操作时进入STOP模式,续航≥1个月(锂电池)
安全防护 过温保护、压缩机延时启动、缺氟检测、童锁功能

二、硬件设计方案

1. 核心硬件选型

模块 型号 关键参数 接口方式
主控MCU STM32F407ZGT6 168MHz Cortex-M4,1MB Flash,192KB RAM,多路ADC/PWM,支持DSP指令集 核心控制器
环境传感器 SHT30+SGP30+PIR SHT30:±0.3℃/±2%RH;SGP30:TVOC/CO₂检测;PIR:检测范围5-10m I2C(PB6/PB7)+ GPIO
执行模块 继电器阵列+步进电机 2路继电器(压缩机/风机)+ 2路PWM(变频器)+ 28BYJ-48步进电机(导风板) GPIO+PWM(TIM3/TIM4)
红外通信 HS0038B+NEC协议 38kHz载波,支持空调遥控器红外指令学习与解码 TIM2输入捕获+TIM3 PWM输出
显示模块 OLED 12864(I2C) 0.96寸,128×64像素,自发光,低功耗(<10mA),显示温度/模式/空气质量 I2C1(复用传感器总线)
通信模块 ESP8266(Wi-Fi) 802.11 b/g/n,UART接口,支持MQTT协议,远程控制/数据上传 UART3(PB10/PB11)
电源模块 12V开关电源+降压模块 输入220V AC,输出12V/5A(压缩机)、5V/2A(控制电路)、3.3V/1A(STM32) 三级稳压供电体系

2. 硬件电路设计要点

2.1 核心电路连接

2.2 抗干扰与安全设计

三、软件设计与核心代码

1. 系统架构(FreeRTOS多任务调度)

采用FreeRTOS实时操作系统,划分6个核心任务(优先级从高到低):

  1. 传感器采集任务(优先级5):周期性读取温度/湿度/空气质量/人体检测数据,滤波后发送至消息队列。
  2. 智能决策任务(优先级4):解析传感器数据,判断当前模式,生成执行指令(压缩机/风机/导风板控制)。
  3. 执行控制任务(优先级3):解析决策指令,通过PWM/继电器/步进电机执行具体操作。
  4. 红外通信任务(优先级2):解码红外遥控器指令,学习新指令,发送红外控制命令。
  5. 人机交互任务(优先级2):更新OLED显示,处理触摸按键/远程指令。
  6. 低功耗管理任务(优先级1):检测无操作/无人状态,进入待机模式。

2. 核心代码实现(基于HAL库)

2.1 传感器采集与滤波

#include "sht30.h"
#include "sgp30.h"
#include "pir.h"

// 传感器数据结构体
typedef struct {
    float temp;       // 温度(℃)
    float humi;       // 湿度(%RH)
    uint16_t tvoc;    // TVOC浓度(ppb)
    uint16_t co2;     // CO₂浓度(ppm)
    uint8_t human;     // 人体检测结果(0=无人,1=有人)
} SensorData_t;

SensorData_t sensor_data;
QueueHandle_t sensor_queue;  // 传感器数据队列

// 传感器采集任务
void Sensor_Task(void *pvParameters) {
    TickType_t xLastWakeTime = xTaskGetTickCount();
    const TickType_t xFrequency = pdMS_TO_TICKS(1000);  // 1秒采集一次
    
    while (1) {
        // 1. 读取SHT30温湿度
        SHT30_Read(&sensor_data.temp, &sensor_data.humi);
        
        // 2. 读取SGP30空气质量
        SGP30_Read(&sensor_data.tvox, &sensor_data.co2);
        
        // 3. 读取PIR人体检测
        sensor_data.human = PIR_Detect();
        
        // 4. 滑动平均滤波(窗口大小5)
        static float temp_buf[5] = {0};
        static float humi_buf[5] = {0};
        static uint8_t filter_idx = 0;
        
        temp_buf[filter_idx] = sensor_data.temp;
        humi_buf[filter_idx] = sensor_data.humi;
        filter_idx = (filter_idx + 1) % 5;
        
        float temp_sum = 0, humi_sum = 0;
        for (uint8_t i=0; i<5; i++) {
            temp_sum += temp_buf[i];
            humi_sum += humi_buf[i];
        }
        sensor_data.temp = temp_sum / 5.0f;
        sensor_data.humi = humi_sum / 5.0f;
        
        // 5. 发送数据至决策任务
        xQueueSend(sensor_queue, &sensor_data, 0);
        
        vTaskDelayUntil(&xLastWakeTime, xFrequency);
    }
}

2.2 智能决策算法

// 空调模式定义
typedef enum {
    MODE_OFF = 0,       // 关机
    MODE_COOL = 1,       // 制冷
    MODE_HEAT = 2,       // 制热
    MODE_DEHUMID = 3,    // 除湿
    MODE_VENT = 4,        // 通风
    MODE_AUTO = 5         // 自动模式
} AC_Mode;

// 系统状态结构体
typedef struct {
    AC_Mode mode;        // 当前模式
    float target_temp;     // 目标温度
    uint8_t fan_speed;     // 风速(0=低,1=中,2=高)
    uint8_t swing;        // 导风板摆动(0=关,1=开)
    uint8_t power;        // 电源状态(0=关,1=开)
} AC_State_t;

AC_State_t ac_state = {MODE_AUTO, 26.0f, 1, 1, 1};
QueueHandle_t decision_queue;  // 决策指令队列

// 智能决策任务
void Decision_Task(void *pvParameters) {
    SensorData_t sensor_data;
    
    while (1) {
        if (xQueueReceive(sensor_queue, &sensor_data, portMAX_DELAY) == pdPASS) {
            // 1. 无人自动待机
            if (!sensor_data.human && ac_state.power) {
                ac_state.power = 0;
                ac_state.mode = MODE_OFF;
                xQueueSend(decision_queue, &ac_state, 0);
                continue;
            }
            
            // 2. 自动模式决策
            if (ac_state.mode == MODE_AUTO) {
                if (sensor_data.temp > ac_state.target_temp + 2.0f) {
                    ac_state.mode = MODE_COOL;  // 高于目标温度2℃→制冷
                } else if (sensor_data.temp < ac_state.target_temp - 2.0f) {
                    ac_state.mode = MODE_HEAT;  // 低于目标温度2℃→制热
                } else if (sensor_data.humi > 65.0f) {
                    ac_state.mode = MODE_DEHUMID;  // 湿度高于65%→除湿
                } else {
                    ac_state.mode = MODE_VENT;  // 其他情况→通风
                }
            }
            
            // 3. 温度自适应调节(PID控制)
            float temp_diff = sensor_data.temp - ac_state.target_temp;
            static float integral = 0, last_diff = 0;
            integral += temp_diff;
            float derivative = temp_diff - last_diff;
            float pid_output = 2.0f*temp_diff + 0.5f*integral + 1.0f*derivative;
            last_diff = temp_diff;
            
            // 根据PID输出调整压缩机功率(PWM占空比)
            uint8_t compressor_pwm = (uint8_t)fmin(fmax(pid_output, 0), 100);
            
            // 4. 发送决策指令至执行任务
            ac_state.compressor_pwm = compressor_pwm;
            xQueueSend(decision_queue, &ac_state, 0);
        }
    }
}

2.3 执行控制模块

// 执行控制任务
void Execute_Task(void *pvParameters) {
    AC_State_t ac_state;
    uint8_t last_compressor_pwm = 0;
    uint32_t compressor_start_time = 0;
    
    while (1) {
        if (xQueueReceive(decision_queue, &ac_state, portMAX_DELAY) == pdPASS) {
            // 1. 电源控制
            if (ac_state.power) {
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  // 电源指示灯亮
            } else {
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 电源指示灯灭
                // 关闭所有执行部件
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); // 压缩机关
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // 风机关
                continue;
            }
            
            // 2. 压缩机控制(带延时启动保护)
            if (ac_state.mode == MODE_COOL || ac_state.mode == MODE_HEAT) {
                if (last_compressor_pwm == 0 && ac_state.compressor_pwm > 0) {
                    // 压缩机刚启动,延时3分钟
                    if (HAL_GetTick() - compressor_start_time < 180000) {
                        // 延时未到,保持关闭
                        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
                    } else {
                        // 延时到,启动压缩机
                        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, ac_state.compressor_pwm * 10);
                        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
                    }
                } else {
                    // 正常运行
                    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, ac_state.compressor_pwm * 10);
                    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
                    compressor_start_time = HAL_GetTick();
                }
            } else {
                // 非制冷/制热模式,关闭压缩机
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
                last_compressor_pwm = ac_state.compressor_pwm;
            }
            
            // 3. 风机控制
            uint16_t fan_pwm = 0;
            switch (ac_state.fan_speed) {
                case 0: fan_pwm = 30; break;  // 低风
                case 1: fan_pwm = 60; break;  // 中风
                case 2: fan_pwm = 100; break; // 高风
            }
            __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, fan_pwm * 10);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
            
            // 4. 导风板控制(步进电机)
            if (ac_state.swing) {
                StepMotor_Swing();  // 摆动模式
            } else {
                StepMotor_Stop();   // 停止模式
            }
            
            // 5. 更新OLED显示
            OLED_Update(ac_state, sensor_data);
        }
    }
}

2.4 红外控制与学习

// 红外学习功能
void IR_Learn(uint8_t key_id) {
    uint32_t learned_code = 0;
    
    // 等待红外信号
    while (!ir_received) {
        HAL_Delay(10);
    }
    
    // 保存学习到的红外码
    learned_code = ir_code;
    AT24C256_Write(key_id * 4, (uint8_t*)&learned_code, 4);
    
    // 清除接收标志
    ir_received = 0;
}

// 红外发送功能
void IR_Send(uint8_t key_id) {
    uint32_t code = 0;
    
    // 读取保存的红外码
    AT24C256_Read(key_id * 4, (uint8_t*)&code, 4);
    
    // 发送红外码
    NEC_SendCode(code);
}

2.5 主程序框架

#include "stm32f4xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
#include "sensor.h"
#include "decision.h"
#include "execute.h"
#include "ir.h"
#include "oled.h"

int main(void) {
    HAL_Init();
    SystemClock_Config();  // 168MHz
    
    // 初始化外设
    MX_I2C1_Init();        // I2C1(传感器)
    MX_TIM2_Init();        // TIM2(红外输入捕获)
    MX_TIM3_Init();        // TIM3(压缩机PWM)
    MX_TIM4_Init();        // TIM4(风机PWM)
    MX_GPIO_Init();         // GPIO(继电器/步进电机/指示灯)
    MX_USART3_Init();      // USART3(Wi-Fi模块)
    
    // 初始化模块
    SHT30_Init();          // 温湿度传感器
    SGP30_Init();          // 空气质量传感器
    PIR_Init();            // 人体检测传感器
    OLED_Init();           // OLED显示
    IR_Init();             // 红外模块
    ESP8266_Init();        // Wi-Fi模块
    
    // 创建FreeRTOS队列
    sensor_queue = xQueueCreate(10, sizeof(SensorData_t));
    decision_queue = xQueueCreate(10, sizeof(AC_State_t));
    
    // 创建FreeRTOS任务
    xTaskCreate(Sensor_Task, "Sensor", 256, NULL, 5, NULL);
    xTaskCreate(Decision_Task, "Decision", 256, NULL, 4, NULL);
    xTaskCreate(Execute_Task, "Execute", 256, NULL, 3, NULL);
    xTaskCreate(IR_Task, "IR", 256, NULL, 2, NULL);
    xTaskCreate(UI_Task, "UI", 256, NULL, 2, NULL);
    xTaskCreate(LowPower_Task, "LowPower", 128, NULL, 1, NULL);
    
    // 启动调度器
    vTaskStartScheduler();
    
    while (1);
}

参考代码 基于STM32的智能空调设计 www.youwenfan.com/contentcst/133642.html

四、关键技术与优化

1. 节能优化技术

2. 可靠性设计

3. 用户体验优化

五、系统调试与扩展

1. 调试步骤

阶段 操作 工具
硬件调试 测量各模块供电电压,检查传感器通信是否正常 万用表、示波器
传感器测试 用标准仪器对比温湿度/空气质量数据 标准温湿度计、空气质量检测仪
执行测试 测试继电器/步进电机/变频器是否正常工作 逻辑分析仪、示波器
功能测试 测试各模式切换、温度调节、定时功能是否正常 实际操作测试

2. 扩展功能

六、总结

基于STM32的智能空调通过多传感器融合实现环境精准感知,智能决策算法实现自动模式切换,FreeRTOS多任务确保系统稳定运行,红外学习+Wi-Fi控制提升用户体验。

专注于matlab/simulink,电子电路,编程