基于STM32单片机的智能家居控制系统(含温湿度传感器DHT11、BH1750光照传感器、声光报警、0.96OLED显示、步进电机ULN2003+28byj-48窗帘控制、灯光、继电器控制,按键交互)
摘要:基于STM32F103C8T6单片机的智能家居控制系统,通过DHT11温湿度传感器和BH1750光照传感器采集环境数据,利用OLED显示屏实时显示信息。系统具备自动控制功能,根据预设阈值调节窗帘、灯光和风扇,同时支持手动模式切换。硬件包含ULN2003驱动的步进电机、继电器控制的风扇及声光报警模块。软件开发采用Keil MDK环境,程序包含数据采集、阈值判断和执行器控制等核心功能。资料包含完
设计简介
基于STM32单片机的智能家居控制系统,通过集成多种传感器和执行器,实现对家居环境的实时监测与控制。系统包含DHT11温湿度传感器、BH1750光照传感器、声光报警模块、OLED显示屏、步进电机ULN2003+28byj-48窗帘控制窗帘电机、灯光控制、继电器控制风扇以及按键输入等功能模块。该系统能够自动调节室内环境,提升居住舒适度,同时支持手动干预。

硬件选型
主控芯片选用STM32F103C8T6,具有丰富的外设接口和较高的性能。
温湿度传感器采用DHT11,成本低且易于集成。
光照传感器选用BH1750,支持高精度光照强度检测。
声光报警模块由蜂鸣器和LED组成,用于异常情况提示。
OLED显示屏为SSD1306驱动的0.96英寸屏幕,显示实时数据。
窗帘电机选用5V步进电机,
通过继电器控制风扇。
根据光照强度自动开关灯
按键模块为机械式按键,用于手动控制模式切换。
软件环境
开发环境为Keil MDK-ARM,支持STM32系列芯片的C语言开发。
通信协议使用I2C和GPIO,部分模块采用单总线协议(如DHT11)。
程序框架基于标准库开发,简化外设初始化与控制逻辑。
上位机通信可选串口调试助手或自定义协议。
所需硬件以及传感器模块
- STM32F103C8T6核心板
STM32F103C8T6单片机是一款非常用的单片机型号,可以方便灵活的进行嵌入式系统开发。首先,它的处理器基于Cortex-M3内核,最高工作频率达72MHz。STM32F103C8T6拥有64KB闪存和20KB SRAM,非常适合中小型单片机开发项目。
具有非常丰富的外设接口,如串口USART、SPI通信、I2C通讯、CAN通讯和USB,在与单片机外设通信方面非常方便。有多个GPIO通用IO口,定时器,中断系统,灵活配置为输入,输出、模拟输入或PWM输出,可以连接各类传感器和模块。
内部集成的12位逐次逼近型ADC和DAC,支持高精度模拟信号处理。STM32F103C8T6还支持低功耗模式,适合电池供电的应用场景。结合强大的STM32开发生态,包括库函数和工具链,可以让开发者很方便的完成单片机项目的开发。


- DHT11温湿度传感器
- BH1750光照传感器
- 蜂鸣器与LED组成的声光报警模块
- SSD1306 OLED显示屏
- 5V步进电机ULN2003A+28BYJ-48(窗帘控制)
- LED灯珠与驱动电路
- 直流风扇与继电器控制电路
- 独立按键
原理图及设计流程图
原理图:包含STM32最小系统电路、传感器接口电路、执行器驱动电路(如继电器、MOSFET)、电源管理电路等。
设计流程图:
- 系统初始化:外设配置、传感器校准。
- 数据采集:循环读取温湿度、光照强度。
- 逻辑判断:根据阈值控制灯光、风扇、窗帘。
- 用户交互:按键输入触发手动模式,OLED显示状态。
- 异常处理:超限时触发声光报警。


程序代码
c复制插入
#include "stm32f10x.h" // Device header #include "Delay.h" #include "sys.h" uint8_t KeyNum; //按键值变量 uint8_t MODE; //手动自动模式变量 uint8_t SetSelect,setflash; //阈值设置位置变量 uint8_t PAGE; //页面显示变量 uint16_t light; //光照强度变量 uint8_t Temperature,Humi; //温度湿度变量 uint16_t light_G=5000; //光照强度阈值高 uint16_t light_D=500; //光照强度阈值低 uint8_t Temperature_G=35; uint8_t Curtain_State=1,Fan_State,Light_State; //窗帘,窗户,烟雾标志位 uint8_t Receive_Data; //按键值变量 void PAGE1(void); //显示页面1函数 void PAGE2(void); //显示页面2函数 int main(void) { /*初始化*/ Delay_ms(100); Relay_Init(); OLED_Init(); Serial_Init(); BH1750_Init(); Key_Init(); DHT11_Init(); AD_Init(); Stepper_Servo_Init(); LED_Buzzer_Init(); LED_Init(); Timer4_Init(); Delay_ms(500); while (1) { Delay_ms(50); DHT11_Read_Data(&Temperature,&Humi); //获取温湿度 light = bh_data_read(); //获取光强度 switch (PAGE) //页面显示 { case 0: { OLED_Clear(); //清屏 PAGE1(); //显示页面1 }break; case 1: { OLED_Clear(); //清屏 PAGE2(); //显示页面2 }break; } if(Key_Check(KEY_1,KEY_SINGLE)) //按键1按下切换手动自动模式 { MODE=!MODE; LED_Off(); Buzzer_Off(); } if(Key_Check(KEY_4,KEY_LONG)) //按键4长按切换显示页面 { PAGE=!PAGE; } if(PAGE==1) //当页面2阈值设置界面时的按键功能 { if(Key_Check(KEY_2,KEY_SINGLE)) { SetSelect++; //按键2按下切换阈值设置位置 SetSelect%=4; } if(Key_Check(KEY_3,KEY_SINGLE)) { if(SetSelect==1) //设置位置2 { light_D+=50; if(light_D>=2000)light_D=2000; } if(SetSelect==2) //设置位置3 { light_G+=1000; //光照强度阈值增加1000 if(light_G>=65535)light_G=65535; } if(SetSelect==3) //设置位置4 { Temperature_G+=1; //温度阈值增加1 if(Temperature_G>=99)Temperature_G=99; } } if(Key_Check(KEY_4,KEY_SINGLE)) { if(SetSelect==1) //设置位置2 { light_D-=50; if(light_D<=0|light_D>=3000)light_D=0; } if(SetSelect==2) //设置位置3 { light_G-=1000; //光照强度阈值减小1000 if(light_G<=0)light_G=0; } if(SetSelect==3) //设置位置4 { Temperature_G-=1; //温度阈值减小1 if(Temperature_G<=0|Temperature_G>100)Temperature_G=0; } } } control_alarm(); //传感器阈值比较报警函数 OLED_Update(); } } void PAGE1(void) //页面显示函数页面1 { OLED_ShowChinese(0,0,"温度"); OLED_ShowChar(28,0,':',OLED_8X16); OLED_ShowNum(36,0,Temperature,2,OLED_8X16); //显示屏显示温度 OLED_ShowChar(52,0,'C',OLED_8X16); OLED_ShowChinese(64,0,"湿度"); OLED_ShowChar(96,0,':',OLED_8X16); OLED_ShowNum(104,0,Humi,2,OLED_8X16); //显示屏显示温度 OLED_ShowChar(120,0,'%',OLED_8X16); OLED_ShowChinese(0,16,"光照"); OLED_ShowChar(32,16,':',OLED_8X16); OLED_ShowNum(72,16,light,5,OLED_8X16); OLED_ShowString(112,16,"LX",OLED_8X16); if(light>=light_D|light<=light_G) { OLED_ShowChinese(40,16,"正常"); OLED_ShowString(0,50," ",OLED_8X16); } if(light>=light_G) { OLED_ShowChinese(40,16,"强烈"); if(MODE==0) OLED_ShowImage(0,50,15,15,Motor); } if(light<=light_D) { OLED_ShowChinese(40,16,"昏暗"); if(MODE==0) OLED_ShowImage(0,50,15,15,Light); } OLED_ShowChinese(0,32,"温度"); OLED_ShowChar(32,32,':',OLED_8X16); if(Temperature>=Temperature_G) { OLED_ShowChinese(40,32,"高"); OLED_ShowString(56,32," ",OLED_8X16); if(MODE==0) OLED_ShowImage(16,50,15,15,Fan); } else { OLED_ShowChinese(40,32,"舒适"); OLED_ShowString(16,50," ",OLED_8X16); } if(MODE==0) OLED_ShowChinese(96,48,"自动"); //显示自动/手动 else OLED_ShowChinese(96,48,"手动"); } void PAGE2(void) //页面显示函数页面2,阈值设定,监控开关 { OLED_ShowChinese(0,0,"光照低"); OLED_ShowChar(48,0,':',OLED_8X16); OLED_ShowNum(56,0,light_D,4,OLED_8X16); OLED_ShowString(88,0,"LX",OLED_8X16); OLED_ShowChinese(0,16,"光照高"); OLED_ShowChar(48,16,':',OLED_8X16); OLED_ShowNum(56,16,light_G,5,OLED_8X16); OLED_ShowString(96,16,"LX",OLED_8X16); OLED_ShowChinese(0,32,"温度"); OLED_ShowChar(32,32,':',OLED_8X16); OLED_ShowNum(40,32,Temperature_G,2,OLED_8X16); OLED_ShowChar(56,32,'C',OLED_8X16); if(MODE==0) OLED_ShowChinese(96,32,"自动"); else OLED_ShowChinese(96,32,"手动"); if(SetSelect==2&&PAGE==1) { if(setflash==1)OLED_ShowNum(56,16,light_G,5,OLED_8X16); else OLED_ShowString(56,16," ",OLED_8X16); } if(SetSelect==3&&PAGE==1) { if(setflash==1)OLED_ShowNum(40,32,Temperature_G,2,OLED_8X16); else OLED_ShowString(40,32," ",OLED_8X16); } if(SetSelect==1&&PAGE==1) { if(setflash==1)OLED_ShowNum(56,0,light_D,4,OLED_8X16); else OLED_ShowString(56,0," ",OLED_8X16); } } void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判断是否是USART1的接收事件触发的中断 { Receive_Data=USART_ReceiveData(USART1); //语音控制,切换到自动模式 if(Receive_Data==0x10) { Curtain_State=1;MODE=1;PAGE=0; } if(Receive_Data==0x20) { Fan_State=1;MODE=1;PAGE=0; } if(Receive_Data==0x30) { Light_State=1;MODE=1;PAGE=0; } if(Receive_Data==0x40) { Curtain_State=0;MODE=1;PAGE=0; } if(Receive_Data==0x50) { Fan_State=0;MODE=1;PAGE=0; } if(Receive_Data==0x60) { Light_State=0;MODE=1;PAGE=0; } if(Receive_Data==0x70) { MODE=0; } USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除标志位 } } void TIM4_IRQHandler(void) //TIM4中断, { static uint16_t j; if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET) { Key_Tick(); j++; if(j>=500) { j=0; setflash=!setflash; } TIM_ClearITPendingBit(TIM4, TIM_IT_Update); } }
实物图片

资料内容清单
- 完整原理图(PDF或Altium Designer文件)。
- PCB布局文件(如需自制电路板)。
- 源代码工程(Keil MDK项目文件)。
- 传感器数据手册(DHT11、BH1750等)。
- OLED显示屏驱动库(SSD1306)。
- 实物组装说明文档(含接线图)。
- 测试视频或功能演示录屏。

源代码程序电路图pcb讲解视频百度网盘下载链接
https://pan.baidu.com/s/105vX94J7XCBM11PUxzeYWQ?pwd=d82p 提取码: d82p
更多推荐



所有评论(0)