基于STM32的智能家居系统设计
目录第1章前言11.1课题研究的背景和实际意义11.1.1课题背景11.1.2实际意义11.2国内外发展现状、存在问题以及前景21.2.1发展现状21.2.2存在问题21.2.3发展前景21.3主要工作、内容安排及预期成果31.3.1主要研究工作31.3.2预期成果3第2章总体设计方案52.1系统总体方案设计52.2系统方案选择62.2.1无线通讯方案选择62.2.2显示器方案选择6第3章系统硬件设计73.1控制单元模块73.2人机交互模块83.3GPRS电路设计93.4温湿度传感器电路设计103.5光强检测电路设计103.6窗帘控制电路设计113.6.1步进电机的选用113.6.2步进电机28BYJ-48介绍113.6.3步进电机驱动123.7继电器驱动电路设计123.8电源电路设计13第4章系统软件设计154.1软件开发环境介绍154.2软件总体设计154.2.1程序结构分析154.2.2主程序设计154.2.3OLED驱动程序分析174.2.4SIM900通信程序设计17第5章系统调试与结果分析195.1程序仿真设计195.2实物调试20结论22致谢23参考文献241.3主要工作、内容安排及预期成果1.3.1主要研究工作消费者们对于智能家居呈现出一种多样化的迫切性需求,一方面是居住环境的安全性,体现在门窗安全、煤气泄漏及火灾隐患自动报警等要求;另一方面是居住环境的舒适便捷性,体现在无线通信的控制方式、室内灯光以及直观性人机交互操作等方面。在了解到消费者对智能家居实质性需求的基础上,结合本人自身的开发能力,本课题最终确定研究的简易智能家居控制系统涵盖了如下几个模块:传感器模块、控制器模块,GPRS通讯模块,继电器输出控制模块,显示器模块等五大电路模块。本系统主要是侧重点是在远程报警(室内温度异常时,通过GPRS通讯模块向手机发送报警短信)和远程控制(需要时,远程终端通过GPRS通讯模块向本地控制器发送控制指令,控制继电器开闭)方面。除此之外,还有窗帘根据光照强度自动开闭以及本地按键执行中断控制(应用于特殊情况,如自动控制出错时)。1.3.2预期成果通过本系统设计各个模块的搭建,预计能够实现如下功能:1、本地温度湿度报警器实时监测室内情况,当温度异常时发送室内实时数据到设定手机上;测量范围为湿度:2090%RH;温度:050℃。所以本设计使用范围广泛,既可用于气候干燥的北方,也可用于较为湿润的南方;既可适用于工地环境,也可用于婴儿房环境;2、窗帘的自动控制和按键控制(本设计中用电机正反转表示窗帘的开闭),这个功能解决了用户频繁手动打开窗帘的麻烦。日常生活中,当遇到有强光的晴天,本设计的窗帘则能自动关闭,减少用户亲自打开窗帘的麻烦,遇到相反情况则相反处理。此外设计的按键控制窗帘,也可减少用户手拨窗帘的不便;3、手机发送控制指令的短信到GPRS通讯模块,实现继电器的开闭。本设计用两个发光二极管代替所控制的家电,实际应用中,可通过继电器控制空调、电饭煲等家用电器。例如炎炎夏季,空调制冷需要一定时间,用户在回家前提前远程控制空调打开,回家即可享受到冰爽的体验。第2章总体设计方案2.1系统总体方案设计本设计硬件电路结构包含6个部分,分别是STM32控制器、输入部分、输出部分、电源模块、环境探测、SIM900无线通讯。其中控制器选用32位微控制器STM32F103R8T6OLED显示器;输入部分包含按键输入、SMS指令输入;输出部分包含0.96寸12864OLED显示器、继电器输出、窗帘控制输出;环境探测包含一体化温湿度检测模块DHT11、光强检测4线制光敏传感器模块。结构框图如下图1.1所示。
光强检测选用的是光感电阻传感器模块,可输出模拟量(电压)至STM32控制器处理后由OLED显示器显示出当前光照强度,同时输出经比较器LM393比较后输出的开关量(0或1)至STM32来控制窗帘的开关从而控制家居的通光率。在系统接通电源开始运行后,控制器通过串口访问SIM900通讯模块,不断判断是否收到绑定手机发送的短信指令,若接受到有效命令则解析指令控制继电器的开闭,从而达到控制家电开闭的目的。在系统工作过程中,温湿度传感器DHT11不断采集环境的实时温湿度并通过串口送入控制器。设置阈值来判别正常和异常情况,本文转载自http://www.biyezuopin.vip/onews.asp?id=12500当发现异常时触发SIM900模块向设定手机号发送状态信息。此外,系统通过按键扫描的方式实现人机交互,控制器响应按键输入同时控制OLED显示各类相关数据信息。
//头文件调用#include"usually.h"#include"usart.h"#include"oled.h"#include"dht11.h"#include"rtc.h"#include"delay.h"#include"stm32f10x_adc.h"#include#include"BSP_Config.h"#include"gpio.h"#include"gsm.h"//宏定义#defineADC_CH00//通道0#defineADC_CH11//通道1#defineADC_CH22//通道2#defineADC_CH33//通道3#defineSEC0#defineMIN1#defineHOUR2#defineDATE3#defineMON4#defineYEAR6#defineMODE_NORMAL0#defineMODE_SET_HOUR1#defineMODE_SET_MIN2#defineMODE_SET_SEC3#defineMODE_SET_YEAR4#defineMODE_SET_MON5#defineMODE_SET_DATE6#defineMODE_SET_HUMI_HIGH8#defineMODE_SET_TEMP_HIGH7#defineMODE_SET_LIGHT9#defineKEY_MENU_INPBin(0)#defineKEY_ADD_INPBin(1)#defineKEY_SUB_INPBin(2)//步进控制A-AB-B-BC-C-CD-D-DA#defineMotor1_A_run{GPIO_SetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}#defineMotor1_AB_run{GPIO_SetBits(GPIOB,GPIO_Pin_8);GPIO_SetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}#defineMotor1_B_run{GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_SetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}#defineMotor1_BC_run{GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_SetBits(GPIOB,GPIO_Pin_9);GPIO_SetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}#defineMotor1_C_run{GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_SetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}#defineMotor1_CD_run{GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_SetBits(GPIOB,GPIO_Pin_10);GPIO_SetBits(GPIOB,GPIO_Pin_11);}#defineMotor1_D_run{GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_SetBits(GPIOB,GPIO_Pin_11);}#defineMotor1_DA_run{GPIO_SetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_SetBits(GPIOB,GPIO_Pin_11);}#defineMotor1_STOP_run{GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}#definemotorSpdDelayUs1100//声明变量externstructData_Timetimer;unsignedchar*pUart1_Rxd;//接收数据指针unsignedintuart1_RxNum=0;//串口1接收字数unsignedcharNum_TXD=0;//串口1发送缓冲区的字节数unsignedcharUart1_TxBuf[256]={0,2,3,};//串口1发送缓冲区unsignedcharUart1_RxBuf[256];//串口1接收缓冲区unsignedchar*pUart2_Rxd;//串口2接收数据指针unsignedintuart2_RxNum=0;//串口2接收字数unsignedcharuart2_TxNum=0;//串口2发送缓冲区的字节数unsignedcharUart2_TxBuf[256]={0,2,3,};//串口2发送缓冲区unsignedcharUart2_RxBuf[256];//串口2接收缓冲区//变量声明//externstructtmtimer;charline1str[17]="Welcometouse!";charline2str[17]="Watinggsm...";charline3str[17]="";charline4str[17]="";uint8_tdht11_buf[5];uint8_tnowtemp,nowhumi;//当前温湿度值uint8_tthalmflg;//温湿度过高报警uint16_tadtemp[12]={0};//连续采集12点算平均值uint16_tlight_adc,set_lit_high,lit_high;uint8_talmtmp_high,almhumi_high;uint8_tmode_status;//模式uint8_tflashflg;//模式uint8_tsettimeflg;//时间被设置标志位uint8_tsolid1flg,solid2flg,winflg;unsignedcharsettime[8]={0x00,30,12,0x6,10,0x01,15};//??sec,min,hour,date,month,week,yearcharrecephonenum[12]="13538510586";charphonenum_flash;uint8_tadci=0;charstrLs[32];//按键输入初始化voidKey_init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能PB端口时钟//ConfigurepinPb1asoutputGPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//PA13,PA14,PA15按键输入GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入GPIO_Init(GPIOB,&GPIO_InitStructure);}//继电器输出IO初始化voidSolid_Init(){GPIO_InitTypeDefGPIO_InitStructure;//ConfigurepinPb0asoutputGPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure);//ConfigurepinPb1asoutputGPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure);/*GPIO_SetBits(GPIOB,GPIO_Pin_5);GPIO_SetBits(GPIOB,GPIO_Pin_6);GPIO_ResetBits(GPIOB,GPIO_Pin_5);GPIO_ResetBits(GPIOB,GPIO_Pin_6);*/}//步进输出IO初始化voidMotor_Init(){GPIO_InitTypeDefGPIO_InitStructure;//ConfigurepinPb0asoutputGPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure);//ConfigurepinPb1asoutputGPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure);//ConfigurepinPb0asoutputGPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure);//ConfigurepinPb1asoutputGPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure);/*GPIO_SetBits(GPIOB,GPIO_Pin_5);GPIO_SetBits(GPIOB,GPIO_Pin_6);GPIO_ResetBits(GPIOB,GPIO_Pin_5);GPIO_ResetBits(GPIOB,GPIO_Pin_6);*/}//初始化ADC//这里我们仅以规则通道为例//我们默认将开启通道0~3voidAdc_Init(void){//先初始化IO口RCC->APB2ENR|=1APB2ENR|=1