STM32智能风扇(机智云)

目录

一、前言

二、项目简介

1.功能详解

2.主要器件

三、原理图设计

四、PCB硬件设计

[PCB图 ​编辑​编辑](#PCB图 编辑编辑)

五、程序设计

六、实验效果

七、包含内容

项目分享


一、前言

项目成品图片:

哔哩哔哩视频链接:https://www.bilibili.com/video/BV1F6Q9BjEVX/?spm_id_from=333.1387.homepage.video_card.click&vd_source=199aed5297a00e80e1faf7e270afe8d7

(资料分享见文末)

二、项目简介

1.功能详解

基于STM32的智能风扇(机智云)

功能如下:

  1. 环境采集:采集环境温湿度、有无人
  2. 显示功能:OLED显示当前环境温度、环境湿度、是否有人和倒计时时间
  3. 模式切换:通过按键可以切换手动模式和自动模式
  4. 自动模式:当有人并且环境温度大于温度下限时开启风扇一档风速,温度大于温度平均值时开启风扇二档风速,温度大于温度上限时开启风扇三档风速并开启蜂鸣器报警;当定时模式开启的状态下有人且风扇开启即开启倒计时,倒计时清零时风扇关闭
  5. 手动模式:可以手动控制灯光和风扇档位(关、一档、二档、三档),风扇开启后可以控制摇头开关
  6. 阈值调节:可通过按键设置温度上限、温度下限、定时时间(时分秒)、定时功能(开/关)
  7. 机智云APP:通过WIFI连接机智云APP,APP可以接收环境信息数据、模式切换、手动模式下控制照明和风速,可修改温度阈值

2.主要器件

  • STM32F103C8T6最小系统板
  • OLED显示屏(4针IIC协议)
  • DHT11温湿度传感器
  • 光电红外传感器
  • ESP8266-01S(WIFI模块)
  • TB6612电机驱动模块
  • 步进电机
  • 风扇
  • 蜂鸣器
  • LED灯

三、原理图设计

四、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 "Motor.h"
#include "HW.h"
#include "usart2.h"
#include "stepmotor.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   // 按键1长按(功能:自动模式 → 设置模式)
#define KEY_1	1        // 按键1短按(功能:自动模式 → 手动模式)
#define KEY_2	2        // 按键2(功能:菜单页面切换/光标移动)
#define KEY_3	3        // 按键3(功能:参数增加/设备开启)
#define KEY_4	4        // 按键4(功能:参数减少/设备关闭)

// Flash存储起始地址:用于保存传感器阈值参数(掉电不丢失)
#define FLASH_START_ADDR	0x0801f000	

// 模式定义
#define AUTO_MODE     1   // 自动模式
#define MANUAL_MODE   2   // 手动模式
#define SETTINGS_MODE 3   // 设置模式

// 外部变量声明
//extern u8 data; // 蓝牙数据
extern uint8_t zt_flag;
extern uint8_t one_second_flag;
// 结构体变量声明
SensorModules sensorData;								// 声明传感器数据结构体变量
SensorThresholdValue Sensorthreshold;		// 声明传感器阈值结构体变量
DriveModules driveData;									// 声明驱动器状态结构体变量

// 系统核心全局变量
uint8_t mode = AUTO_MODE;	// 系统模式控制:1=自动模式,2=手动模式,3=设置模式

// 模式内部状态变量
static uint8_t auto_page = 1;      // 自动模式页面:1=第一页,2=第二页
uint8_t count_m = 1;        // 手动模式按键计数:记录当前选中的控制项
static uint8_t count_s = 1;        // 设置模式按键计数:记录当前选中的阈值项

static uint8_t is_secondary_menu = 0;      // 0一级菜单,1二级菜单
static uint8_t secondary_pos = 1;          // 二级菜单光标位置(1-3对应时/分/秒)
static uint8_t last_secondary_pos = 0;     // 记录上次光标位置
static uint8_t last_hour = 0xFF, last_minute = 0xFF, last_second = 0xFF;  // 记录上次时间值
static uint8_t secondary_initialized = 0;   // 二级菜单初始化标记

static uint8_t timer_start_flag = 0;        // 倒计时开始标志,1=开始倒计时,0=停止
static uint8_t force_fan_on = 0;            // 强制风扇开启标志

void OLED_manualPage1(void);
void OLED_manualOption(uint8_t num);
void ManualSettingsDisplay1(void);

/**
  * @brief  主函数(系统入口)
  * @note   初始化硬件→读取Flash阈值→主循环
  * @param  无
  * @retval 无
  */
int main(void)
{ 
	SystemInit();	// 配置系统时钟为72M
	delay_init(72);
	ADCX_Init();
	LED_Init();
	LED_On();
	Key_Init();
	OLED_Init();
	DHT11_Init();
	OLED_Clear();
	BEEP_Init();
	MOTOR_Init();
	MOTORE_Init();
	HW_Init();
	TIM2_Init(); ; 
	USART1_Config();	// 串口初始化
  USART2_Config(); 		// 蓝牙串口初始化

	FLASH_ReadThreshold();
    
    delay_ms(1000);
    OLED_Clear();
	
	// 静态变量用于记录模式内状态
	static uint8_t last_mode = 0;			// 记录上一次的系统模式
	static uint32_t last_sensor_time = 0;	// 传感器扫描时间戳
	
	TIM4_Init(1000-1, 72-1);
	userInit();       // 机智云用户初始化(数据点初始化等)
    gizwitsInit();    // 机智云协议初始化(WiFi配网、数据通信初始化)
	gizwitsSetMode(WIFI_AIRLINK_MODE); //默认一键配网
	delay_ms(200);
	
    printf("Start \n"); 
    gizwitsHandle((dataPoint_t *)&currentDataPoint);
    ScanGizwitsMode();

    delay_ms(200);
    
	while (1)
	{
		gizwitsHandle((dataPoint_t *)&currentDataPoint);
		
		// 获取当前系统时间
		uint32_t current_time = delay_get_tick();
		
		// 优化传感器扫描频率:每200ms扫描一次
		if(current_time - last_sensor_time > 200)
		{
			SensorScan();	// 获取传感器数据
			last_sensor_time = current_time;
		}
		
		// 立即处理按键
		uint8_t current_key_num = KeyNum;
		
		// 模式切换按键立即处理
		if(current_key_num != 0)
		{
			switch(mode)
			{
				case AUTO_MODE:
					if(current_key_num == KEY_1) // 短按KEY1:自动模式→手动模式
					{
						mode = MANUAL_MODE;
						count_m = 1;
						// 如果定时开启,风扇保持开启状态
						if (Sensorthreshold.timing == 1)
						{
							// 定时开启时,切换到手动模式保持风扇开启
							if (driveData.Fan_Flag == 0)
								driveData.Fan_Flag = 1;
						}
						else
						{
							driveData.Fan_Flag = 0;
						}
						driveData.LED_Flag = 0;
						KeyNum = 0;
					}
					else if(current_key_num == KEY_Long1) // 长按KEY1:自动模式→设置模式
					{
						mode = SETTINGS_MODE;
						count_s = 1;
						KeyNum = 0;
					}
					break;
					
				case MANUAL_MODE:
					if(current_key_num == KEY_1) // 短按KEY1:手动模式→自动模式
					{
						mode = AUTO_MODE;
						// 如果定时未开启,关闭风扇
						if (Sensorthreshold.timing == 0)
						{
							driveData.Fan_Flag = 0;
						}
						KeyNum = 0;
					}
					break;
					
				case SETTINGS_MODE:
					// 设置模式内部按键在各自模式中处理
					break;
			}
		}
		
		// 模式切换优化:检测到系统模式变化时清屏并初始化
		if(last_mode != mode)
		{
			OLED_Clear();
			last_mode = mode;
			
			// 立即绘制新模式的固定标题内容
			switch(mode)
			{
				case AUTO_MODE:
					auto_page = 1;
					OLED_autoPage1();
					break;
				case MANUAL_MODE:
					OLED_manualPage1();
					break;
				case SETTINGS_MODE:
					OLED_settingsPage1();
					SettingsThresholdDisplay1();
					break;
			}
			OLED_Refresh();
		}
		
		// 模式处理
		switch(mode)
		{
			// 自动模式
			case AUTO_MODE:
			{
				uint8_t curr_auto_page = SetAuto();
				if(curr_auto_page == 1)
				{
					SensorDataDisplay1();
				}
//				else
//				{
//					SensorDataDisplay2();
//				}
				AutoControl();
				Control_Manager();
				break;
			}
			
			// 手动模式
			case MANUAL_MODE:
			{
				static uint8_t manual_page_initialized = 0;
				static uint8_t last_manual_count = 0;
				static uint8_t last_LED_Flag = 0;
				static uint8_t last_Fan_Flag = 0;
				static uint8_t force_refresh = 0;
				
				// 模式切换时重新初始化状态
				if(last_mode != mode)
				{
					manual_page_initialized = 0;
					last_manual_count = 0;
					last_LED_Flag = driveData.LED_Flag;
					last_Fan_Flag = driveData.Fan_Flag;
					force_refresh = 1;
					count_m = 1;
				}
				
				uint8_t current_manual_count = SetManual();
				
				// 检查设备状态是否改变
				uint8_t need_refresh = 0;
				if(driveData.LED_Flag != last_LED_Flag || driveData.Fan_Flag != last_Fan_Flag)
				{
					need_refresh = 1;
					last_LED_Flag = driveData.LED_Flag;
					last_Fan_Flag = driveData.Fan_Flag;
				}
				
				// 需要刷新时重新绘制页面
				if(!manual_page_initialized || current_manual_count != last_manual_count || need_refresh || force_refresh)
				{
					OLED_manualPage1();
					OLED_manualOption(current_manual_count);
					ManualSettingsDisplay1();
					manual_page_initialized = 1;
					last_manual_count = current_manual_count;
					force_refresh = 0;
					OLED_Refresh();
				}
				
				// 立即处理手动模式按键
				if(current_key_num != 0)
				{
					ManualControl(current_manual_count);
					OLED_manualPage1();
					OLED_manualOption(current_manual_count);
					ManualSettingsDisplay1();
					OLED_Refresh();
					KeyNum = 0;
				}
				
				Control_Manager();
				break;
			}
			
			// 设置模式
			case SETTINGS_MODE:
			{
				SettingsModeHandler();
				
				// 按键1:返回自动模式并保存所有设置
				if (KeyNum == KEY_1)
				{
					KeyNum = 0;
					mode = AUTO_MODE;
					
					// 保存设置到Flash
					FLASH_SaveSettings();
					
					// 重置二级菜单状态
					is_secondary_menu = 0;
					secondary_initialized = 0;
					secondary_pos = 1;
					
					// 清屏并显示自动模式第一页
					OLED_Clear();
					OLED_autoPage1();
					OLED_Refresh();
					
					printf("返回自动模式,设置已保存\n");
					printf("定时状态:%s,定时时间:%02d:%02d:%02d\n", 
                           Sensorthreshold.timing ? "开启" : "关闭",
                           Sensorthreshold.time_hours,
                           Sensorthreshold.time_minute,
                           Sensorthreshold.time_second);
				}
				break;
			}
		}
		
		// 限制显示刷新频率:每50ms刷新一次(避免屏幕闪烁)
		if(current_time % 50 == 0)
		{
			OLED_Refresh();
		}
		
		userHandle();
	}
}

六、实验效果

七、包含内容

项目分享

相关推荐
【 STM32开发 】2 小时前
【STM32 + CubeMX】低功耗 -- SLEEP 睡眠模式
stm32·单片机·低功耗·sleep·睡眠模式
芯芯点灯2 小时前
LIS2DW12驱动,功耗,数据可视化
驱动开发·单片机
Nice__J3 小时前
Mcu架构以及原理——2.Cortex-M流水线与指令集
单片机·嵌入式硬件·架构
小白橘颂3 小时前
【C语言】基础概念梳理(一)
c语言·开发语言·stm32·单片机·mcu·物联网·51单片机
aini_lovee3 小时前
SIM7600模块STM32控制程序
stm32·单片机·嵌入式硬件
是翔仔呐3 小时前
第13章 超声波测距传感器驱动:HC-SR04底层原理与C语言实现
c语言·开发语言·单片机·嵌入式硬件·gitee
小飞菜涅4 小时前
fast-lio2复现
嵌入式硬件·学习·ubuntu
青山_FPGA4 小时前
AT24CM01芯片的时序是如何进行控制的?
嵌入式硬件·fpga开发·lattice
鲨辣椒100864 小时前
51单片机核心钉子户——温度采集模块
单片机·嵌入式硬件·51单片机