基于STM32的智能家居系统设计

news2024/11/18 13:54:31

目录
第1章 前言 1
1.1 课题研究的背景和实际意义 1
1.1.1课题背景 1
1.1.2实际意义 1
1.2国内外发展现状、存在问题以及前景 2
1.2.1发展现状 2
1.2.2存在问题 2
1.2.3发展前景 2
1.3 主要工作、内容安排及预期成果 3
1.3.1主要研究工作 3
1.3.2预期成果 3
第2章 总体设计方案 5
2.1 系统总体方案设计 5
2.2 系统方案选择 6
2.2.1 无线通讯方案选择 6
2.2.2 显示器方案选择 6
第3章 系统硬件设计 7
3.1 控制单元模块 7
3.2 人机交互模块 8
3.3 GPRS电路设计 9
3.4 温湿度传感器电路设计 10
3.5 光强检测电路设计 10
3.6 窗帘控制电路设计 11
3.6.1 步进电机的选用 11
3.6.2 步进电机28BYJ-48介绍 11
3.6.3 步进电机驱动 12
3.7 继电器驱动电路设计 12
3.8 电源电路设计 13
第4章 系统软件设计 15
4.1 软件开发环境介绍 15
4.2 软件总体设计 15
4.2.1 程序结构分析 15
4.2.2 主程序设计 15
4.2.3 OLED驱动程序分析 17
4.2.4 SIM900通信程序设计 17
第5章 系统调试与结果分析 19
5.1 程序仿真设计 19
5.2 实物调试 20
结论 22
致谢 23
参考文献 24
1.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寸12864 OLED显示器、继电器输出、窗帘控制输出;环境探测包含一体化温湿度检测模块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 <string.h>
#include "BSP_Config.h"
#include "gpio.h"
#include "gsm.h"


//宏定义
#define ADC_CH0  0 //通道0
#define ADC_CH1  1 //通道1
#define ADC_CH2  2 //通道2
#define ADC_CH3  3 //通道3	


#define SEC 0
#define MIN 1
#define HOUR 2
#define DATE 3
#define MON 4
#define YEAR 6

#define MODE_NORMAL 0
#define MODE_SET_HOUR 1
#define MODE_SET_MIN 2
#define MODE_SET_SEC 3
#define MODE_SET_YEAR 4
#define MODE_SET_MON 5
#define MODE_SET_DATE 6
#define MODE_SET_HUMI_HIGH 8
#define MODE_SET_TEMP_HIGH 7
#define MODE_SET_LIGHT 9


#define KEY_MENU_IN PBin(0)
#define KEY_ADD_IN PBin(1)
#define KEY_SUB_IN PBin(2)

//步进控制 A-AB-B-BC-C-CD-D-DA
#define Motor1_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);}
#define Motor1_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);}
#define Motor1_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);}
#define Motor1_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);}
#define Motor1_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);}
#define Motor1_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);}
#define Motor1_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);}
#define Motor1_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);}
#define Motor1_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);}


#define motorSpdDelayUs  1100
//声明变量
extern struct Data_Time  timer;
unsigned char *pUart1_Rxd;//接收数据指针
unsigned int  uart1_RxNum=0;//串口1接收字数
unsigned char Num_TXD=0;//串口1发送缓冲区的字节数
unsigned char Uart1_TxBuf[256]={0,2,3,};//串口1发送缓冲区
unsigned char Uart1_RxBuf[256]; //串口1接收缓冲区

unsigned char *pUart2_Rxd;			//串口2接收数据指针
unsigned int  uart2_RxNum=0;	 //串口2接收字数
unsigned char uart2_TxNum=0;	 //串口2发送缓冲区的字节数
unsigned char Uart2_TxBuf[256]={0,2,3,};//串口2发送缓冲区
unsigned char Uart2_RxBuf[256]; //串口2接收缓冲区

//变量声明
//extern struct tm  timer;
char line1str[17]="Welcome to use!";
char line2str[17]="Wating gsm... ";
char line3str[17]="              ";
char line4str[17]="              ";
uint8_t dht11_buf[5];
uint8_t nowtemp,nowhumi;//当前温湿度值
uint8_t thalmflg;  //温湿度过高报警
uint16_t adtemp[12]={0};  //连续采集12点算平均值
uint16_t light_adc,set_lit_high,lit_high;
uint8_t almtmp_high,almhumi_high;
uint8_t mode_status; //模式
uint8_t flashflg; //模式
uint8_t settimeflg;	//时间被设置标志位
uint8_t solid1flg,solid2flg,winflg;
unsigned char settime[8]={0x00,30,12,0x6,10,0x01,15};//??sec,min,hour,date,month,week,year
char recephonenum[12]="13538510586";
char phonenum_flash;
uint8_t adci=0;
char strLs[32];
//按键输入初始化
void Key_init(void){
	
  GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PB端口时钟
	//Configure pin Pb1 as output 
	GPIO_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初始化
void Solid_Init(){
	
  GPIO_InitTypeDef  GPIO_InitStructure;
	//Configure pin Pb0 as output 
	GPIO_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);

	//Configure pin Pb1 as output 
	GPIO_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初始化
void Motor_Init(){
	
  GPIO_InitTypeDef  GPIO_InitStructure;
	//Configure pin Pb0 as output 
	GPIO_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);

	//Configure pin Pb1 as output 
	GPIO_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);
		//Configure pin Pb0 as output 
	GPIO_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);

	//Configure pin Pb1 as output 
	GPIO_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~3																	   
void  Adc_Init(void)
{    
	//先初始化IO口
 	RCC->APB2ENR|=1<<2;    //使能PORTA口时钟 
	GPIOA->CRL&=0XFFFF0000;//PA0 1 2 3 anolog输入
	//通道10/11设置			 
	RCC->APB2ENR|=1<<9;    //ADC1时钟使能	  
	RCC->APB2RSTR|=1<<9;   //ADC1复位
	RCC->APB2RSTR&=~(1<<9);//复位结束	    
	RCC->CFGR&=~(3<<14);   //分频因子清零	
	//SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
	//否则将导致ADC准确度下降! 
	RCC->CFGR|=2<<14;      	 

	ADC1->CR1&=0XF0FFFF;   //工作模式清零
	ADC1->CR1|=0<<16;      //独立工作模式  
	ADC1->CR1&=~(1<<8);    //非扫描模式	  
	ADC1->CR2&=~(1<<1);    //单次转换模式
	ADC1->CR2&=~(7<<17);	   
	ADC1->CR2|=7<<17;	   //软件控制转换  
	ADC1->CR2|=1<<20;      //使用用外部触发(SWSTART)!!!	必须使用一个事件来触发
	ADC1->CR2&=~(1<<11);   //右对齐	 
	ADC1->SQR1&=~(0XF<<20);
	ADC1->SQR1&=0<<20;     //1个转换在规则序列中 也就是只转换规则序列1 			   
	//设置通道0~3的采样时间
	ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3采样时间清空	  
	ADC1->SMPR2|=7<<9;      //通道3  239.5周期,提高采样时间可以提高精确度	 
	ADC1->SMPR2|=7<<6;      //通道2  239.5周期,提高采样时间可以提高精确度	 
	ADC1->SMPR2|=7<<3;      //通道1  239.5周期,提高采样时间可以提高精确度	 
	ADC1->SMPR2|=7<<0;      //通道0  239.5周期,提高采样时间可以提高精确度	 

	ADC1->CR2|=1<<0;	    //开启AD转换器	 
	ADC1->CR2|=1<<3;        //使能复位校准  
	while(ADC1->CR2&1<<3);  //等待校准结束 			 
    //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。 		 
	ADC1->CR2|=1<<2;        //开启AD校准	   
	while(ADC1->CR2&1<<2);  //等待校准结束
	//该位由软件设置以开始校准,并在校准结束时由硬件清除  
}				  
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{
	//设置转换序列	  		 
	ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch
	ADC1->SQR3|=ch;		  			    
	ADC1->CR2|=1<<22;       //启动规则转换通道 
	while(!(ADC1->SR&1<<1));//等待转换结束	 	   
	return ADC1->DR;		//返回adc值	
}


//
uint16_t adc_avg(void)
{
  uint8_t i;
	uint32_t sum=0;
	uint16_t ret=0;
	for(i=0;i<12;i++)  sum+=adtemp[i];
	ret= sum/12;
	
	return ret;  
}
//马达正转开窗帘
void motor_Foreward(void)
{
    Motor1_A_run;
    delay_us(motorSpdDelayUs);
    Motor1_AB_run;
    delay_us(motorSpdDelayUs);
    Motor1_B_run;
    delay_us(motorSpdDelayUs);
    Motor1_BC_run;
    delay_us(motorSpdDelayUs);
    Motor1_C_run;
    delay_us(motorSpdDelayUs);
    Motor1_CD_run;
    delay_us(motorSpdDelayUs);
    Motor1_D_run;
    delay_us(motorSpdDelayUs);
    Motor1_DA_run;
    delay_us(motorSpdDelayUs);
}


//马达反转关窗帘
void motor_Backward(void)
{
    Motor1_DA_run;
    delay_us(motorSpdDelayUs);   
    Motor1_D_run; 
    delay_us(motorSpdDelayUs);
    Motor1_CD_run;
    delay_us(motorSpdDelayUs);
    Motor1_C_run; 
    delay_us(motorSpdDelayUs);
    Motor1_BC_run;
    delay_us(motorSpdDelayUs);
    Motor1_B_run;
    delay_us(motorSpdDelayUs);
    Motor1_AB_run;
    delay_us(motorSpdDelayUs);
    Motor1_A_run;
    delay_us(motorSpdDelayUs);   
}



//显示设置页面
void Show_Normal(void){
	//显示温湿度
	strncpy(line1str,"tmp:99C/hm:99%RH",16);
	line1str[4]=0x30+nowtemp/10;
	line1str[5]=0x30+nowtemp%10;
	line1str[11]=0x30+nowhumi/10;
	line1str[12]=0x30+nowhumi%10;
	OLED_8x16Str(0,0,line1str);	
	//显示光照强度及窗帘状态
	if(winflg){
	  strncpy(line2str,"lit:99 /wn:open ",16);
	}else{
		strncpy(line2str,"lit:99 /wn:close",16);
  }
	line2str[4]=0x30+light_adc/41/10; //100%显示
	line2str[5]=0x30+light_adc/41%10;
	OLED_8x16Str(0,2,line2str);	
	
	//显示继电器输出状态
	strncpy(line3str, "s1:open s2:open ",16);
	if(solid1flg) {
	  line3str[3]='o';line3str[4]='p';line3str[5]='e';line3str[6]='n';line3str[7]=' ';
  }else{
	  line3str[3]='c';line3str[4]='l';line3str[5]='o';line3str[6]='s';line3str[7]='e';
  }
	if(solid2flg) {
	  line3str[11]='o';line3str[12]='p';line3str[13]='e';line3str[14]='n';line3str[15]=' ';
  }else{
	  line3str[11]='c';line3str[12]='l';line3str[13]='o';line3str[14]='s';line3str[15]='e';
  }	
	
	OLED_8x16Str(0,4,line3str);
	
	//显示时间
	//line4str[0]= 0x30+ timer.w_year%1000%100/10;	
	line4str[0]= 0x30+ timer.w_year%1000%100%10;	
	line4str[1]= '/';
	line4str[2]= 0x30+timer.w_month/10;	
	line4str[3]= 0x30+ timer.w_month%10;	
	line4str[4]= '/';	
	line4str[5]= 0x30+timer.w_date/10;	
	line4str[6]= 0x30+ timer.w_date%10;	
	line4str[7]= ' ';		
	line4str[8]= 0x30+ timer.hour/10;	
	line4str[9]= 0x30+ timer.hour%10;	
	line4str[10]= ':';
	line4str[11]= 0x30+timer.min/10;	
	line4str[12]= 0x30+ timer.min%10;	
	line4str[13]= ':';	
	line4str[14]= 0x30+timer.sec/10;	
	line4str[15]= 0x30+timer.sec%10;	
	OLED_8x16Str(0,6,line4str);

}
/*
   显示设置页面

*/
void Show_SetPage(void){
	uint8_t i;
	//显示温湿度
	strncpy(line1str,"tH:99C/hH:99%RH ",16);
	
	if(MODE_SET_TEMP_HIGH== mode_status && flashflg){
		line1str[3]=' ';
		line1str[4]=' ';
	}else{
		line1str[3]=0x30+almtmp_high/10;
		line1str[4]=0x30+almtmp_high%10;
  }
	if(MODE_SET_HUMI_HIGH== mode_status && flashflg){
		line1str[10]=' ';
		line1str[11]=' ';
  }else{
		line1str[10]=0x30+almhumi_high/10;
		line1str[11]=0x30+almhumi_high%10;
	}
	OLED_8x16Str(0,0,line1str);	
	
	//设置光强度
	strncpy(line2str,"litH:99 15/04/25",16);
	
	if(MODE_SET_LIGHT== mode_status && flashflg){
	  line2str[5]=' '; //100%显示
	  line2str[6]=' ';

  }else{
	  line2str[5]=0x30+set_lit_high/10; //100%显示
	  line2str[6]=0x30+set_lit_high%10;
	}
	if(MODE_SET_YEAR== mode_status && flashflg){
	  line2str[8]=' '; //100%显示
	  line2str[9]=' ';

  }else{
	  line2str[8]=0x30+settime[YEAR]/10; //100%显示
	  line2str[9]=0x30+settime[YEAR]%10;
	}	
	
	if(MODE_SET_MON== mode_status && flashflg){
	  line2str[11]=' '; //100%显示
	  line2str[12]=' ';

  }else{
	  line2str[11]=0x30+settime[MON]/10; //100%显示
	  line2str[12]=0x30+settime[MON]%10;
	}		
	
	if(MODE_SET_DATE== mode_status && flashflg){
	  line2str[14]=' '; //100%显示
	  line2str[15]=' ';

  }else{
	  line2str[14]=0x30+settime[DATE]/10; //100%显示
	  line2str[15]=0x30+settime[DATE]%10;
	}	
	OLED_8x16Str(0,2,line2str);	
	

	//设置时间
	strncpy(line3str," 10/59/00       ",16);
	
	if(MODE_SET_HOUR== mode_status && flashflg){
	  line3str[1]=' '; //100%显示
	  line3str[2]=' ';

  }else{
	  line3str[1]=0x30+settime[HOUR]/10; //100%显示
	  line3str[2]=0x30+settime[HOUR]%10;
	}
	if(MODE_SET_MIN== mode_status && flashflg){
	  line3str[4]=' '; //100%显示
	  line3str[5]=' ';

  }else{
	  line3str[4]=0x30+settime[MIN]/10; //100%显示
	  line3str[5]=0x30+settime[MIN]%10;
	}	
	
	if(MODE_SET_SEC== mode_status && flashflg){
	  line3str[7]=' '; //100%显示
	  line3str[8]=' ';

  }else{
	  line3str[7]=0x30+settime[SEC]/10; //100%显示
	  line3str[8]=0x30+settime[SEC]%10;
	}		
	OLED_8x16Str(0,4,line3str);
	
	//显示手机
	strncpy(line4str,"NO:13538510586   ",16);
	for(i=3;i<14;i++){
    line4str[i]=  recephonenum[i-3];
  }
	OLED_8x16Str(0,6,line4str);
}



/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
int main(void)
{
	uint8_t check,flashi,t,posi;
	uint16_t adcx,motori,tt;
	u32 i=0,xx;
	SystemInit();					//系统时钟配置
	OLED_Init();					  //初始化OLED  
  NVIC_Configuration();		//初始化中断向量
	Init_RTC();							//内部RTC初始化
	Adc_Init();							//adc 初始化
	Usart1_Configuration(9600);	//串口配置 设置波特率9600
	USART2_Config(9600);
	Key_init();							//按键初始化输入
  OLED_8x16Str(0,0,line1str);
	OLED_8x16Str(0,2,line2str);
  OLED_8x16Str(0,4,line3str);
	OLED_8x16Str(0,6,line4str);	

	Motor_Init();						//马达控制IO初始化
	
	Uart1_ClrBuf();
  while(0==Sim_Send_AT())   delay_ms(1000);		//??SIM ???? ,SIM900?????
  Sim_Set_MODE(1);
  delay_ms(800);
  Sim_ReSms_Config();
  delay_ms(800);
  Sim_Sms_Config_Cscs();
	Solid_Init(); 					//继电器IO配置输出
	Uart2_ClrBuf();
	Uart1_ClrBuf();

	set_lit_high=85;
  almtmp_high=40;
  almhumi_high=60;
	
	mode_status=0;
	//RTC_Set(2015,4,25,20,35,00);
	adci=0;
	while(1)													
	{
	  if(KEY_MENU_IN==0){        
				delay_ms(5);
			  if(KEY_MENU_IN==0){
          mode_status++; //
		      if(mode_status>9) mode_status=0;		
					if( settimeflg){
						settimeflg=0;
						Time_Update(settime[YEAR]+2000,settime[MON],settime[DATE],settime[HOUR],settime[MIN],settime[SEC]);
					}
				}
        while(KEY_MENU_IN==0) ;			//等待放键
	  }	
	  if(KEY_ADD_IN==0){    //加键
			delay_ms(5);
			if(KEY_ADD_IN==0){
			  switch(mode_status ){ //
         case MODE_SET_HOUR:   
					 if(settime[HOUR]<24)  settime[HOUR]++;
					 else							settime[HOUR]=0;
					 settimeflg=1;
				 break;
         case MODE_SET_MIN:   
					 if(settime[MIN]<60)  settime[MIN]++;
					 else							settime[MIN]=0;
					 settimeflg=1;
				 break;				 
         case MODE_SET_SEC:   
					 if(settime[MIN]<60)  settime[SEC]++;
					 else							settime[SEC]=0;
					 settimeflg=1;
				 break;		
         case MODE_SET_YEAR:   
					 if(settime[YEAR]<99)  settime[YEAR]++;
					 else							settime[YEAR]=0;
					 settimeflg=1;
				 break;		
         case MODE_SET_MON:   
					 if(settime[MON]<12)  settime[MON]++;
					 else							settime[MON]=0;
					 settimeflg=1;
				 break;		
         case MODE_SET_DATE:   
					 if(settime[DATE]<31)  settime[DATE]++;
					 else							settime[DATE]=0;
					 settimeflg=1;
				 break;
         case MODE_SET_TEMP_HIGH:   
					 if(almtmp_high<99)  almtmp_high++;
					 else							almtmp_high=0;
				 break;
         case MODE_SET_HUMI_HIGH :   
					 if(almhumi_high<99)  almhumi_high++;
					 else							almhumi_high=0;
				 break;	
         case MODE_SET_LIGHT :   
					 if(set_lit_high<99)  set_lit_high++;
					 else							set_lit_high=0;
				 break;					 
			  } 
			}				
      while(KEY_ADD_IN==0) ;			
	}
	if(KEY_SUB_IN==0){    
      delay_ms(5);  
			if(KEY_SUB_IN==0){	
			  switch(mode_status ){ //
         case MODE_SET_HOUR:   
					 if(settime[HOUR]>0)  settime[HOUR]--;
					 else							settime[HOUR]=0;
					 settimeflg=1;
				 break;
         case MODE_SET_MIN:   
					 if(settime[MIN]>0)  settime[MIN]--;
					 else							settime[MIN]=0;
					 settimeflg=1;
				 break;				 
         case MODE_SET_SEC:   
					 if(settime[MIN]>0)  settime[SEC]--;
					 else							settime[SEC]=0;
					 settimeflg=1;
				 break;		
         case MODE_SET_YEAR:   
					 if(settime[YEAR]>0)  settime[YEAR]--;
					 else				 settime[YEAR]=0;
					 settimeflg=1;
				 break;		
         case MODE_SET_MON:   
					 if(settime[MON]>0)  settime[MON]--;
					 else							settime[MON]=0;
					 settimeflg=1;
				 break;		
         case MODE_SET_DATE:   
					 if(settime[DATE]>0)  settime[DATE]--;
					 else							settime[DATE]=0;
					 settimeflg=1;
				 break;
         case MODE_SET_TEMP_HIGH:   
					 if(almtmp_high>0)  almtmp_high--;
					 else							almtmp_high=0;
				 break;
         case MODE_SET_HUMI_HIGH :   
					 if(almhumi_high>0)  almhumi_high--;
					 else							almhumi_high=0;
				 break;			 	
         case MODE_SET_LIGHT :   
					 if(set_lit_high>0)  set_lit_high--;
					 else							set_lit_high=0;
				 break;						 
			 } 	
		 }				
     while(KEY_SUB_IN==0) ;			
}	


switch(mode_status){  ///不同状态显示不同页面
  	
			case MODE_NORMAL:				
		
			dht11_readdata(dht11_buf);
			check= dht11_buf[0]+ dht11_buf[1]+ dht11_buf[2]+ dht11_buf[3];
			if(dht11_buf[4]==check){

				nowhumi = dht11_buf[0];
				nowtemp = dht11_buf[2];
				thalmflg =0;
				if(nowtemp> almtmp_high) thalmflg=1;
				if(nowhumi> almhumi_high) thalmflg=1;
			
				if (thalmflg){  //触发短息发送
						tt++;
					  if(tt>300){
							strncpy(strLs,"Alarm Temp:99 oC, Humi:99 %RH",29);
					    strLs[11]=0x30+nowtemp/10;
							strLs[12]=0x30+nowtemp%10;
							strLs[23]=0x30+nowhumi/10;
							strLs[24]=0x30+nowhumi%10;
							OLED_8x16Str(0,2,"Sending msg.... ");	
							delay_ms(1000);
							Sim_Send_Text(recephonenum,strLs);
							tt=0;
						}
					
				}		
			}	
			
				adtemp[adci]=Get_Adc(ADC_CH0);
				adci++;		
				if(	adci>11) {
					adci=0;
					light_adc = adc_avg();
					if(light_adc >  set_lit_high*41) {//光照充足关闭窗帘
            if(winflg==1){
							  motori=800;
                while(motori--) { motor_Backward();}
								Motor1_STOP_run;
						}
						winflg=0;}	
				  else	{
						if(winflg==0){
							  motori=800;
                while(motori--) { motor_Foreward();}
								Motor1_STOP_run;
						}
						winflg=1;   //打开窗帘
					}
				}	

				if(t!=timer.sec)
				{
					t=timer.sec; 
					//printf("%d年%d月%d日%d点%d分%d秒\r\n",timer.w_year,timer.w_month,timer.w_date,timer.hour,timer.min,timer.sec);		
				}	
				Show_Normal();
				memset(strLs,0,sizeof(strLs));
				strLs[0]=0x3a;
				strLs[1]=nowtemp/10+0x30;
				strLs[2]=nowtemp%10+0x30;				
				strLs[3]=nowhumi/10+0x30;
				strLs[4]=nowtemp%10+0x30;				
				strLs[5]=0x30+light_adc/41/10;	
				strLs[6]=0x30+light_adc/41%10;		
				strLs[7]=timer.w_year%1000%100/10+0x30;
				strLs[8]=timer.w_year%1000%100%10+0x30;
				strLs[9]=timer.w_month/10+0x30;			
				strLs[10]=timer.w_month%10+0x30;		
				strLs[11]=timer.w_date/10+0x30;			
				strLs[12]=timer.w_date%10+0x30;			
				if(solid1flg) strLs[14]=1+0x30;			
				else					strLs[14]=0+0x30;		
				if(solid2flg) strLs[15]=1+0x30;			
				else					strLs[15]=0+0x30;	
				if(winflg) 		strLs[16]=1+0x30;			
				else					strLs[16]=0+0x30;			
				
				for(i=0;i<17;i++) USART2_Senddata(strLs[i]);
		   break;

	    case MODE_SET_HOUR:
			case MODE_SET_MIN:
			case MODE_SET_SEC:
		  case MODE_SET_YEAR: 
			case MODE_SET_MON:
			case MODE_SET_DATE:	
			case MODE_SET_HUMI_HIGH:
			case MODE_SET_TEMP_HIGH:		
			case MODE_SET_LIGHT:		
				flashi++;
				if(flashi>2){
					flashflg=~flashflg;
					flashi=0;
				}			
				Show_SetPage();

			 break;
			 default:
					break;

		}	
		 
		
		if(mystrstr(Uart1_RxBuf,"+CMTI:")!= NULL ){  //接收到手机短息
			delay_ms(300);
			OLED_8x16Str(0,2,"Receing msg.... ");	
		  Uart1_ClrBuf();
			delay_ms(1000);		
	    USART1_SendString("AT+CMGR=1\r\n"); //??????
		
			while(Uart1_RxBuf[0]==0);					//等级待接收
			delay_ms(1000);				//set 1lu: 
			delay_ms(1000);				//set 1lu: 
			delay_ms(1000);				//set 1lu: 
			if( mystrstr(Uart1_RxBuf,"1 Close")!= NULL ){
				GPIO_ResetBits(GPIOB,GPIO_Pin_5);  //关闭1路继电器输出
				solid1flg=0;
			}
			if( mystrstr(Uart1_RxBuf,"1 Open")!= NULL ){
				GPIO_SetBits(GPIOB,GPIO_Pin_5);  //关闭1路继电器输出
				solid1flg=1;
			}
			if( mystrstr(Uart1_RxBuf,"2 Close")!= NULL ){
				GPIO_ResetBits(GPIOB,GPIO_Pin_6);  //关闭2路继电器输出
				solid2flg=0;
			}
			if( mystrstr(Uart1_RxBuf,"2 Open")!= NULL ){
				GPIO_SetBits(GPIOB,GPIO_Pin_6);  //打开2路继电器输出
				solid2flg=1;
			}
			Sim_delt_Sms();		//删除短信
			delay_ms(2000);		  
			Uart1_ClrBuf();		
		}	

		if( mystrstr(Uart2_RxBuf,"num")!=NULL ){

			//USART2_SendString(Uart2_RxBuf);
			posi =0;
			for(i=0;i<255;i++){
         if(Uart2_RxBuf[i]==0x3a) {posi=i+1; break;}
      }
			if(posi){
       
					for(i=0;i<11;i++) recephonenum[i]=Uart2_RxBuf[posi+i]; //更新手机号
      }
			Uart2_ClrBuf();
    }
		
    delay_ms(100);
	}
}

/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Init_NVIC
** 功能描述: 系统中断配置
** 参数描述:无
** 作   者: Dream
** 日   期: 2011年5月14日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Init_NVIC(void)
{ 	
  	NVIC_InitTypeDef NVIC_InitStructure;			//定义一个NVIC向量表结构体变量

	#ifdef  VECT_TAB_RAM  							//向量表基地址选择

	  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);  	//将0x20000000地址作为向量表基地址(RAM)
	#else  

	  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); //将0x08000000地址作为向量表基地址(FLASH)  
	#endif

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//设置中断组 为2 

	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;			//配置串口1为中断源
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; 	//设置占先优先级为2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		  	//设置副优先级为0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			  	//使能串口1中断
	NVIC_Init(&NVIC_InitStructure);							  	//根据参数初始化中断寄存器
}



在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安卓4.X版本ssl: sslv3 alert handshake failure 握手失败

低版本https握手失败错误查看接口的协议改写代码&#xff08;网络访问采用原生的HttpsURLConnection&#xff09;参考博文&#xff1a;https://www.cnblogs.com/lwbqqyumidi/p/12063489.htmlhttps://blog.csdn.net/qq_16117167/article/details/52621112错误 如图所示&#xf…

linux进程概念

目录 1、进程的基本概念 2、进程控制块 - PCB task_struct内容分类 3、查看进程 通过ps命令查看进程 通过proc查看进程 4、通过系统调用获取进程标示符 5、通过系统调用创建进程-fork初识 6、进程状态 操作系统进程状态 linux进程状态 僵尸进程 孤儿进程 僵尸进…

计算机网络-谢希仁-第7版 第1章 概述

计算机网络-谢希仁-第7版 第1章 概述1.011.021.031.071.081.091.101.111.121.131.141.161.171.181.191.201.211.221.241.251.26计算机网络谢希仁版&#xff08;第七版&#xff09;答案 1.01 计算机网络可以向用户提供哪些服务&#xff1f; 计算机网络使用户在计算机之间传送数…

【Linux】Linux下的编译器——gcc/g++

&#x1f4ac;推荐一款模拟面试、刷题神器 、从基础到大厂面试题&#xff1a;&#x1f449;点击跳转刷题网站进行注册学习 目录 一、编译的过程 1、预处理阶段 1.1预处理的工作——头文件展开、去注释、宏替换、条件编译 1.2外部定义宏&#xff08;-D选项&#xff09; 1.…

会话跟踪技术(Cookie、Session)

目录一、CookieCookie的基本使用发送Cookie获取CookieCookie原理Cookie使用细节二、SessionSession基本使用Session原理Session使用细节三、小结四、登录注册案例会话&#xff1a;用户打开浏览器&#xff0c;访问Web服务器的资源&#xff0c;会话建立&#xff0c;直到有一方断开…

数据结构之堆的应用

系列文章目录 数据结构之堆_crazy_xieyi的博客-CSDN博客 文章目录 前言一、Top-k问题 1.前K个最小数&#xff08;第k个最小数&#xff09; 2.前K个最大数&#xff08;第K个最大数&#xff09;二、堆排序 1.从小到大排序&#xff08;建大根堆&#xff09;2.从大到…

【2022研电赛】安谋科技企业命题一等奖:基于EAIDK-610的中国象棋机器人对弈系统

本文为2022年第十七届中国研究生电子设计竞赛安谋科技企业命题一等奖作品分享&#xff0c;参加极术社区的【有奖活动】分享2022研电赛作品扩大影响力&#xff0c;更有丰富电子礼品等你来领&#xff01; 基于EAIDK-610的中国象棋机器人对弈系统 参赛单位&#xff1a;西安邮电大学…

硬件开发趋势与技术探索

LiveVideoStackCon 2022 音视频技术大会 北京站将于11月25日至26日在北京丽亭华苑酒店召开&#xff0c;本次大会将延续【音视频无限可能】的主题&#xff0c;邀请业内众多企业及专家学者&#xff0c;将他们在过去一年乃至更长时间里对音视频在更多领域和场景下应用的探索、在实…

2023届C/C++软件开发工程师校招面试常问知识点复盘Part 8

目录52、vector<string>是怎么存储的&#xff1f;53、epoll的底层原理53.1 对比select和poll53.2 ET和LT的工作模式54、进程、线程、协程的理解和他们的通信方式54.1 进程的含义54.2 线程的含义54.3 协程的含义54.4 进程间通信IPC54.5 线程间通信方式55、define宏定义的用…

【JavaDS】优先级队列(PriorityQueue),堆,Top-k问题

✨博客主页: 心荣~ ✨系列专栏:【Java实现数据结构】 ✨一句短话: 难在坚持,贵在坚持,成在坚持! 文章目录一. 堆1. 堆的概念2. 堆的存储方式3. 堆的创建4. 元素入堆5. 元素出堆6. 获取堆中元素二. 优先级堆列(PriorityQueue)1. 优先级队列2. PriorityQueue的特性3. 集合框架中P…

万字启程——零基础~前端工程师_养成之路001篇

目录 什么是前端 什么是后端 前端和后端的区别 前端工程师职责 后端工程师职责 前端的核心技术 HTML CSS JavaScript RESTful结构 特点 HTTP请求方式有哪些 目前最火的前端框架Vue vue优点 vue的响应式编程、组件化 搭建编程环境 什么是编程环境 前端的编程环…

华为云CDN,海量资源智能路由,让内容传输更快一步

华为云CDN,海量资源智能路由,让内容传输更快一步 云服务对于我们生活的影响已经愈发深入&#xff0c;在数字化转型的大背景下&#xff0c;城市管理、公共交通、医疗健康等领域都需要云服务的支持。华为云作为国内知名的云服务平台&#xff0c;以技术强、更可靠、资源多以及帮肋…

基于CentOS 7.9操作系统应用httpd配置本地镜像(本地yum源)

记录&#xff1a;301 场景&#xff1a;配置离线本地镜像源(本地yum源)的三种方式&#xff1a;直接使用iso镜像包配置、使用httpd服务应用iso镜像包配置、使用httpd服务应用rpm包配置。在内网环境或者局域网环境&#xff0c;基于CentOS 7.9操作系统应用httpd配置本地镜像(本地y…

手把手带你玩转Spark机器学习-深度学习在Spark上的应用

系列文章目录 手把手带你玩转Spark机器学习-专栏介绍手把手带你玩转Spark机器学习-问题汇总手把手带你玩转Spark机器学习-Spark的安装及使用手把手带你玩转Spark机器学习-使用Spark进行数据处理和数据转换手把手带你玩转Spark机器学习-使用Spark构建分类模型手把手带你玩转Spa…

Python学习笔记(十三)——编译错误和异常处理

异常和异常类 Python常见错误 语法错误 源代码存在拼写语法错 误&#xff0c;这些错误导致Python 编译器无法把Python源代 码转换为字节码&#xff0c;故也称 之为编译错误。>>> print("我爱山大"} SyntaxError: invalid syntax 运行时错误 • 程序中没有…

Python常用库1:collections,容器数据类型

collections&#xff1a;数据容器 点这里跳到原文地址。预计阅读时长&#xff1a;10分钟未完待续&#xff0c;遇到相关力扣题目&#xff0c;会继续补充~ 文章目录前言一、Collections中的内置函数二、各个函数的使用1. deque1.1 deque的介绍1.2 deque支持的方法1.3 使用deque解…

js-键盘事件

onkeydown:按键被按下 onkeyup:按键被松开 事件绑定的对象&#xff1a;键盘事件一般绑定给可以获取焦点的对象或者document对象 焦点&#xff1a;光标在闪的&#xff1a;比如input标签 如果一直按按键不松手&#xff0c;按键会一直被触发 当&#xff1a;onkeydown连续触发时…

THREE.JS实现看房自由(VR看房)

VR看房一、前言二、基础知识三、场景3.1 网络模型3.2 光照3.2.1 环境光3.2.2 平行光3.2.3 点光源3.2.4 聚光灯3.2.5 半球光四、相机4.1 正交相机4.2 透视相机五、渲染器六、贴图纹理6.1 基础介绍6.2 环境贴图6.3 HDR处理七、拓展7.1 坐标系7.2 控制器7.3 自适应7.4 全屏响应7.5…

C#基础·补丁

文章目录一 命名空间二字符串2.1 System.String类2.2 StringBuilder类三 正则表达式3.1 什么是正则表达式&#xff1f;3.2 查找举例3.3 重复描述字符举例3.4 反义字符3.5 基本语法元字符3.6 定位元字符3.7 择一匹配3.8 分组一 命名空间 二字符串 字符串类 System.String(strin…

python数据分析之numpy

数据分析之Numpy 1、Numpy的数组对象及其索引 import numpy as npimport numpy as npanp.array([1,2,3,4]) print(a) bnp.array([2,3,4,5]) print(b)print(ab)产生数组 从列表产生数组&#xff1a; list_array[1,2,3,4] anp.array(list_array) print(a)从列表传入&#xff…