基于 STM32 的智能家居系统,是以 STM32 系列微控制器为核心控制单元,整合传感器感知、设备联动、远程通信与智能决策的家居智能化解决方案。该系统依托 STM32 芯片高性能、低功耗、外设丰富的优势,实现家居环境监测、设备智能控制、场景自动化联动等核心功能,旨在提升生活便捷性、舒适性与能源利用效率。
核心设计理念
以 "感知 - 决策 - 控制" 为核心逻辑,通过各类传感器采集家居环境数据(如温湿度、光照、人体感应、燃气浓度等),由 STM32 主控制器进行数据处理与逻辑判断,再驱动执行设备(如灯光、空调、窗帘、门锁、家电等)完成相应操作;同时支持远程终端(手机 APP、小程序、语音助手)交互,让用户随时随地掌控家居状态,实现 "人 - 机 - 环境" 的智能协同。
系统核心组成
- 控制层(核心):采用 STM32 系列微控制器( STM32F103),作为系统 "大脑"。负责解析传感器数据、执行用户指令、运行场景联动算法,通过 UART、I2C、SPI、GPIO 等外设接口对接各类模块,保障系统稳定运行。
- 感知层:由各类传感器组成,包括环境传感器(温湿度传感器 、光照传感器 )、安全传感器(烟雾传感器 )等,实时采集家居环境与安全状态数据,为智能决策提供依据。
- 执行层:涵盖各类家居控制设备,如灯光(LED 灯、智能开关)、家电(继电器模块控制)、电动设备(窗帘电机)、报警设备(蜂鸣器)等,接收 STM32 控制器的指令,完成开关、调节、报警等操作。
- 通信层:支持多种通信方式,实现数据传输与远程交互。包括短距离通信(蓝牙 BLE、ZigBee)用于设备本地联动,远距离通信(WiFi 模块 ESP8266模块)实现手机 APP 远程控制,部分高端方案可集成语音模块,支持语音指令控制。
- 交互层:提供多维度用户交互渠道,包括手机 APP / 小程序(实时查看状态、发送控制指令)、本地控制面板(触摸按键、LCD 显示屏)、语音助手(对接小爱同学、天猫精灵等),满足不同场景下的操作需求。
主函数代码如下,可以修改一些改成自己需要代码
cs
#include "stm32f10x.h"
#include "oled.h"
#include "adcx.h"
#include "sensormodules.h"
#include "dht11.h"
#include "key.h"
#include "tim2.h"
#include "tim3.h"
#include "flash.h"
#include "motor.h"
#include "pwm.h"
#include "usart.h"
#include "iwdg.h"
#include "relay.h"
#include "usart3.h"
#include "BH1750.h"
#include "fan.h"
SensorModules sensorData; //声明传感器模块的结构体变量
SensorThresholdValue Sensorthreshold; //声明传感器阈值结构体变量
SystemState systemState; //声明系统状态结构体变量
#define FLASH_START_ADDR 0x0801f000 //写入的起始地址
uint8_t oledPages = 1; //系统显示页面
typedef enum
{
DISPLAY_PAGE1 = 1,
SETTINGS_PAGE
} OLED_PAGES;
/**
* @brief 显示菜单1的固定内容
* @param 无
* @retval 无
*/
void OLED_Menu1(void)
{
//显示"温度: C"
OLED_ShowChinese(1,1,0);
OLED_ShowChinese(1,2,2);
OLED_ShowChar(1,5,':');
OLED_ShowChar(1,8,'C');
//显示"湿度: %"
OLED_ShowChinese(1,5,1);
OLED_ShowChinese(1,6,2);
OLED_ShowChar(1,13,':');
OLED_ShowChar(1,16,'%');
//显示"光照强度: Lux"
OLED_ShowChinese(2, 1, 3);
OLED_ShowChinese(2, 2, 4);
OLED_ShowChinese(2, 3, 5);
OLED_ShowChinese(2, 4, 6);
OLED_ShowChar(2, 9, ':');
OLED_ShowString(2,14,"Lux");
//显示"烟雾浓度: ppm"
OLED_ShowChinese(3, 1, 7);
OLED_ShowChinese(3, 2, 8);
OLED_ShowChinese(3, 3, 9);
OLED_ShowChinese(3, 4, 10);
OLED_ShowChar(3, 9, ':');
OLED_ShowString(3,13,"ppm");
//显示"系统模式:"
OLED_ShowChinese(4, 1, 11);
OLED_ShowChinese(4, 2, 12);
OLED_ShowChinese(4, 3, 13);
OLED_ShowChinese(4, 4, 14);
OLED_ShowChar(4, 9, ':');
}
/**
* @brief 显示菜单1的传感器数据
* @param 无
* @retval 无
*/
void SensorDataDisplay1(void)
{
//显示温度数据
OLED_ShowNum(1, 6, sensorData.temp, 2);
//显示湿度数据
OLED_ShowNum(1, 14, sensorData.humi, 2);
//显示光照强度数据
OLED_ShowNum(2, 10, sensorData.lux, 4);
//显示烟雾浓度数据
OLED_ShowNum(3, 10, sensorData.smoke, 3);
//显示系统状态数据
if (!systemState.mode)
{
OLED_ShowChinese(4, 6, 15);
OLED_ShowChinese(4, 7, 16);
}
else
{
OLED_ShowChinese(4, 6, 17);
OLED_ShowChinese(4, 7, 18);
}
}
/**
* @brief 显示系统阈值设置界面1
* @param 无
* @retval 无
*/
void OLED_SetInterfacevoid(void)
{
//显示"烟雾阈值"
OLED_ShowChinese(1, 2, 7);
OLED_ShowChinese(1, 3, 8);
OLED_ShowChinese(1, 4, 21);
OLED_ShowChinese(1, 5, 22);
OLED_ShowChar(1, 11, ':');
//显示"温度阈值"
OLED_ShowChinese(2, 2, 0);
OLED_ShowChinese(2, 3, 2);
OLED_ShowChinese(2, 4, 21);
OLED_ShowChinese(2, 5, 22);
OLED_ShowChar(2, 11, ':');
//显示"湿度阈值"
OLED_ShowChinese(3, 2, 1);
OLED_ShowChinese(3, 3, 2);
OLED_ShowChinese(3, 4, 21);
OLED_ShowChinese(3, 5, 22);
OLED_ShowChar(3, 11, ':');
//显示"光照阈值"
OLED_ShowChinese(4, 2, 3);
OLED_ShowChinese(4, 3, 4);
OLED_ShowChinese(4, 4, 21);
OLED_ShowChinese(4, 5, 22);
OLED_ShowChar(4, 11, ':');
//显示烟雾阈值数值
OLED_ShowNum(1, 12, Sensorthreshold.smokeValue, 3);
//显示温度阈值数值
OLED_ShowNum(2, 12, Sensorthreshold.tempValue, 2);
//显示湿度阈值数值
OLED_ShowNum(3, 12, Sensorthreshold.humiValue, 2);
//显示光照阈值数值
OLED_ShowNum(4, 12, Sensorthreshold.luxValue, 4);
}
/**
* @brief 记录阈值界面下按KEY1的次数
* @param 无
* @retval 返回次数
*/
uint8_t SetSelection(void)
{
static uint8_t count = 1;
if(KeyNum == KEY_1)
{
KeyNum = 0;
count++;
if (count >= 5)
{
count = 1;
}
}
return count;
}
/**
* @brief 显示阈值界面的选择符号
* @param num 为显示的位置
* @retval 无
*/
void OLED_Option(uint8_t num)
{
switch(num)
{
case 1:
OLED_ShowChar(1,1,'>');
OLED_ShowChar(2,1,' ');
OLED_ShowChar(3,1,' ');
OLED_ShowChar(4,1,' ');
break;
case 2:
OLED_ShowChar(1,1,' ');
OLED_ShowChar(2,1,'>');
OLED_ShowChar(3,1,' ');
OLED_ShowChar(4,1,' ');
break;
case 3:
OLED_ShowChar(1,1,' ');
OLED_ShowChar(2,1,' ');
OLED_ShowChar(3,1,'>');
OLED_ShowChar(4,1,' ');
break;
case 4:
OLED_ShowChar(1,1,' ');
OLED_ShowChar(2,1,' ');
OLED_ShowChar(3,1,' ');
OLED_ShowChar(4,1,'>');
break;
default:
break;
}
}
/**
* @brief 对阈值界面的传感器阈值进行修改
* @param num 为当前用户需要更改的传感器阈值位置
* @retval 无
*/
void ThresholdModification(uint8_t num)
{
switch (num)
{
case 1:
if (KeyNum == KEY_3)
{
KeyNum = 0;
Sensorthreshold.smokeValue += 10;
if (Sensorthreshold.smokeValue > 500)
{
Sensorthreshold.smokeValue = 0;
}
}
else if (KeyNum == KEY_4)
{
KeyNum = 0;
Sensorthreshold.smokeValue -= 10;
if (Sensorthreshold.smokeValue > 500)
{
Sensorthreshold.smokeValue = 500;
}
}
break;
case 2:
if (KeyNum == KEY_3)
{
KeyNum = 0;
Sensorthreshold.tempValue ++;
if (Sensorthreshold.tempValue > 99)
{
Sensorthreshold.tempValue = 0;
}
}
else if (KeyNum == KEY_4)
{
KeyNum = 0;
Sensorthreshold.tempValue --;
if (Sensorthreshold.tempValue > 99)
{
Sensorthreshold.tempValue = 99;
}
}
break;
case 3:
if (KeyNum == KEY_3)
{
KeyNum = 0;
Sensorthreshold.humiValue ++;
if (Sensorthreshold.humiValue > 99)
{
Sensorthreshold.humiValue = 0;
}
}
else if (KeyNum == KEY_4)
{
KeyNum = 0;
Sensorthreshold.humiValue --;
if (Sensorthreshold.humiValue > 99)
{
Sensorthreshold.humiValue = 99;
}
}
break;
case 4:
if (KeyNum == KEY_3)
{
KeyNum = 0;
Sensorthreshold.luxValue += 10;
if (Sensorthreshold.luxValue > 2000)
{
Sensorthreshold.luxValue = 0;
}
}
else if (KeyNum == KEY_4)
{
KeyNum = 0;
Sensorthreshold.luxValue -= 10;
if (Sensorthreshold.luxValue > 2000)
{
Sensorthreshold.luxValue = 2000;
}
}
break;
default:
break;
}
}
/**
* @brief 获取语音模块数据
* @param 无
* @retval 无
*/
void Asrpro(void)
{
if (Usart3_RxFlag == 1)
{
Usart3_RxFlag = 0;
switch (Usart3_RxPacket[3])
{
/*控制开关灯*/
case 1:
if (!systemState.mode)
{
if (Usart3_RxPacket[4])
{
ledluminance.ledDutyRatio = 100;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
}
else
{
ledluminance.ledDutyRatio = 0;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
}
}
break;
/*控制开关风扇*/
case 2:
if (!systemState.mode)
{
if (Usart3_RxPacket[4])
{
fanluminance.FanDutyRatio = 100;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
}
else
{
fanluminance.FanDutyRatio = 0;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
}
}
break;
/*控制窗户开关*/
case 3:
if (!systemState.mode)
{
if (Usart3_RxPacket[4])
{
systemState.motorCommand.motorLocation = motorLocation_ON;
systemState.motorCommand.motorAnterogradeFlag = SET;
currentDataPoint.valuestepperMotor = systemState.motorCommand.motorLocation;
}
else
{
systemState.motorCommand.motorLocation = motorLocation_OFF;
systemState.motorCommand.motorReversalFlag = SET;
currentDataPoint.valuestepperMotor = systemState.motorCommand.motorLocation;
}
}
break;
/*控制系统模式*/
case 4:
if (Usart3_RxPacket[4])
{
systemState.mode = 1;
Buzzer_OFF(); //蜂鸣器关闭
Relay_OFF(); //加湿器关闭
currentDataPoint.valuehumidifier = RESET;
systemState.motorCommand.motorLocation = motorLocation_OFF;
currentDataPoint.valuestepperMotor = RESET;
fanluminance.FanDutyRatio = RESET;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
ledluminance.ledDutyRatio = RESET;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
}
else
{
systemState.mode = 0;
Buzzer_OFF(); //蜂鸣器关闭
Relay_OFF(); //加湿器关闭
currentDataPoint.valuehumidifier = RESET;
systemState.motorCommand.motorLocation = motorLocation_OFF;
currentDataPoint.valuestepperMotor = RESET;
fanluminance.FanDutyRatio = RESET;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
ledluminance.ledDutyRatio = RESET;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
}
break;
/*控制LED亮度等级*/
case 5:
switch (Usart3_RxPacket[4])
{
case 0:
ledluminance.ledDutyRatio = 0;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 1:
ledluminance.ledDutyRatio = 10;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 2:
ledluminance.ledDutyRatio = 20;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 3:
ledluminance.ledDutyRatio = 30;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 4:
ledluminance.ledDutyRatio = 40;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 5:
ledluminance.ledDutyRatio = 50;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 6:
ledluminance.ledDutyRatio = 60;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 7:
ledluminance.ledDutyRatio = 70;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 8:
ledluminance.ledDutyRatio = 80;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 9:
ledluminance.ledDutyRatio = 90;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
case 10:
ledluminance.ledDutyRatio = 100;
currentDataPoint.valueLED = ledluminance.ledDutyRatio; //LED亮度上传云平台
TIM_SetCompare2(TIM1, ledluminance.ledDutyRatio); //显示亮度
break;
default:
break;
}
break;
/*控制风速等级*/
case 6:
if (!systemState.mode)
{
switch (Usart3_RxPacket[4])
{
case 0:
fanluminance.FanDutyRatio = 0;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 1:
fanluminance.FanDutyRatio = 15;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 2:
fanluminance.FanDutyRatio = 20;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 3:
fanluminance.FanDutyRatio = 30;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 4:
fanluminance.FanDutyRatio = 40;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 5:
fanluminance.FanDutyRatio = 50;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 6:
fanluminance.FanDutyRatio = 60;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 7:
fanluminance.FanDutyRatio = 70;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 8:
fanluminance.FanDutyRatio = 80;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 9:
fanluminance.FanDutyRatio = 90;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
case 10:
fanluminance.FanDutyRatio = 100;
currentDataPoint.valuefan = fanluminance.FanDutyRatio; //风速数据上传至云平台
TIM_SetCompare3(TIM1, fanluminance.FanDutyRatio); //显示风速
break;
default:
break;
}
}
break;
/*控制加湿器开关*/
case 7:
if (!systemState.mode)
{
if (Usart3_RxPacket[4])
{
Relay_ON(); //加湿器开启
currentDataPoint.valuehumidifier = 1;
}
else
{
Relay_OFF(); //加湿器关闭
currentDataPoint.valuehumidifier = 0;
}
}
break;
default:
break;
}
}
}
/**
* @brief 传感器数据扫描
* @param 无
* @retval 无
*/
void SensorScan(void)
{
DHT11_Read_Data(&sensorData.humi, &sensorData.temp);
Get_Average_MQ2_PPM(&sensorData.smoke);
sensorData.lux = (uint16_t)read_BH1750();
}
int main(void)
{
OLED_Init();
DHT11_Init();
Key_Init();
MOTOR_Init();
Buzzer_Init();
Relay_Init();
Init_BH1750();
LED_Init();
Fan_Init();
ADCX_Init();
Timer2_Init(9, 14398);
Uart2_Init(9600);
Uart1_Init(115200);
IWDG_Init();
Uart3_Init();
PWM_Init(100 - 1, 720 - 1);
Sensorthreshold.tempValue = FLASH_R(FLASH_START_ADDR); //从指定页的地址读FLASH
Sensorthreshold.humiValue = FLASH_R(FLASH_START_ADDR+2); //从指定页的地址读FLASH
Sensorthreshold.luxValue = FLASH_R(FLASH_START_ADDR+4); //从指定页的地址读FLASH
Sensorthreshold.smokeValue = FLASH_R(FLASH_START_ADDR+6); //从指定页的地址读FLASH
Sensorthreshold.flameValue = FLASH_R(FLASH_START_ADDR+8); //从指定页的地址读FLASH
GENERAL_TIM_Init();
userInit(); //完成机智云初始赋值
gizwitsInit(); //开辟一个环形缓冲区
gizwitsSetMode(WIFI_AIRLINK_MODE);
Delay_ms(1000);
while (1)
{
IWDG_ReloadCounter(); //使能重装载寄存器计数
SensorScan(); //获取传感器数据
switch (oledPages)
{
case DISPLAY_PAGE1:
OLED_Menu1(); //显示主页面1固定信息
SensorDataDisplay1();//显示传感器1数据
/* 手动模式下按键控制执行器的运行 */
if (!systemState.mode)
{
LED_PWM_KEY(); //LED按键控制
Fan_PWM_KEY(); //风扇按键控制
/* 按键控制步进电机的运行 */
if(KeyNum == KEY_4 && systemState.motorCommand.motorLocation == motorLocation_OFF)
{
KeyNum = 0;
systemState.motorCommand.motorAnterogradeFlag = 1;
}
else if ((KeyNum == KEY_4 && systemState.motorCommand.motorLocation == motorLocation_ON))
{
KeyNum = 0;
systemState.motorCommand.motorReversalFlag = 1;
}
}
/*按键按下时切换模式*/
if (KeyNum == KEY_1)
{
KeyNum = 0;
systemState.mode = !systemState.mode;
if (!systemState.mode)
{
Buzzer_OFF();
Relay_OFF();
}
}
/*按键按下时进入阈值设计界面*/
if (KeyNum == KEY_Long1)
{
KeyNum = 0;
oledPages = SETTINGS_PAGE;
OLED_Clear();
}
Asrpro(); //语音控制
MotorOperation(); //步进电机控制
break;
case SETTINGS_PAGE:
OLED_Option(SetSelection()); //实现阈值设置页面的选择功能
OLED_SetInterfacevoid(); //显示阈值设置界面1的固定内容
ThresholdModification(SetSelection()); //实现阈值调节功能
//判断是否退出阈值设置界面
if (KeyNum == KEY_2)
{
KeyNum = 0;
oledPages = DISPLAY_PAGE1; //跳转到主界面
OLED_Clear(); //清屏
//存储修改的传感器阈值至flash内
FLASH_W(FLASH_START_ADDR, Sensorthreshold.tempValue,Sensorthreshold.humiValue,
Sensorthreshold.luxValue, Sensorthreshold.smokeValue, Sensorthreshold.flameValue);
}
break;
default: break;
}
userHandle(); //更新机智云数据点变量存储的值
gizwitsHandle((dataPoint_t *)¤tDataPoint); //数据上传至机智云
}
}