家居智能灯光窗帘控制器的设计与制作

作者主页:编程千纸鹤

作者简介:Java、前端、Python开发多年,做过高程,项目经理,架构师

主要内容:Java项目开发、Python项目开发、大学数据和AI项目开发、单片机项目设计、面试技术整理、最新技术分享

收藏点赞不迷路  关注作者有好处

文末获得源码

 项目编号:BS-DPJ-007

一,环境介绍

语言环境:c

开发工具:51单片机

二,项目简介

在20世纪,自动控制技术得到了迅速的发展和广泛的影响。当今社会,无论是在科技、生产、军事、管理还是生活等方面,都与自动控制技术密不可分。从定义上来说,自动控制技术属于控制论的技术实现应用,它是通过具有一定控制功能的自动控制系统,来完成某种控制任务,保证某个过程能够按照预期进行,或者实现某个预定的目标。随着电子计算机等高科技的不断进步,自动化程度不断提高,应用范围不断扩大,功能也不断增强。它在工业自动化,机器人技术,综合管理,航空航天,军事技术等方面发挥着举足轻重的作用。因此,对智能家庭来说,自动化控制是一种很有前途的技术。采用自控技术,使家居环境变得更智能、更人性化。

为了解决家居环境中的照明、避光和雨水等问题,我们推出了一种更具人性化的自动窗帘控制系统。文章对自动窗帘系统的设计和控制系统进行了总结,并对设计和制造一个完整的自动窗帘控制系统所需进行的理论分析和各个环节的功能实现进行了阐述。自动窗帘控制系统的核心是使用的单片机STC89C52控制,其次使用了雨水感应电路,感光检测电路,灯光电路,时钟电路,电机控制电路、按键电路等外围电路。通过各个模块之间的相互协作,使整个系统达到了半自动化、自动化的目的。在理论层次上,通过程序来驱动各个模块的工作,使各个模块之间相互关联;在应用层次上,通过软件来完成结构图的设计与模拟。

自动窗帘系统的硬件电路,主要包括了雨水感应电路,感光检测电路,灯光电路,时钟电路,电机控制电路,按键电路等外围电路。在此基础上,详细介绍了窗帘自动控制系统的总体设计流程、硬件电路的设计和软件的调试。该系统可根据灯光强弱,实现对窗帘开关的各种控制,如自动控制、人工控制等。

本文是以单片机为基础,设计与制作了以单片机为基础的家庭智能灯光窗帘控制器,系统包括了单片机最小系统、按键模块、温度检测模块、时钟模块、雨滴检测模块、显示模块、报警模块、窗帘控制电机模块、灯光模块。本论文的主要研究内容包括:

(1)搜集和研读文献:在阅读了大量关于家庭智能灯光窗帘控制系统的相关文献后,介绍了本课题的研究背景和意义,并在此基础上进行了归纳和归纳,最终形成了目前国内外的研究状况。

(2)系统的总体方案设计,通过对有关文献的综述和研究,设计出家居智能灯光窗帘控制系统的总体方案,明确了系统的各构成模块和功能,并对设计方案进行了优选和确认。

(3)元件选型:根据总体设计方案,对规划各模块所需的电子元件进行分类,并对元件的型号进行选取和决定。

(4)系统硬件设计:在确定了设计家居智能灯光窗帘控制系统所需要的元件型号后,仔细研究了各元件的各管脚的功能,并根据这些元件的特点,进行了系统硬件电路的设计。

(5)系统软件的设计:在确定了系统所需的功能后,用 C语言设计了系统的软件程序。

(6)实物调试:在基础工作结束后,对实物设备进行焊接和调试,并对各种功能进行测试,并对结果做出解释。

(7)总结:论文的结尾部分,总结了本系统的工作流程,并提出了本系统的不足之处,为下一步的工作提出了建议。

三,系统展示

主程序流程图

OLED12864显示流程

湿度检测流程

雨滴检测流程

四,核心代码展示

#include "reg52.h"	//头文件
#include "stdio.h"  
#include "string.h" 
#include "picture.h"
 
/***************************接口定义*********************************/
 
#define uchar unsigned char 
#define uint  unsigned int

typedef unsigned char  u8;
typedef unsigned int   u16;
 
#define high 1
#define low 0 

u8 kx,ky;
u8 code keyvalue[4][4]={"123a",	  //矩阵键盘数值定义
						"456b",
						"789c",
						"*0#d"};


sbit Cs0832 = P1^0;		 //adc0832接口
sbit Di0832 = P1^2;
sbit Do0832 = P1^2;
sbit Clk0832 = P1^1;

sbit YD = P0^1;	   //雨滴传感器
 
sbit SCL=P0^6;	  //液晶接口
sbit SDA=P0^7;

sbit P10 = P3^2;	//步进电机接口
sbit P11 = P3^3;
sbit P12 = P3^4;
sbit P13 = P3^5;

bit Flag4X4=0;
unsigned char Flagkey=16;

 
/******************************/ 

/******************************/  

sbit dht11 = P0^0;
//防止在与硬件通信时发生死循环的计数范围
#define NUMBER 20
#define SIZE 5
static unsigned char status;
//存放五字节数据的数组
static unsigned char value_array[SIZE];
 
#define OK 1
#define ERROR 0
 
 
 
/********************************数据定义************************************/
 
unsigned int  Time_10ms;
unsigned int  Time_1ms;
unsigned int Chan0Value=0;	   //光照
unsigned char RxBuf[10];
unsigned char Hour=8;	 //实时时间
unsigned char Min=0;
unsigned char Sec=0;
unsigned char Hour1=14;	 //定时开始时间
unsigned char Min1=0;
unsigned char Hour2=17;	  //定时结束时间
unsigned char Min2=30;
bit FlagUpData=0;
unsigned char FlagBJ=0;
unsigned char FlagState=0;	  
unsigned char FlagModel=0;	  //模式 0手动 1自动 2定时
unsigned char FlagSet=0;	  //设置参数标志位
unsigned char PassWord[4]; 
unsigned char FlagGo=0;
unsigned char FlagYD=0;
int temp_value, humi_value;	 //温湿度
int temp_value1, humi_value1;
unsigned char AlarmH = 60;
unsigned char AlarmG = 40;
  
//  
void Uart_init()
{
   
	TMOD= 0X21;		//T1  方式2  ,8位   自动重装   
	TH1=0Xfd;
	TL1=0Xfd;	    //2400
	TR1=1; 		    // 定时器1启动  
	SM0=0;	    // 设置串口的工作模式
	SM1=1; 	    //方式1
	REN=1; 		 // 允许串口接收数据 	 
	ES=1; 	     // 串口中断应许 
	EA=1;		 // 开启中断	
}
 
void InitTime0(void)	              //定时器初始化在串口之后做
{
   TMOD |= 0x01;                        //设置T0定时模式1 
   TL0= 0xEF;                         //设置T0低8位初值 
   TH0= 0xD8;                        //设置T0高8位初值
   EA=1;                              //总中断允许 
   ET0=1;                             //定时器T0中断允许 
   TR0=1;                             //定时器T0启动
}
 
 void SendASC(uchar d)		 //串口发送一个字节函数
{
	
	SBUF=d;
	while(!TI);
 
	TI=0;
}
void SendString(uchar *str)	 //串口发送字符串
{
	while(*str)
	{
		SendASC(*str) ;
		str++;
		//delay_uart(1);
	}
}
///
 
 
/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
   SCL = high;		
   SDA = high;
   SDA = low;
   SCL = low;
}
 
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
   SCL = low;
   SDA = low;
   SCL = high;
   SDA = high;
}
/**********************************************
// IIC Write byte
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)		
	{
		if(IIC_Byte & 0x80)
		SDA=high;
		else
		SDA=low;
		SCL=high;
		SCL=low;
		IIC_Byte<<=1;
	}
	SDA=1;
	SCL=1;
	SCL=0;
}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
   IIC_Start();
   Write_IIC_Byte(0x78);            //Slave address,SA0=0
   Write_IIC_Byte(0x00);			//write command
   Write_IIC_Byte(IIC_Command); 
   IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
   IIC_Start();
   Write_IIC_Byte(0x78);			//D/C#=0; R/W#=0
   Write_IIC_Byte(0x40);			//write data
   Write_IIC_Byte(IIC_Data);
   IIC_Stop();
}
/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{
	unsigned char m,n;
	for(m=0;m<8;m++)
	{
		Write_IIC_Command(0xb0+m);		//page0-page1
		Write_IIC_Command(0x02);		//low column start address
		Write_IIC_Command(0x10);		//high column start address
		for(n=0;n<128;n++)
			{
				Write_IIC_Data(fill_Data);
			}
	}
}
 
//液晶显示中文函数
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
	unsigned char wm=0;
	unsigned int  adder=32*N;
    Write_IIC_Command(0xb0+x);
    Write_IIC_Command(((y&0xf0)>>4)|0x10);
    Write_IIC_Command((y&0x0f)|0x01);
	for(wm = 0;wm < 16;wm++)
	{
		Write_IIC_Data(F16x16[adder]);
		adder += 1;
	}
    Write_IIC_Command(0xb0+x+1);
    Write_IIC_Command((((y+1)&0xf0)>>4)|0x10);
    Write_IIC_Command(((y+1)&0x0f)|0x01);
	for(wm = 0;wm < 16;wm++)
	{
		Write_IIC_Data(F16x16[adder]);
		adder += 1;
	}
}  
 //液晶显示字符函数
void OLED_ShowZF(unsigned char x, unsigned char y, unsigned char N)
{
	unsigned char wm=0;
	unsigned int  adder=16*N;
    Write_IIC_Command(0xb0+x);
    Write_IIC_Command(((y&0xf0)>>4)|0x10);
    Write_IIC_Command((y&0x0f)|0x01);
	for(wm = 0;wm < 8;wm++)
	{
		Write_IIC_Data(F8X16[adder]);
		adder += 1;
	}
    Write_IIC_Command(0xb0+x+1);
    Write_IIC_Command((((y+1)&0xf0)>>4)|0x10);
    Write_IIC_Command(((y+1)&0x0f)|0x01);
	for(wm = 0;wm < 8;wm++)
	{
		Write_IIC_Data(F8X16[adder]);
		adder += 1;
	}
}	

/**********************************ADC0832 start********************************/
uchar GetValue0832(uchar Channel) //获取数值返回。入口:通道(0或1)。出口:数值。
{
		uchar i,Dat1=0,Dat2=0;
		Clk0832=0;
		Di0832=1;
		Cs0832=0;
		Clk0832=1;
		Clk0832=0; //第一脉冲,开始位
		Di0832=1;
		Clk0832=1;
		Clk0832=0; //第二脉冲,模式选择
		Di0832=Channel;//通道选择,0或1
		Clk0832=1;
		Clk0832=0; //第三脉冲,通道选择
		Di0832=1; //释放输入线
		for(i=0;i<8;i++) //从高到低取一次数
		{
				Clk0832=1; //下降沿有效
				Clk0832=0;
				if(Do0832) Dat1|=0x80>>i;
		}
		for(i=0;i<8;i++) //从低到高取一次数
		{
				if(Do0832) Dat2|=0x01<<i;
				Clk0832=1; //下降沿有效
				Clk0832=0;
		}
		Cs0832=1;
		Di0832=1;
		Clk0832=1; //数据读取完成,释放所有数据线
		if(Dat1==Dat2)
		return Dat1; //校验两次数相等
}
/**********************************ADC0832 end********************************/	
 
 
 
/***********************Delay****************************************/
void Delay_50ms(unsigned int Del_50ms)	//延时函数
{
	unsigned int m;
	for(;Del_50ms>0;Del_50ms--)
		for(m=6245;m>0;m--);
}
 
void Delay_1ms(unsigned int Del_1ms)
{
	unsigned char j;
	while(Del_1ms--)
	{	
		for(j=0;j<123;j++);
	}
}
 
 
void Initial_M096128x64_ssd1306()		//液晶初始化
{
	Delay_50ms(5);
	Write_IIC_Command(0xAE);   //display off
	Write_IIC_Command(0x02);	//Set Memory Addressing Mode	
	Write_IIC_Command(0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	Write_IIC_Command(0x40);	//Set Page Start Address for Page Addressing Mode,0-7
	Write_IIC_Command(0xb0);	//Set COM Output Scan Direction
	Write_IIC_Command(0x81);//---set low column address
	Write_IIC_Command(0xff);//---set high column address
	Write_IIC_Command(0xa1);//--set start line address
	Write_IIC_Command(0xa6);//--set contrast control register
	Write_IIC_Command(0xa8);
	Write_IIC_Command(0x3f);//--set segment re-map 0 to 127
	Write_IIC_Command(0xad);//--set normal display
	Write_IIC_Command(0x8b);//--set multiplex ratio(1 to 64)
	Write_IIC_Command(0x33);//
	Write_IIC_Command(0xc8);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	Write_IIC_Command(0xd3);//-set display offset
	Write_IIC_Command(0x00);//-not offset
	Write_IIC_Command(0xd5);//--set display clock divide ratio/oscillator frequency
	Write_IIC_Command(0x80);//--set divide ratio
	Write_IIC_Command(0xd9);//--set pre-charge period
	Write_IIC_Command(0x1f); //
	Write_IIC_Command(0xda);//--set com pins hardware configuration
	Write_IIC_Command(0x12);
	Write_IIC_Command(0xdb);//--set vcomh
	Write_IIC_Command(0x40);//0x20,0.77xVcc
//	Write_IIC_Command(0x8d);//--set DC-DC enable
//	Write_IIC_Command(0x14);//
	Write_IIC_Command(0xaf);//--turn on oled panel 
}


/***********************DHT11****************************************/
 
static void Delay_10us(void)
{
unsigned char i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/*读一个字节的数据*/
static unsigned char ReadValue(void)
{
unsigned char count, value = 0, i;
status = OK; //设定标志为正常状态
for(i = 8; i > 0; i--)
{
//高位在先
value <<= 1;
count = 0;
//每一位数据前会有一个50us 的低电平时间.等待50us 低电平结束
while(dht11 == 0 && count++ < NUMBER);
if(count >= NUMBER)
{
status = ERROR; //设定错误标志
return 0; //函数执行过程发生错误就退出函数
}
//26-28us 的高电平表示该位是0,为70us 高电平表该位1
Delay_10us();
Delay_10us();
Delay_10us();
//延时30us 后检测数据线是否还是高电平
if(dht11 != 0)
{
//进入这里表示该位是1
value++;
//等待剩余(约40us)的高电平结束
while(dht11 != 0 && count++ < NUMBER)
{
dht11 = 1;
}
if(count >= NUMBER)
{
status = ERROR; //设定错误标志
return 0;
}
}
}
return (value);
}
//读一次的数据,共五字节
extern unsigned char ReadTempAndHumi(void)
{
unsigned char i = 0, check_value = 0,count = 0;
EA = 0;
dht11 = 0; //拉低数据线大于18ms 发送开始信号
Delay_1ms(20); //需大于18 毫秒
dht11 = 1; //释放数据线,用于检测低电平的应答信号
//延时20-40us,等待一段时间后检测应答信号,应答信号是从机拉低数据线80us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
if(dht11 != 0) //检测应答信号,应答信号是低电平
{
//没应答信号
EA = 1;
return ERROR;
}
else
{
//有应答信号
while(dht11 == 0 && count++ < NUMBER); //等待应答信号结束
if(count >= NUMBER) //检测计数器是否超过了设定的范围
{
dht11 = 1;
EA = 1;
return ERROR; //读数据出错,退出函数
}
count = 0;
dht11 = 1;//释放数据线
//应答信号后会有一个80us 的高电平,等待高电平结束
while(dht11 != 0 && count++ < NUMBER);
if(count >= NUMBER)
{
dht11 = 1;
EA = 1;
return ERROR; //退出函数
}
//读出湿.温度值
for(i = 0; i < SIZE; i++)
{
	value_array[i] = ReadValue();
	if(status == ERROR)//调用ReadValue()读数据出错会设定status 为ERROR
	{
	dht11 = 1;
	EA = 1;
	return ERROR;
	}
	//读出的最后一个值是校验值不需加上去
	if(i != SIZE - 1)
	{
	//读出的五字节数据中的前四字节数据和等于第五字节数据表示成功
	check_value += value_array[i];
	}
}	//end for
	//在没用发生函数调用失败时进行校验
	if(check_value == value_array[SIZE - 1])
	{
		//将温湿度扩大10 倍方便分离出每一位
		humi_value = value_array[0] * 10;
		temp_value = value_array[2] * 10;
		dht11 = 1;
		EA = 1;
		return OK; //正确的读出dht11 输出的数据
	}
	else
	{
	//校验数据出错
		EA = 1;
		return ERROR;
	}
}
}
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
/




void delay(u16 ms)
{
	u16 i;u8 j;
	for(i=0;i<ms;i++)
		for(j=0;j<110;j++);
}


void keyscan()	//矩阵键盘扫描
{
	u8 temp;
	P2 = 0xf0;
	temp = P2;
	if(temp!=0xf0)	//扫描行
		delay(2);
		if( (temp!=0xf0)&&(Flag4X4==0) )
		{  	
			Flag4X4 = 1;
			switch(temp)
			{
				case 0x70:kx=0; break;
				case 0xb0:kx=1; break;
				case 0xd0:kx=2; break;
				case 0xe0:kx=3; break;
				default:		break;
			}
		}
		else
		{
			 Flag4X4 = 0;
		}
		
		P2 = 0x0f;
		temp = P2;
		if(temp!=0xf0)	  //扫描列
		{ 	
			switch(temp)
			{
				case 0x07:ky=0; break;
				case 0x0b:ky=1; break;
				case 0x0d:ky=2; break;
				case 0x0e:ky=3; break;
				default:		break;
			}
		}
		
}

void check()	//矩阵键盘数值转换
{
	switch(keyvalue[kx][ky])
	{
		case '0':Flagkey=0;  break;
		case '1':Flagkey=1;  break;
		case '2':Flagkey=2;  break;
		case '3':Flagkey=3;  break;
		case '4':Flagkey=4;  break;
		case '5':Flagkey=5;  break;
		case '6':Flagkey=6;  break;	
		case '7':Flagkey=7;  break;
		case '8':Flagkey=8;  break;
		case '9':Flagkey=9;  break;
		case 'a':Flagkey=10;  break;
		case 'b':Flagkey=11;  break;
		case 'c':Flagkey=12;  break;
		case 'd':Flagkey=13;  break;
		case '*':Flagkey=14;  break;
		case '#':Flagkey=15;  break;
		default:   break;
	}
}
 
/**********************************主程序************************************/
 
void main(void)
{
	Delay_1ms(100);
	Uart_init();	//串口初始化
	Delay_1ms(100);
	InitTime0();  //定时器初始化
	TR0=0;
	Delay_1ms(100);
	Initial_M096128x64_ssd1306();  //液晶初始化
	Delay_1ms(5);
	fill_picture(0xff);//全屏显示
	Delay_1ms(1000);
	fill_picture(0x00);
	TR0=1; 
	while(1)
	{
		Chan0Value= 100-GetValue0832(0)*0.392;	  //读取光照
		 ReadTempAndHumi();	//读取温湿度
	   	temp_value1 = temp_value/10;	//温度
		humi_value1 = humi_value/10; 	//湿度
		 Delay_1ms(100);


		 if(FlagModel==1)	//自动模式
		 { 
		 		if(FlagYD==1)	//有雨收回
				 {
				 	if(FlagGo==1)
					{
						FlagState=2;
						Delay_1ms(3000);
						FlagState=0;
						FlagGo = 0;
					}
				 }
				 else	//天晴情况下
				 {
				 	 if( (humi_value1<AlarmH)&&(Chan0Value>AlarmG) )   //湿度小于阈值并且光照大于阈值伸出晾衣架
					 {
							 		if(FlagGo==0)
									{
										FlagState = 1;
										Delay_1ms(3000);
										FlagState = 0;
										FlagGo = 1;
									}					 		
					 }
					 else //否则收回晾衣架
					 {
								 	if(FlagGo==1)
									{
										FlagState=2;
										Delay_1ms(3000);
										FlagState=0;
										FlagGo = 0;
									}					 	
					 }
				 }
		 }
		 else if(FlagModel==2)	  //定时模式
		 {
		  		if( ( (Hour*60+Min)>=(Hour1*60+Min1) )&&(Hour*60+Min)<(Hour2*60+Min2) )	//在定时时间内伸出晾衣架
				{
							 		if(FlagGo==0)
									{
										FlagState = 1;
										Delay_1ms(3000);
										FlagState = 0;
										FlagGo = 1;
									}						
				}
				else   //否则收回晾衣架
				{
							 		if(FlagGo==1)
									{
										FlagState = 2;
										Delay_1ms(3000);
										FlagState = 0;
										FlagGo = 0;
									}							
				}
		 }


		keyscan();	 //调用矩阵键盘函数
		check();
		if(Flag4X4)	 //键值处理
		{
					Flag4X4 = 0;
					//Delay_1ms(100);
			 		if(Flagkey<10)		 //数字输入
					{
							PassWord[3] = PassWord[2];
							PassWord[2] = PassWord[1];
							PassWord[1] = PassWord[0];
							PassWord[0] = Flagkey;						
					}
					else if(Flagkey==14)	 //手动伸出晾衣架
					{
							if(FlagModel==0)
							 {
							 		if(FlagGo==0)
									{
										FlagState = 1;
										Delay_1ms(3000);
										FlagState = 0;
										FlagGo = 1;
									}	
							 }			
					}
					else if(Flagkey==15)	 //手动收回晾衣架
					{
							 if(FlagModel==0)
							 {
							 		if(FlagGo==1)
									{
										FlagState = 2;
										Delay_1ms(3000);
										FlagState = 0;
										FlagGo = 0;
									}	
							 }			
					}
					else if(Flagkey==10)	//模式切换
					{
						 if(FlagModel<2) FlagModel++;
					}
					else if(Flagkey==11)	//模式切换
					{
						 if(FlagModel>0) FlagModel--;
					}
					else if(Flagkey==12)   //设置参数
					{
						   if(FlagSet==1)	   //设置实时时间
						   {
						   		Sec=0;
								Hour = PassWord[3]*10+PassWord[2];
								Min = PassWord[1]*10+PassWord[0];
						   }
						   else if(FlagSet==2)	  //设置定时开始时间
						   {
								Hour1 = PassWord[3]*10+PassWord[2];
								Min1 = PassWord[1]*10+PassWord[0];
						   }
						   else if(FlagSet==3)	//设置定时结束时间
						   {
								Hour2 = PassWord[3]*10+PassWord[2];
								Min2 = PassWord[1]*10+PassWord[0];
						   }
						   else if(FlagSet==5)	//设置光照阈值
						   {
								AlarmG = PassWord[1]*10+PassWord[0];
						   }
						   else if(FlagSet==4) //设置湿度阈值
						   {
								AlarmH = PassWord[1]*10+PassWord[0];
						   }
						   
						   PassWord[1]=0;
						   PassWord[0]=0;
						   PassWord[2]=0;
						   PassWord[3]=0;
					}
					else if(Flagkey==13)	//切换参数
					{
						   FlagSet++;
						   if(FlagSet>=6) FlagSet=0;
					}
		}


		 if(FlagGo==0)		 //显示晾衣架状态
		 {
			 OLED_ShowCN(0,0,0);	 //收回
			 OLED_ShowCN(0,16,1);		 	
		 }
		 else
		 {
		 	 OLED_ShowCN(0,0,2);   //伸出
			 OLED_ShowCN(0,16,3);	
		 }

		 OLED_ShowZF(0,32,Hour/10);	 //显示实时时间
		 OLED_ShowZF(0,40,Hour%10);
		 OLED_ShowZF(0,48,19);
		 OLED_ShowZF(0,56,Min/10);
		 OLED_ShowZF(0,64,Min%10);
		 if(FlagSet==1) OLED_ShowZF(0,72,20);
		 else           OLED_ShowZF(0,72,19);
		 OLED_ShowZF(0,80,Sec/10);
		 OLED_ShowZF(0,88,Sec%10);

		 if(FlagModel==0)	   //显示模式
		 {
			 OLED_ShowCN(0,96,4);
			 OLED_ShowCN(0,112,5);	//手动	 	
		 }
		 else if(FlagModel==1)
		 {
		 	 OLED_ShowCN(0,96,6); //自动
			 OLED_ShowCN(0,112,7);	
		 }
		 else if(FlagModel==2)
		 {
		 	 OLED_ShowCN(0,96,8);//定时
			 OLED_ShowCN(0,112,9);	
		 }

 		 OLED_ShowZF(2,0,Hour1/10);	   //显示定时时间
		 OLED_ShowZF(2,8,Hour1%10);
		 OLED_ShowZF(2,16,19);
		 OLED_ShowZF(2,24,Min1/10);
		 OLED_ShowZF(2,32,Min1%10);
		 if(FlagSet==2) OLED_ShowZF(2,40,20);
		 else           OLED_ShowZF(2,40,16);
		 OLED_ShowZF(2,64,Hour2/10);
		 OLED_ShowZF(2,72,Hour2%10);
		 OLED_ShowZF(2,80,19);
		 OLED_ShowZF(2,88,Min2/10);
		 OLED_ShowZF(2,96,Min2%10);
		 if(FlagSet==3)	OLED_ShowZF(2,104,20);
		 else 	        OLED_ShowZF(2,104,16);

		OLED_ShowZF(4,0,humi_value1%100/10);  //显示湿度和阈值
		OLED_ShowZF(4,8,humi_value1%10);
		OLED_ShowZF(4,16,14);
		OLED_ShowZF(4,32,AlarmH%100/10);
		OLED_ShowZF(4,40,AlarmH%10);
		OLED_ShowZF(4,48,14);
		if(FlagSet==4)	OLED_ShowZF(4,56,20);
		else 	        OLED_ShowZF(4,56,16);
		

		OLED_ShowZF(4,64,Chan0Value%100/10);  //显示光照和阈值
		OLED_ShowZF(4,72,Chan0Value%10);
		OLED_ShowZF(4,80,14);
		OLED_ShowZF(4,96,AlarmG%100/10);
		OLED_ShowZF(4,104,AlarmG%10);
		OLED_ShowZF(4,112,14);
		if(FlagSet==5)	OLED_ShowZF(4,120,20);
		else 	        OLED_ShowZF(4,120,16);

		 OLED_ShowZF(6,0,PassWord[3]);		//显示设置数字
		 OLED_ShowZF(6,8,PassWord[2]);
		 OLED_ShowZF(6,16,PassWord[1]);
		 OLED_ShowZF(6,24,PassWord[0]);
		OLED_ShowCN(6,32,10);
		OLED_ShowCN(6,48,11);
		
		if(YD) FlagYD=1;	//检测雨滴状态
		else FlagYD =0; 	

		 if(FlagYD==0)		 //显示天晴还是有雨
		 {
			 OLED_ShowCN(6,96,12);
			 OLED_ShowCN(6,112,13);		 	
		 }
		 else
		 {
		 	 OLED_ShowCN(6,96,14);
			 OLED_ShowCN(6,112,15);	
		 }
		
  	}
}
 
/****************************************************************************/
/******************************T0定时中断处理函数****************************/
void  timer0_int(void) interrupt 1     //T0中断1ms中断一次
{
	   	TL0= 0x17;                         //设置T0低8位初值 
	   	TH0= 0xFC;                        //设置T0高8位初值
	   	Time_10ms++;
	   	if(Time_10ms>=3)
	   	{
		   		Time_10ms= 0;
				FlagUpData = 1;
				FlagBJ++;
				if(FlagBJ>3) FlagBJ=0;
					
				if(FlagState==1)	  //步进电机控制
				{
					if(FlagBJ==0) 		{P10=1; P11=0; P12=0; P13=0;}
					else if(FlagBJ==1)	{P10=0; P11=1; P12=0; P13=0;}
					else if(FlagBJ==2)	{P10=0; P11=0; P12=1; P13=0;}
					else if(FlagBJ==3)	{P10=0; P11=0; P12=0; P13=1;}
				}
				else if(FlagState==2)
				{
					if(FlagBJ==0) 		{P10=0; P11=0; P12=0; P13=1;}
					else if(FlagBJ==1)	{P10=0; P11=0; P12=1; P13=0;}
					else if(FlagBJ==2)	{P10=0; P11=1; P12=0; P13=0;}
					else if(FlagBJ==3)	{P10=1; P11=0; P12=0; P13=0;}
				}
				else
				{
						P10=0; P11=0; P12=0; P13=0;
				}
	   	}

		Time_1ms++;
		if(Time_1ms>=1000)
		{
			Time_1ms = 0;
			Sec++;
			if(Sec>=60)
			{
				Sec = 0;
				Min++;
				if(Min>=60)
				{
					Min = 0;
					Hour++;
					if(Hour>=24) Hour=0;
				}
			}
		}

  
 
     
}
/**********************************************/
 
//  通讯中断接收程序   中断函数无返回值
  void uart_rx(void)  interrupt 4   //放在这里 和放在main()里面是一样的
 { 
    if(RI)	                 //是否接收中断
    {
				RI=0;
				RxBuf[0] = RxBuf[1];
				RxBuf[1] = SBUF;

	}
 
 }

五,相关作品展示

基于Java开发、Python开发、PHP开发、C#开发等相关语言开发的实战项目

基于Nodejs、Vue等前端技术开发的前端实战项目

基于微信小程序和安卓APP应用开发的相关作品

基于51单片机等嵌入式物联网开发应用

基于各类算法实现的AI智能应用

基于大数据实现的各类数据管理和推荐系统

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程千纸鹤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值