目录
一、前言
项目成品图片:

哔哩哔哩视频链接:
(资料分享见文末)
二、项目简介
1.功能详解
基于STM32的智能鞋柜(机智云)
功能如下:
- DHT11检测鞋柜温湿度,温度低于阈值开启加热,湿度高于阈值开启通风;
- PM2.5传感器检测粉尘浓度,当粉尘浓度值大于设置最大值,进行通风且开启蜂鸣器报警
- MQ-135检测鞋柜空气质量,过高时启动通风并开启蜂鸣器报警
- 光电红外传感器检测柜门状态,关闭时,在定时时间范围内自动打开消毒灯,打开时,消毒灯关闭
- 光敏传感器检测光照值,光照值低于阈值且鞋柜门打开时,开启灯光
- 按键可调节阈值、设置消毒开关时间和模式切换
- 显示屏显示当前测量值
- 手动模式下可通过按键控制加热、照明、消毒和风扇的开关
- 通过机智云连接手机APP,APP可查看环境信息数据和控制指令下发
2.主要器件
- STM32F103C8T6单片机
- OLED 屏幕
- DHT11温湿度传感器
- PM2.5粉尘传感器
- MQ-135空气质量传感器
- 光电红外传感器
- 光敏传感器
- ESP8266-01S WIFI模块
- 加热片
- 风扇模块
- UV消毒灯
- 照明灯
- 有源蜂鸣器
- 继电器
三、原理图设计
四、PCB硬件设计
PCB图
五、程序设计
cpp
#include "stm32f10x.h"
#include "led.h"
#include "beep.h"
#include "usart.h"
#include "delay.h"
#include "dht11.h"
#include "oled.h"
#include "key.h"
#include "Modules.h"
#include "TIM2.h"
#include "adcx.h"
#include "flash.h"
#include "stepmotor.h"
#include "fan.h"
#include "bump.h"
#include "jsq.h"
#include "usart2.h"
#include "TIM3.h"
#include "gizwits_product.h"
#include "gizwits_protocol.h"
/****************异方辰电子工作室******************
STM32
* 项目 : STM32智能鞋柜
* 版本 : V2.0
* 日期 : 2025.7.13
* MCU : STM32F103C8T6
* 接口 : 见代码
* IP账号 : 异方辰电子/辰哥单片机设计(同BILIBILI|抖音|快手|小红书|CSDN|公众号|视频号等)
* 作者 : 辰哥
* 工作室 : 异方辰电子工作室
* 授权IP : 辰哥单片机设计、异方辰电子、YFC电子、异方辰系列
* 官方网站 : www.yfcdz.cn
**********************BEGIN***********************/
#define KEY_Long1 11
#define KEY_1 1
#define KEY_2 2
#define KEY_3 3
#define KEY_4 4
#define FLASH_START_ADDR 0x0801f000 //写入的起始地址
SensorModules sensorData; //声明传感器数据结构体变量
SensorThresholdValue Sensorthreshold; //声明传感器阈值结构体变量
DriveModules driveData; //声明驱动器状态结构体变量
TimeValue TimeData; //声明时间状态结构体变量
uint8_t Time_flag = 1;
uint8_t mode = 1; //系统模式 1自动 2手动 3设置
u8 dakai;//串口3使用的传递变量
u8 Flag_dakai;//串口3接收标志位
uint8_t RxData; //定义用于接收串口数据的变量
uint8_t A_MODE,B_MODE,C_MODE,D_MODE,E_MODE,F_MODE,G_MODE;
uint8_t Motor_F,Time_f1 = 1,Time_f2,Time_f3,Time_con=0;
uint8_t day = 0;
//系统静态变量
static uint8_t count_a = 1; //自动模式按键数
uint8_t count_m = 1; //手动模式按键数
uint8_t last_mode = 0;
static uint8_t count_s = 1; //设置模式按键数
int main(void)
{
SystemInit();//配置系统时钟为72M
delay_init(72);
ADCx_Init();
LED_Init();
// LED_On();
Key_Init();
BEEP_Init();
MOTOR_Init();
FAN_Init();
BUMP_Init();
JSQ_Init();
OLED_Init();
DHT11_Init();
PM25_Init();
OLED_Clear();
Sensorthreshold.tempValue = FLASH_R(FLASH_START_ADDR);
Sensorthreshold.humiValue = FLASH_R(FLASH_START_ADDR+2);
Sensorthreshold.luxValue = FLASH_R(FLASH_START_ADDR+4);
Sensorthreshold.PM25Value = FLASH_R(FLASH_START_ADDR+6);
Sensorthreshold.COValue = FLASH_R(FLASH_START_ADDR+8);
Sensorthreshold.AQIValue = FLASH_R(FLASH_START_ADDR+10);
TimeData.H = FLASH_R(FLASH_START_ADDR+12);
TimeData.M = FLASH_R(FLASH_START_ADDR+14);
TimeData.S = FLASH_R(FLASH_START_ADDR+16);
// 读取消毒时间
TimeData.H_D = FLASH_R(FLASH_START_ADDR+18);
TimeData.M_D = FLASH_R(FLASH_START_ADDR+20);
TimeData.S_D = FLASH_R(FLASH_START_ADDR+22);
TimeData.H_D1 = FLASH_R(FLASH_START_ADDR+24);
TimeData.M_D1 = FLASH_R(FLASH_START_ADDR+26);
TimeData.S_D1 = FLASH_R(FLASH_START_ADDR+28);
// 设置默认值(如果读取的值不合理)
if(TimeData.H > 23) TimeData.H = 12;
if(TimeData.M > 59) TimeData.M = 0;
if(TimeData.S > 59) TimeData.S = 0;
if(TimeData.H_D > 23) TimeData.H_D = 9;
if(TimeData.M_D > 59) TimeData.M_D = 0;
if(TimeData.S_D > 59) TimeData.S_D = 0;
if(TimeData.H_D1 > 23) TimeData.H_D1 = 18;
if(TimeData.M_D1 > 59) TimeData.M_D1 = 0;
if(TimeData.S_D1 > 59) TimeData.S_D1 = 0;
if(Sensorthreshold.tempValue > 50) Sensorthreshold.tempValue = 20;
if(Sensorthreshold.humiValue > 80) Sensorthreshold.humiValue = 20;
if(Sensorthreshold.luxValue > 999) Sensorthreshold.luxValue = 100;
if(Sensorthreshold.AQIValue > 1000) Sensorthreshold.AQIValue = 50;
if(Sensorthreshold.PM25Value > 500) Sensorthreshold.PM25Value = 100;
TIM2_Init(72-1,1000-1);
TIM3_Int_Init(1000-1,72-1);
USART1_Config();//串口初始化
USART2_Config();
OLED_Clear();
TimeData.New = 1;
TimeData.Time_f = 0;
userInit(); // 机智云用户初始化(数据点初始化等)
gizwitsInit(); // 机智云协议初始化(WiFi配网、数据通信初始化)
gizwitsSetMode(WIFI_AIRLINK_MODE); //默认一键配网
delay_ms(200);
printf("Start \n");
gizwitsHandle((dataPoint_t *)¤tDataPoint);
ScanGizwitsMode();
// delay_ms(200);
while (1)
{
gizwitsHandle((dataPoint_t *)¤tDataPoint);
SensorScan(); //获取传感器数据
switch(mode)
{
case AUTO_MODE:
{
AutoControl();
Control_Manager();
Time_f2 = 0;
Time_f1 = 1;//控制菜单显示
if(SetAuto() ==1 )//判断自动模式按下按键2的次数
{
OLED_autoPage1(); //显示主页面1固定信息
SensorDataDisplay1(); //显示传感器1数据
}
else
{
OLED_autoPage2(); //显示主页面2固定信息
SensorDataDisplay2(); //显示传感器2数据
}
/*按键1按下时切换模式*/
if (KeyNum == KEY_1) //系统模式mode 1自动 2手动 3设置
{
KeyNum = 0;
mode = MANUAL_MODE;
driveData.LED_Flag = 0;
driveData.Fan_Flag = 0;
count_m = 1;
Time_f1 = 1;
OLED_Clear();
}
if (KeyNum == KEY_Long1)
{
KeyNum = 0;
mode = SETTINGS_MODE;
count_s = 1;
OLED_Clear();
}
}
break;
case MANUAL_MODE:
{
OLED_manualOption(SetManual());//通过按键2按下的次数来控制光标显示的位置
ManualControl(SetManual());//通过按键2按下的次数来显示相应的执行器的开/关
if (SetManual() <= 4) //通过判断按键2按下的次数来显示界面
{
OLED_manualPage1();
ManualSettingsDisplay1();
}
else
{
OLED_manualPage2();
ManualSettingsDisplay2();
}
if (KeyNum == KEY_1) //系统模式mode 0手动 1自动(默认)
{
KeyNum = 0;
mode = AUTO_MODE;
count_a = 1;
OLED_Clear();
}
Control_Manager();
}
break;
case SETTINGS_MODE:
OLED_settingsOption(SetSelection()); //实现阈值设置页面的选择功能
ThresholdSettings(SetSelection()); //实现阈值调节功能
if (Time_f1 == 1)
{
OLED_settingsPage1(); //显示阈值设置界面1固定信息
SettingsThresholdDisplay1(); //显示传感器阈值1数据
}
else if(Time_f1 == 2) //否则显示设置页面2
{
OLED_settingsPage2(); //显示阈值设置界面2固定信息
SettingsThresholdDisplay2(); //显示传感器阈值2数据
}
else if(Time_f1 == 3)//界面3 系统时间设置
{
OLED_settingsPage3(); //显示阈值设置界面3固定信息
SettingsThresholdDisplay3(); //显示传感器阈值3数据
}
else if(Time_f1 == 4)//界面4消毒定时开启/关闭
{
OLED_settingsPage4(); //显示阈值设置界面4固定信息
SettingsThresholdDisplay4(); //显示传感器阈值2数据
}
//判断是否退出阈值设置界面
if (KeyNum == KEY_1)
{
KeyNum = 0;
if(Time_f1 == 3)
{
mode = SETTINGS_MODE;
Time_f1 = 1;
count_s = 1;
TimeData.New = 1;
OLED_Clear(); //清屏
}
else if(Time_f1 == 4)
{
mode = SETTINGS_MODE;
TimeData.Time_f = 1;
Time_f1 = 2;
count_s = 7;
OLED_Clear(); //清屏
}
else
{
mode = AUTO_MODE;
count_a = 1;
count_s = 1;
OLED_Clear(); //清屏
}
}
break;
default: break;
}
//存储修改的传感器阈值至flash内
FLASH_W(FLASH_START_ADDR, Sensorthreshold.tempValue, Sensorthreshold.humiValue,
Sensorthreshold.luxValue, Sensorthreshold.PM25Value,
Sensorthreshold.COValue, Sensorthreshold.AQIValue,
TimeData.H, TimeData.M, TimeData.S,
TimeData.H_D, TimeData.M_D, TimeData.S_D,
TimeData.H_D1, TimeData.M_D1, TimeData.S_D1);
userHandle();
}
}
六、实验效果
七、资料内容