基于51单片机教室红外计数灯光控制—可蓝牙控制

基于51单片机智能教室灯光

(仿真+程序+原理图+PCB+设计报告)

功能介绍

具体功能:

本系统由STC89C52单片机+时钟芯片DS1302+液晶屏LCD1602+光敏电阻+红外对管+LED灯模块+按键模块+蓝牙模块构成

具体功能:

1.四个LED模拟教室灯光;

2.使用两个红外对管检测人进出教室,并统计;

3.LCD1602实时显示日期时间和统计的人数及光照强度;

4.按键设定定时时间段,在这时间段内开启自动照明功能;

5.光敏电阻检测光线,光线暗则打开自动照明;

6.人数<10:亮1个;10≤人数<20:亮2个;20≤人数<30:亮3个;30≤人数:全亮;

7.可以切换手动模式,手动开灯、手动调节亮度;

8.可以无线蓝牙按键控制

添加图片注释,不超过 140 字(可选)

程序

#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/***微信公众号:木子单片机********/
uchar time_data[7];
uchar code write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};       //数据的地址
uchar code read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};

uchar code table1[]="L: - |2000/00/00";
uchar code table2[]="R:   |00:00:00 0";
uchar code table3[]="                ";			 //清屏内容
uchar code table4[]="  Set Real Time ";
uchar code table5[]="  Set Open Time ";
uchar code table6[]="   Start Time:  ";
uchar code table7[]="    00:00:00    ";
uchar code table8[]="    End Time:   ";
uchar code table9[]="Date: 2000/00/00";
uchar code table0[]="Time: 00:00:00 0";
uchar value[]="C:000 L: \r\n";

bit Adjust;			  //调节标志位,=1表示进入调节模式,=0是正常模式
bit Auto_flg;		  //自动模式标志位,=1表示手动模式,=0是自动模式
bit Timer;
bit SELT_flg;
bit ENTER_flg;
bit UP_flg;
bit DOWN_flg;	  								
/***微信公众号:木子单片机********/
sbit rs=P1^0;		  //LCD1602
sbit rw=P1^1; 		  //LCD1602
sbit e=P1^2;		  //LCD1602
sbit sck=P2^5;		  //时钟端口
sbit io=P2^6;		  //时钟端口
sbit rst=P2^7;		  //时钟端口
sbit SELT =P1^6;	  //设置键
sbit ENTER=P1^7;	  //确认键
sbit UP   =P2^4;	  //加键
sbit DOWN =P2^3;	  //减键
sbit AUTO_LED=P1^3;	  //自动模式灯接口
sbit HAND_LED=P1^5;	  //手动灯接口
sbit LAMP1=P3^4;	  //灯接口
sbit LAMP2=P3^5;	  //灯接口
sbit LAMP3=P3^6;	  //灯接口
sbit LAMP4=P3^7;	  //灯接口
sbit CS   =P2^0;								//ADC0832
sbit Clk  =P2^2;						    	//ADC0832
sbit DATI =P2^1;								//ADC0832
sbit DATO =P2^1;								//ADC0832

uchar Select_num;	  //设置按键按下次数
uchar Enter_num;	  //确认按键按下次数
uchar Switch_num;	  //手动开关按键按下次数
char Year,Month,Day;
float Hour,Minute,Second;			//时间设置值
char Week;		
float Hour_H,Minute_H,Second_H;  					//设置结束时间
float Hour_L,Minute_L,Second_L;  					//设置开始时间
int Value1;											//人数
uchar IN1_flag=0;
uchar OUT1_flag=0;
uint Count;           //T0定时器中断计数次数
uchar Miao;
uint Count1;           //T1定时器中断计数次数
uchar dat=0x00;           						//AD值
uchar CH;       								//通道变量
char num;			   							//PWM中断次数
char pwm;			   							//脉宽参数 0-10 开机默认中间值
char Light;										//光线强度

uchar xdata UART0_Data[32];
uchar UART0_Len=1;

void read_rtc();

/***********************************************液晶屏LCD1602**********************************************************************/
void delay1(uint z)			  		//延时0.1ms函数
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=3;y>0;y--);
}

void write_com(uchar com)			 //写指令函数
{
	rw=0;
	delay1(5);
	rs=0;
	delay1(5);
	e=1;
	delay1(5);
	P0=com;
	delay1(5);
	e=0;
	delay1(5);	
}

void write_date(uchar date)			//写数据函数
{									
	rw=0;
	delay1(5);
	rs=1;
	delay1(5);
	e=1;
	delay1(5);
	P0=date;
	delay1(5);
	e=0;
	delay1(5);	
}

void init()						    //初始化函数
{	
	uchar num;	
	e=0;						    // 时序表e初始为0
	write_com(0x38);		        //设置16*2显示,5*7点阵,8位数据接口
	write_com(0x0c);				//设置光标
	write_com(0x06);				//光标自动加1,光标输入方式
	write_com(0x01);				//清屏
	write_com(0x80);				//设置初始显示位置
	for(num=0;num<16;num++)
	{
		write_date(table1[num]);
		delay1(5);
	}
	write_com(0x80+0x40);
	for(num=0;num<16;num++)
	{
		write_date(table2[num]);
		delay1(5);
	}					  
}

void SetTime_dispaly(uchar add,uchar dat)	 //第一个:参数的地址,第二个:参数的内容
{
	uchar shi,ge;
	shi=dat/10;							//把十位提取出来
	ge=dat%10;							//把个位提取出来
	write_com(add);			   	 		//要写的地址
	write_date(0x30+shi);				//十位的内容   1602字符库
	write_date(0x30+ge);				//个位的内容   1602字符库
}

void Week_dispaly(uchar add,uchar dat)	//第一个:参数的地址,第二个:参数的内容
{
	write_com(add);						//要写的地址
	write_date(0x30+dat);				//十位的内容   1602字符库
}
void Date_dispaly(uchar add,uchar dat)	 //第一个:参数的地址,第二个:参数的内容
{
	uchar shi,ge;
	shi=dat/16;							//把十位提取出来
	ge=dat%16;							//把个位提取出来
	write_com(add+3);			   	 	//要写的地址
	write_date(0x30+shi);				//十位的内容   1602字符库
	write_date(0x30+ge);				//个位的内容   1602字符库				   
}
void Write_Data(uchar add,uint date)  //把数据写到对应的位置 为3位数
{
	uchar bai,shi,ge;
	bai=date/100;
	shi=date%100/10;
	ge=date%10;
	write_com(0x80+add);
	write_date(0x30+bai);
	write_date(0x30+shi);				   
	write_date(0x30+ge);				    
}
void LCD_Display_String(unsigned char line,unsigned char *string)
{ 										//液晶屏显示内容,把要显示的内容写到对应的位置
	unsigned char i;
	unsigned char address=0;
	if(line==1)
	{
		address=0x80;	 				//0X80是第1行的第1个位置  ,0x81第2位
	}
	else if(line==2)
	{
		address=0x80+0x40;  			//0X80+0x40是第2行的第1个位置  ,0X80+0x40+1是第2行第2位
	}
	
	for(i=0;i<16;i++)
	{
		write_com(address);
		write_date(string[i]);
		address++;
	} 
}

void Time_Display(void)
{
	read_rtc();
	Date_dispaly(0x80+0x40+9,time_data[6]);  //显示秒
	Date_dispaly(0x80+0x40+6,time_data[5]);	 //显示分
	Date_dispaly(0x80+0x40+3,time_data[4]);	 //显示时
	Date_dispaly(0x80+11,time_data[3]);		 //显示日
	Date_dispaly(0x80+8,time_data[2]);		 //显示月
	Week_dispaly(0x80+0x40+15,time_data[1]-1);  //显示周  0表示星期天,1表示星期一......6表示星期六 芯片读出的数据表示1为一周的第一天星期天,故做减一处理
	Date_dispaly(0x80+5,time_data[0]);		 //显示年
					   //	Year/10*16+Year%10
	Year=time_data[0]/16*10+time_data[0]%16;
	Week=time_data[1]/16*10+time_data[1]%16-1;
	Month=time_data[2]/16*10+time_data[2]%16;
	Day=time_data[3]/16*10+time_data[3]%16;
	Hour=time_data[4]/16*10+time_data[4]%16;
	Minute=time_data[5]/16*10+time_data[5]%16;
	Second=time_data[6]/16*10+time_data[6]%16;
	
}

/*******************************************时钟芯片DS1302*****************************************************/
void write_ds1302_byte(uchar dat)
{
	uchar i;
	for(i=0;i<8;i++)
	{
		sck=0;
		io=dat&0x01;					   //准备数据,从最低位开始
		dat=dat>>1;
		sck=1;
	}
}

void write_ds1302(uchar add,uchar dat)
{
	rst=0;
	_nop_();  						//CPU原地踏步
	sck=0;
	_nop_();
	rst=1;
	_nop_();
	write_ds1302_byte(add);		    //传地址
	write_ds1302_byte(dat);		    //传数据
	rst=0;     						//不受其他影响
	_nop_();
	io=1;						   //释放
	sck=1;
}

uchar read_ds1302(uchar add)
{
	uchar i,value;
	rst=0;
	_nop_();  //CPU原地踏步
	sck=0;
	_nop_();
	rst=1;
	_nop_();
	write_ds1302_byte(add);
	for(i=0;i<8;i++)
	{
		value=value>>1;
		sck=0;
		if(io)
		value=value|0x80;
		sck=1;
	}
	rst=0;
	_nop_();
	sck=0;
	_nop_();
	sck=1;
	io=1;
	return value;
}

void set_rtc()			          //设置时间
{
	uchar i,j;
	for(i=0;i<7;i++)			 //转换BCD码
	{
		j=time_data[i]/10;
		time_data[i]=time_data[i]%10;
		time_data[i]=time_data[i]+j*16;
	}
	write_ds1302(0x8e,0x00);	  //去除写保护
	for(i=0;i<7;i++)
	{
		write_ds1302(write_add[i],time_data[i]);
	}
	write_ds1302(0x8e,0x80);      //加写保护
}

void read_rtc()
{
	uchar i;
	for(i=0;i<7;i++)
	{
		time_data[i]=read_ds1302(read_add[i]);	//最终读出来的数 16进制
	}
}

/*************************************************按键****************************************************************/
void Keyscan(void)
{
	if((SELT==0)||(SELT_flg==1))
	{
		delay1(50);
		if(SELT==0)
		{
			while(!SELT);
		}
		SELT_flg=0;
		Select_num++;						//设置键按下一次
		Adjust=1;							//进入调节模式
		if(Select_num==1)
		{
			LCD_Display_String(1,table4);
			LCD_Display_String(2,table5);
			write_com(0x80+0);				//写 >>
			write_date(0x3e);
			write_com(0x80+1);				//写 >>
			write_date(0x3e);
			Enter_num=0;
		}
		if(Select_num==2)
		{
			LCD_Display_String(1,table4);
			LCD_Display_String(2,table5);
			write_com(0x80+0x40+0);				//写 >>
			write_date(0x3e);
			write_com(0x80+0x40+1);				//写 >>
			write_date(0x3e);
			Enter_num=0;
		}
		if(Select_num==3)
		{
			LCD_Display_String(1,table1);
			LCD_Display_String(2,table2);
			Select_num=0;
			Enter_num=0;					
			Adjust=0;
		}
		write_com(0x0c);									//光标不再闪烁
		Enter_num=0;
	}
	
	if((ENTER==0)||(ENTER_flg==1))
	{
		delay1(50);
		if(ENTER==0)
		{
			while(!ENTER);
		}
		ENTER_flg=0;			
			
		Enter_num++;
		if(Select_num==0)					//模式切换
		{
			Auto_flg=~Auto_flg;				//模式切换
			if(Auto_flg==0)					//自动模式
			{
				AUTO_LED=0;					//自动灯亮
				HAND_LED=1;
			}
			if(Auto_flg==1)					//手动模式
			{
				AUTO_LED=1;					
				HAND_LED=0;					//手动灯亮
				LAMP1=1;					//关灯
				LAMP2=1;
				LAMP3=1;
				LAMP4=1;
				pwm=5;
			}
		}
		if(Select_num==1)					//设置实时时间
		{
			if(Enter_num==1)
			{
				LCD_Display_String(1,table9);
				LCD_Display_String(2,table0);
				SetTime_dispaly(0x80+8,Year);
				SetTime_dispaly(0x80+11,Month);
				SetTime_dispaly(0x80+14,Day);
				SetTime_dispaly(0x80+0x40+6,Hour);
				SetTime_dispaly(0x80+0x40+9,Minute);
				SetTime_dispaly(0x80+0x40+12,Second);
				Week_dispaly(0x80+0x40+15,Week);
				write_com(0x80+8);			//光标闪烁地址,停留在年的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==2)
			{
				write_com(0x80+11);			//光标闪烁地址,停留在月的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==3)
			{
				write_com(0x80+14);			//光标闪烁地址,停留在日的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==4)
			{
				write_com(0x80+0x40+6);		//光标闪烁地址,停留在时的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==5)
			{
				write_com(0x80+0x40+9);		//光标闪烁地址,停留在分的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==6)
			{
				write_com(0x80+0x40+12);	//光标闪烁地址,停留在秒的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==7)
			{
				write_com(0x80+0x40+15);	//光标闪烁地址,停留在星期的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==8)
			{
				Enter_num=0;
				write_com(0x0c);			//光标不再闪烁
				LCD_Display_String(1,table1);
				LCD_Display_String(2,table2);
				Week++;                     //按键设置时,比如设置星期6,此时显示会被减一处理(void Time_Display(void)函数)显示5,此处加回去,保证设置多少就显示多少
				time_data[0]=Year;///10*16+Year%10;
				time_data[1]=Week;///10*16+Week%10;
				time_data[2]=Month;///10*16+Month%10;
				time_data[3]=Day;///10*16+Day%10;
				time_data[4]=Hour;///10*16+Hour%10;
				time_data[5]=Minute;///10*16+Minute%10;
				time_data[6]=Second;///10*16+Second%10;
				set_rtc();					 //设置时间
				Select_num=0;
				Adjust=0;
			}
		}

		if(Select_num==2)					//设置开启时间
		{
			if(Enter_num==1)
			{
				LCD_Display_String(1,table6);
				LCD_Display_String(2,table7);
				SetTime_dispaly(0x80+0x40+4,Hour_L);
				SetTime_dispaly(0x80+0x40+7,Minute_L);
				SetTime_dispaly(0x80+0x40+10,Second_L);
				write_com(0x80+0x40+4);		//光标闪烁地址,停留在时的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==2)
			{
				write_com(0x80+0x40+7);		//光标闪烁地址,停留在分的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==3)
			{
				write_com(0x80+0x40+10);	//光标闪烁地址,停留在秒的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==4)
			{
				write_com(0x0c);			//光标不再闪烁
				LCD_Display_String(1,table8);
				LCD_Display_String(2,table7);	
				SetTime_dispaly(0x80+0x40+4,Hour_H);
				SetTime_dispaly(0x80+0x40+7,Minute_H);
				SetTime_dispaly(0x80+0x40+10,Second_H);
				write_com(0x80+0x40+4);		//光标闪烁地址,停留在时的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==5)
			{
				write_com(0x80+0x40+7);		//光标闪烁地址,停留在分的位置上					
				write_com(0x0f);			//光标闪烁
			}
			if(Enter_num==6)
			{
				write_com(0x80+0x40+10);	//光标闪烁地址,停留在秒的位置上					
				write_com(0x0f);			//光标闪烁
			}		
			if(Enter_num==7)
			{
				Enter_num=0;
				write_com(0x0c);			//光标不再闪烁
				LCD_Display_String(1,table1);
				LCD_Display_String(2,table2);
				Select_num=0;
				Adjust=0;
			}
		}

	}
	if((UP==0)||(UP_flg==1))
	{
		delay1(50);
		if(UP==0)
		{
			while(!UP);
		}
		UP_flg=0;
		if(Select_num==0)
		{
			if(Auto_flg==1)							//手动模式
			{
				Switch_num++;				//按下次数增加
				if(Switch_num==1)			//按下一次,开一盏灯
				{
					LAMP1=0;
					LAMP2=1;
					LAMP3=1;
					LAMP4=1;
				}
				if(Switch_num==2)			//按下二次,开二盏灯
				{
					LAMP1=0;
					LAMP2=0;
					LAMP3=1;
					LAMP4=1;
				}
				if(Switch_num==3)			//按下3次,开3盏灯
				{
					LAMP1=0;
					LAMP2=0;
					LAMP3=0;
					LAMP4=1;
				}
				if(Switch_num==4)			//按下4次,开4盏灯
				{
					LAMP1=0;
					LAMP2=0;
					LAMP3=0;
					LAMP4=0;
				}
				if(Switch_num==5)			//按下5次,开0盏灯
				{
					LAMP1=1;
					LAMP2=1;
					LAMP3=1;
					LAMP4=1;
					Switch_num=0;			//次数清除
				}
			}
		}

		if(Select_num==1)
		{
			if(Enter_num==1)
			{
				Year++;
				if(Year>99)
				Year=0;
				SetTime_dispaly(0x80+8,Year);
				write_com(0x80+8);								
				write_com(0x0f);			
			}
			if(Enter_num==2)
			{
				Month++;
				if(Month>12)
				Month=1;
				SetTime_dispaly(0x80+11,Month);
				write_com(0x80+11);								
				write_com(0x0f);							  
			}
			if(Enter_num==3)
			{
				Day++;
				if(Day>31)
				Day=1;
				SetTime_dispaly(0x80+14,Day);
				write_com(0x80+14);								
				write_com(0x0f);
			}
			if(Enter_num==4)
			{
				Hour++;
				if(Hour>23)
				Hour=0;
				SetTime_dispaly(0x80+0x40+6,Hour);
				write_com(0x80+0x40+6);								
				write_com(0x0f);
			}
			if(Enter_num==5)
			{
				Minute++;
				if(Minute>59)
				Minute=0;
				SetTime_dispaly(0x80+0x40+9,Minute);
				write_com(0x80+0x40+9);								
				write_com(0x0f);
			}
			if(Enter_num==6)
			{
				Second++;
				if(Second>59)
				Second=0;
				SetTime_dispaly(0x80+0x40+12,Second);
				write_com(0x80+0x40+12);								
				write_com(0x0f);
			}
			if(Enter_num==7)
			{
				Week++;
				if(Week>6)
				Week=0;
				Week_dispaly(0x80+0x40+15,Week);
				write_com(0x80+0x40+15);								
				write_com(0x0f);
			}
		}
		if(Select_num==2)
		{				
			if(Enter_num==1)
			{
				Hour_L++;
				if(Hour_L>23)
				Hour_L=0;
				SetTime_dispaly(0x80+0x40+4,Hour_L);
				write_com(0x80+0x40+4);								
				write_com(0x0f);
			}
			if(Enter_num==2)
			{
				Minute_L++;
				if(Minute_L>59)
				Minute_L=0;
				SetTime_dispaly(0x80+0x40+7,Minute_L);
				write_com(0x80+0x40+7);								
				write_com(0x0f);
			}
			 
			if(Enter_num==3)
			{
				Second_L++;
				if(Second_L>59)
				Second_L=0;
				SetTime_dispaly(0x80+0x40+10,Second_L);
				write_com(0x80+0x40+10);								
				write_com(0x0f);
			}
			if(Enter_num==4)
			{
				Hour_H++;
				if(Hour_H>23)
				Hour_H=0;
				SetTime_dispaly(0x80+0x40+4,Hour_H);
				write_com(0x80+0x40+4);								
				write_com(0x0f);
			}
			if(Enter_num==5)
			{
				Minute_H++;
				if(Minute_H>59)
				Minute_H=0;
				SetTime_dispaly(0x80+0x40+7,Minute_H);
				write_com(0x80+0x40+7);								
				write_com(0x0f);
			}
			 
			if(Enter_num==6)
			{
				Second_H++;
				if(Second_H>59)
				Second_H=0;
				SetTime_dispaly(0x80+0x40+10,Second_H);
				write_com(0x80+0x40+10);								
				write_com(0x0f);
			}				
		}
	}
	if((DOWN==0)||(DOWN_flg==1))
	{
		delay1(50);
		if(DOWN==0)
		{
			while(!DOWN);
		}
		DOWN_flg=0;
		if(Select_num==0)
		{
			if(Auto_flg==1)					//手动模式
			{
				pwm++;						//亮度变化
				if(pwm>9)
				pwm=0;
			}
		}

		if(Select_num==1)
		{
			if(Enter_num==1)
			{
				Year--;
				if(Year<0)
				Year=99;
				SetTime_dispaly(0x80+8,Year);
				write_com(0x80+8);								
				write_com(0x0f);
			}
			if(Enter_num==2)
			{
				Month--;
				if(Month<1)
				Month=12;
				SetTime_dispaly(0x80+11,Month);
				write_com(0x80+11);								
				write_com(0x0f);
			}
			if(Enter_num==3)
			{
				Day--;
				if(Day<1)
				Day=31;
				SetTime_dispaly(0x80+14,Day);
				write_com(0x80+14);								
				write_com(0x0f);
			}
			if(Enter_num==4)
			{
				Hour--;
				if(Hour<0)
				Hour=23;
				SetTime_dispaly(0x80+0x40+6,Hour);
				write_com(0x80+0x40+6);								
				write_com(0x0f);
			}
			if(Enter_num==5)
			{
				Minute--;
				if(Minute<0)
				Minute=59;
				SetTime_dispaly(0x80+0x40+9,Minute);
				write_com(0x80+0x40+9);								
				write_com(0x0f);
			}
			if(Enter_num==6)
			{
				Second--;
				if(Second<0)
				Second=59;
				SetTime_dispaly(0x80+0x40+12,Second);
				write_com(0x80+0x40+12);								
				write_com(0x0f);
			}
			if(Enter_num==7)
			{
				Week--;
				if(Week<0)
				Week=6;
				Week_dispaly(0x80+0x40+15,Week);
				write_com(0x80+0x40+15);								
				write_com(0x0f);
			}		
		}

		if(Select_num==2)
		{
			if(Enter_num==1)
			{
				Hour_L--;
				if(Hour_L<0)
				Hour_L=23;
				SetTime_dispaly(0x80+0x40+4,Hour_L);
				write_com(0x80+0x40+4);								
				write_com(0x0f);
			}
			if(Enter_num==2)
			{
				Minute_L--;
				if(Minute_L<0)
				Minute_L=59;
				SetTime_dispaly(0x80+0x40+7,Minute_L);
				write_com(0x80+0x40+7);								
				write_com(0x0f);
			}
			if(Enter_num==3)
			{
				Second_L--;
				if(Second_L<0)
				Second_L=59;
				SetTime_dispaly(0x80+0x40+10,Second_L);
				write_com(0x80+0x40+10);								
				write_com(0x0f);
			}
			 
			if(Enter_num==4)
			{
				Hour_H--;
				if(Hour_H<0)
				Hour_H=23;
				SetTime_dispaly(0x80+0x40+4,Hour_H);
				write_com(0x80+0x40+4);								
				write_com(0x0f);
			}
			if(Enter_num==5)
			{
				Minute_H--;
				if(Minute_H<0)
				Minute_H=59;
				SetTime_dispaly(0x80+0x40+7,Minute_H);
				write_com(0x80+0x40+7);								
				write_com(0x0f);
			}
			if(Enter_num==6)
			{
				Second_H--;
				if(Second_H<0)
				Second_H=59;
				SetTime_dispaly(0x80+0x40+10,Second_H);
				write_com(0x80+0x40+10);								
				write_com(0x0f);
			}
		}
	}	
}
****//完整资料
***//***微信公众号:木子单片机********/
void Open(void)
{
	float Now;
	float Set_L,Set_H;
	Now=Hour+Minute/60+Second/3600;				  		//把实时时间化成小时为单位
	Set_L=Hour_L+Minute_L/60+Second_L/3600;		  		//把设置下限时间化成小时为单位
	Set_H=Hour_H+Minute_H/60+Second_H/3600;		  		//把设置上限时间化成小时为单位
	if((Now>=Set_L)&(Now<=Set_H))				  		//实时时间在上下限时间范围内
	Timer=1;
	else
	Timer=0;		
} 
/*************************************ADC0832*****************************************/
uchar adc0832(uchar CH)					// AD转换子程序
{
	uchar i,test,adval;
	adval=0x00;
	test=0x00;
	Clk=0;       						//初始化
	DATI=1;
	_nop_();
	CS=0;
	_nop_();
	Clk=1;
	_nop_();
	if(CH==0x00)      					//通道选择
	{
		Clk=0;
		DATI=1;      //通道0的第一位
		_nop_();
		Clk=1;
		_nop_();
		Clk=0;
		DATI=0;      //通道0的第二位
		_nop_();
		Clk=1;
		_nop_();
	} 
	else
	{
		Clk=0;
		DATI=1;      //通道1的第一位
		_nop_();
		Clk=1;
		_nop_();
		Clk=0;
		DATI=1;      //通道1的第二位
		_nop_();
		Clk=1;
		_nop_();
	}
	Clk=0;
	DATI=1;
	for(i=0;i<8;i++)      //读取前8位的值
	{
		_nop_();
		adval<<=1;
		Clk=1;
		_nop_();
		Clk=0;
		if(DATO)
		adval|=0x01;
		else
		adval|=0x00;
	}
	for(i=0;i<8;i++)      //读取后8位的值
	{
		test>>=1;
		if(DATO)
		test|=0x80;
		else 
		test|=0x00;
		_nop_();
		Clk=1;
		_nop_();
		Clk=0;
	}
	if(adval == test)      //比较前8位与后8位的值,如果不相同舍去。若一直出现显示为零,请将该行去掉
	dat=test;
	
	_nop_();
	CS=1;        			//释放ADC0832
	DATO=1;
	Clk=1;
	return dat;
}
void Light_Check(void)
{
	dat=adc0832(CH);						//采集光线电压
	if((dat>=0)&(dat<20))					//根据采到的电压值给定光线强度,电压越高,光线强度越低
	{Light=9;}				   
	if((dat>=20)&(dat<40))
	{Light=8;}
	if((dat>=40)&(dat<60))
	{Light=7;}
	if((dat>=60)&(dat<80))
	{Light=6;}
	if((dat>=80)&(dat<100))
	{Light=5;}
	if((dat>=100)&(dat<120))
	{Light=4;}
	if((dat>=120)&(dat<140))
	{Light=3;}
	if((dat>=140)&(dat<160))
	{Light=2;}
	if((dat>=160)&(dat<180))
	{Light=1;}
	if((dat>=180)&(dat<=255))
	{Light=0;}

	if(Auto_flg==0)			   				//自动模式下
	{
		if((dat>=0)&(dat<20))					
		{pwm=0;}				   
		if((dat>=20)&(dat<40))
		{pwm=1;}
		if((dat>=40)&(dat<60))
		{pwm=2;}
		if((dat>=60)&(dat<80))
		{pwm=3;}
		if((dat>=80)&(dat<100))
		{pwm=4;}
		if((dat>=100)&(dat<120))
		{pwm=5;}
		if((dat>=120)&(dat<140))
		{pwm=6;}
		if((dat>=140)&(dat<160))
		{pwm=7;}
		if((dat>=160)&(dat<180))
		{pwm=8;}
		if((dat>=180)&(dat<=255))
		{pwm=9;}
	}
	Week_dispaly(0x80+2,Light);				//显示光线强度
	Week_dispaly(0x80+4,pwm);				//显示亮灯强度
}
/*****************************************人数统计**************************************************************/
void intinit(void)				 //外部中断0初始化
{	
	EA=1;					  	 //打开总中断
 	EX0=1;					  	 //中断允许位
	IT0=1;					  	 //外部中断0触发方式为下降沿触发
	EX1=1;					  	 //中断允许位
	IT1=1;					  	 //外部中断0触发方式为下降沿触发
}

void int1 () interrupt 2   		//外红外对管
{	
	if(IN1_flag==0)
	{
		OUT1_flag=1;
		TR0=1;					 //开启定时器开始计时,如果3秒内只触发一个则清零,防止误触发
	}
	if(IN1_flag==1)
	{
		Value1--;				//人数减少
		if(Value1<0)			//如果人数计数小于0,变为最小0
		Value1=0;
		IN1_flag=0;				//清零
		OUT1_flag=0;
		TR0=0;					 //关闭定时器
		Count=0;
		Miao=0;
	}
}
void int0 () interrupt 0   		//内红外对管
{	
	if(OUT1_flag==0)
	{
		IN1_flag=1;
		TR0=1;					 //开启定时器开始计时,如果3秒内只触发一个则清零,防止误触发
	}
	if(OUT1_flag==1)
	{
		
		Value1++;				 //人数增加
		if(Value1>=999)			 //如果人数计数到999,变为最大999
		Value1=999;
		OUT1_flag=0;			 //清零
		IN1_flag=0;
		TR0=0;					 //关闭定时器
		Count=0;
		Miao=0;
	}
}

硬件设计

使用元器件:

单片机:STC89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

排阻:8*10K;瓷片电容:104;

插件电容:2.2uF/50V;

插件电容:100uF/16V;

LED灯;纽扣电池座;

开关;电源接口;瓷片电容:30;

蓝牙模块:HC-05;液晶屏:LCD1602;

红外接收管;红外发射管;

光敏电阻:100k;蓝白可调电阻:10K;

插件电阻:4.7K;插件电阻:510;

插件电阻:10K;插件电阻:100k;

插件电阻:100;按键:SW-PB;

万用板:9*15cm; 时钟芯片:DS1302;

模数转换器:ADC0832;运放:LM393;

晶振:32768Hz;晶振:11.0592M;

12M晶振;导线:若干;

添加图片注释,不超过 140 字(可选)

流程图:

添加图片注释,不超过 140 字(可选)

设计资料

01仿真图

本设计使用proteus7.8和proteus8.9两个版本设计,向下兼容,无需担心!具体如图!

添加图片注释,不超过 140 字(可选)

02原理图

本系统原理图采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

03程序

本设计使用keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

04设计报告

一万两千字设计报告,具体如下!

添加图片注释,不超过 140 字(可选)

05设计资料

全部资料包括程序(含注释)、仿真源文件 、AD原理图、任务书、PCB、设计报告、流程图、实物图、元件清单等。具体内容如下,全网最全! !

点赞分享一起学习成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值