proteus:教室自动感应照明控制系统

描述

教室自动感应照明控制系统是基于单片机对学校教室照明设备进行控制和管理,教室亮度的调节、自动与手动状态的切换。整个系统由红外对管电路、光线检测电路、独立按键操作电路组成。单片机可以实现对教室内的教室检测控制元件所采集到的信息的接收、处理,从而可以很轻松的通过自习学生人数对教室光照强度进行实时调节。
教室照明节电控制部分采用STC89C52单片机作为核心控制芯片。教室入口装有两个激光传感器通过高低电平判断人数输出信号。楼道和洗手间采用热释电传感器触发电路使LED灯发亮。
系统实现的主要功能有:
1)红外对管电路,也是人数检测电路,可以对进入教室的人数进行统计,然后在光线黑暗的条件下,根据教室的人数决定照明灯的亮度。
2)光敏电阻检测光线强度,对照明现场的亮度进行检测,如果现场亮度符合照明要求,系统应关闭照明设备实现智能控制。
3)独立按键操作电路,可以切换自动状态和手动状态。手动状态就是可以手动控制教室的照明灯。 
4)楼道部分采用热释电传感器检测该区域是否有人通过,控制LED灯的开关。

 

Proteus
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;
#define ulong unsigned long
ulong volt;//测量的电压值
sbit wr=P2^0;				//数据写
sbit rd=P2^1;				//数据读
sbit ce=P2^2;				//片选
sbit cd=P2^3;				//指令数据通道,1指令,0数据
sbit rst=P2^4;			//复位信号

sbit CLK=P1^3;//定义时钟信号口
sbit DIN=P1^1;//定义2543数据写入口
sbit DOUT=P1^0;//定义2543数据读取口
sbit CS=P1^2;//定义2543片选信号口

sbit LED1 = P1^4;	//教室灯光
sbit LED2 = P1^5;	//走廊灯光
sbit KEY1 = P3^0;
sbit KEY2 = P3^1;
sbit KEY3 = P3^4;
sbit KEY4 = P3^5;
sbit KEY5 = P3^6;


uchar Peo_Number;
uint LDR_value;
uchar Mode = 0;  //当前控制模式 0 为 自动 1 为手动
uchar flag; 		//当前黑暗程度 0 为 明亮  1 为黑暗
uchar PWM_SET = 0;
uchar PWM_Value;
uchar LED_flag;			//走廊灯

uchar code HZ0[][32]={
	
{0x08,0x20,0x08,0x20,0x7E,0xA0,0x09,0x3E,0x0A,0x44,0xFF,0x44,0x08,0x44,0x7E,0xA4,
0x24,0x28,0x48,0x28,0x8F,0x10,0x78,0x10,0x08,0x28,0x08,0x48,0x28,0x84,0x11,0x02},/*"教",0*/

{0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x80,0x04,0x3F,0xF8,0x04,0x00,0x08,0x20,
0x1F,0xF0,0x01,0x10,0x01,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00},/*"室",1*/

{0x00,0x00,0x7D,0xFC,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x94,0x7D,0x08,0x44,0xFC,
0x44,0x84,0x44,0x84,0x44,0x84,0x7C,0xFC,0x00,0x00,0x48,0x88,0x44,0x44,0x84,0x44},/*"照",2*/

{0x00,0x00,0x00,0xFC,0x7C,0x84,0x44,0x84,0x44,0x84,0x44,0xFC,0x7C,0x84,0x44,0x84,
0x44,0x84,0x44,0xFC,0x7C,0x84,0x44,0x84,0x01,0x04,0x01,0x04,0x02,0x14,0x04,0x08},/*"明",3*/

{0x00,0xF8,0x3F,0x00,0x04,0x00,0x08,0x20,0x10,0x40,0x3F,0x80,0x01,0x00,0x06,0x10,
0x18,0x08,0x7F,0xFC,0x01,0x04,0x09,0x20,0x11,0x10,0x21,0x08,0x45,0x04,0x02,0x00},/*"系",4*/

{0x10,0x40,0x10,0x20,0x20,0x20,0x23,0xFE,0x48,0x40,0xF8,0x88,0x11,0x04,0x23,0xFE,
0x40,0x92,0xF8,0x90,0x40,0x90,0x00,0x90,0x19,0x12,0xE1,0x12,0x42,0x0E,0x04,0x00},/*"统",5*/

{0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x80,0x02,0x80,
0x04,0x40,0x04,0x40,0x08,0x20,0x08,0x20,0x10,0x10,0x20,0x08,0x40,0x04,0x80,0x02},/*"人",6*/

{0x08,0x20,0x49,0x20,0x2A,0x20,0x08,0x3E,0xFF,0x44,0x2A,0x44,0x49,0x44,0x88,0xA4,
0x10,0x28,0xFE,0x28,0x22,0x10,0x42,0x10,0x64,0x28,0x18,0x28,0x34,0x44,0xC2,0x82},/*"数",7*/

{0x01,0x00,0x02,0x00,0x04,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,
0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10},/*"自",8*/

{0x00,0x40,0x00,0x40,0x7C,0x40,0x00,0x40,0x01,0xFC,0x00,0x44,0xFE,0x44,0x20,0x44,
0x20,0x44,0x20,0x84,0x48,0x84,0x44,0x84,0xFD,0x04,0x45,0x04,0x02,0x28,0x04,0x10},/*"动",9*/

{0x00,0x10,0x00,0xF8,0x3F,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,
0x01,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00},/*"手",10*/

{0x00,0x40,0x00,0x40,0x7C,0x40,0x00,0x40,0x01,0xFC,0x00,0x44,0xFE,0x44,0x20,0x44,
0x20,0x44,0x20,0x84,0x48,0x84,0x44,0x84,0xFD,0x04,0x45,0x04,0x02,0x28,0x04,0x10},/*"动",11*/

{0x11,0x10,0x11,0x10,0x17,0xFC,0x11,0x10,0xFC,0x00,0x13,0xF8,0x32,0x08,0x3B,0xF8,
0x56,0x08,0x53,0xF8,0x90,0x40,0x17,0xFC,0x10,0xA0,0x11,0x10,0x12,0x08,0x14,0x06},/*"模",12*/

{0x00,0x48,0x00,0x44,0x00,0x44,0x00,0x40,0xFF,0xFE,0x00,0x40,0x00,0x40,0x3E,0x40,
0x08,0x40,0x08,0x40,0x08,0x20,0x08,0x22,0x0F,0x12,0x78,0x0A,0x20,0x06,0x00,0x02},/*"式",13*/

{0x01,0x00,0x21,0x08,0x11,0x08,0x09,0x10,0x09,0x20,0x01,0x00,0xFF,0xFE,0x04,0x40,
0x04,0x40,0x04,0x40,0x04,0x40,0x08,0x42,0x08,0x42,0x10,0x42,0x20,0x3E,0xC0,0x00},/*"光",14*/

{0x40,0x20,0x40,0x20,0x7F,0x20,0x80,0x3E,0x7E,0x44,0x42,0x44,0x52,0x44,0x4A,0xA4,
0xFF,0xA8,0x42,0x28,0x92,0x10,0x8A,0x10,0xFF,0x28,0x02,0x48,0x14,0x84,0x09,0x02},/*"敏",15*/

{0x00,0x00,0x7D,0xF8,0x45,0x08,0x49,0x08,0x49,0x08,0x51,0xF8,0x49,0x08,0x49,0x08,
0x45,0x08,0x45,0xF8,0x45,0x08,0x69,0x08,0x51,0x08,0x41,0x08,0x47,0xFE,0x40,0x00},/*"阻",16*/

{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,
0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00},/*"值",17*/


};

uchar code SZ[][16]={
	
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00},/*"0",0*/

{0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"1",1*/

{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00},/*"2",2*/

{0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3C,0x00,0x00},/*"3",3*/

{0x00,0x00,0x00,0x04,0x0C,0x0C,0x14,0x24,0x24,0x44,0x7F,0x04,0x04,0x1F,0x00,0x00},/*"4",4*/

{0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00},/*"5",5*/

{0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x22,0x1C,0x00,0x00},/*"6",6*/

{0x00,0x00,0x00,0x7E,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00},/*"7",7*/

{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00},/*"8",8*/

{0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x24,0x18,0x00,0x00},/*"9",9*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",10*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00},/*":",11*/
};

void delay(uint j)                        //1ms
{
        uchar i=250;
        for(;j >0;j--)
				{
                while(--i);
                i=249;
                while(--i);
                i=250;
        }
}

void Delay_xms(uint x)
{
  uint i,j;
  for(i=0;i< x;i++)
    for(j=0;j< 112;j++);
}

uchar read_status() //读取lcd12864的状态
{
uchar status;
P0=0;//端口b置为输入
rd=0;
wr=1;
ce=0;
cd=1;
status=P1;
return status;
}

void check_status()//检查lcd12864的状态
{
uchar s;
	P0=0Xff;//端口b置为输出
while((s&0x80)!=0x80)
   s=read_status();//等待位1,2置为。命令读写准备好。数据读写准备好
}

void write_data(uchar dat)//写数据
{
rd=1;
cd=0;
ce=0;
wr=0;
P0=dat;
wr=1;
ce=1;
cd=1;
}


void write_cmd1(uchar cmd)//写数据1
{
rd=1;
cd=1;
ce=0;
wr=0;
P0=cmd;
wr=1;
ce=1;
cd=0;
}

//先送参数,再送指令
void write_cmd2(uchar dat,uchar cmd)
{
check_status();
write_data(dat);
check_status();
write_cmd1(cmd);
}
void write_cmd3(uchar data1,uchar data2,uchar cmd)//发送参数并发指令再发送数据
{
check_status();
write_data(data1);
check_status();
write_data(data2);
check_status();
write_cmd1(cmd);
}


void init()//LCD12864的初始化
{
P2=0Xff;
P1=0Xff;
 
rst=1;
delay(10);
rst=0;
 
wr=1;
rd=1;
ce=1;
cd=1;
rst=1;
 
check_status();
write_cmd3(0x01,0x00,0x21);//光标指针设置
check_status();
write_cmd3(0x00,0x00,0x42);//图形区首地址
check_status();
write_cmd3(16,0x00,0x43);//图形区宽度
check_status();
write_cmd1(0x80);//显示方式设置,正常显示
check_status();
write_cmd1(0x98);//图形方式显示,不显示字母,只打点
check_status();
write_cmd1(0xa0);//光标形状设置1 0 1 0 0 N2 N1 N0
}


//汉字显示函数,处在x y处显示汉字
void display_HZ(uchar x,uchar y,uchar *hz)////x 0-3      y 0-7
{
uchar i,j=0;
for(i=0;i< 16;i++)
{
   write_cmd3(((j/2)< <4)|(y*2),x,0x24);//地址指针设置..低地址,高地址,命令
   write_cmd2(hz[j++],0xc0);
   write_cmd2(hz[j++],0xc0);
}
}



void display_SZ(uchar x,uchar y,uchar *hz)////x 0-3      y 0-14
{
uchar i,j=0;
for(i=0;i< 16;i++)
{
   write_cmd3(((j)< <4)|y,x,0x24);//地址指针设置..低地址,高地址,命令
   write_cmd2(hz[j++],0xc0);
}
}


void read2543(uchar addr)
{
	uint ad=0;
	uchar i;
	CLK=0;
	CS=0;//片选段,启动2543
	addr< <=4;//对地址位预处理
	for(i=0;i< 12;i++) //12个时钟走完,完成一次读取测量
	{
		if(DOUT==1)
			ad=ad|0x01;//单片机读取ad数据
		DIN=addr&0x80;//2543读取测量地址位
		CLK=1;
		;;;//很短的延时
		CLK=0;//产生下降沿,产生时钟信号
		;;;
		addr< <=1;
		ad< <=1;//将数据移位准备下一位的读写
	}
	CS=1;//关2543
	ad >>=1;
	volt=ad;//取走转换结果
	
	volt=volt*1221;//例子的满量程为5V,转换分辩率为12位(2的12次方=4096) 。即最大值是255,5/4096=1221mV,即例子中的1V代表实际1221mV
	LDR_value = volt / 1000;	
}


void KEY_Scan()
{
	if(KEY1 == 0)
	{
		delay(20);
		if(KEY1 == 0)
		{
			while(KEY1==0);
			display_HZ(1,0,HZ0[10]);
			display_HZ(1,1,HZ0[11]);		
			display_HZ(1,2,HZ0[12]);
			display_HZ(1,3,HZ0[13]);	
			Mode = 1;
			
		}
	}
	
		if(KEY2 == 0)
	{
		delay(20);
		if(KEY2 == 0)
		{
			while(KEY2==0);
			display_HZ(1,0,HZ0[8]);
			display_HZ(1,1,HZ0[9]);		
			display_HZ(1,2,HZ0[12]);
			display_HZ(1,3,HZ0[13]);	
			Mode = 0;
		}
	}
	
		if(KEY3 == 0)
	{
		delay(20);
		if(KEY3 == 0)
		{
			while(KEY3==0);
			if(Mode==1)
			{
				LED1 = 0;
			}
		}
	}
	
	
		if(KEY4 == 0)
	{
		delay(20);
		if(KEY4 == 0)
		{
			while(KEY4==0);
			if(Mode==1)
			{
				LED1 = 1;
			}
		}
	}
	
	
		if(KEY5 == 0)
	{
		delay(20);
		if(KEY5 == 0)
		{
			while(KEY5==0);
			LED2 = 0;
			delay(1000);
			LED2 = 1;
		}
	}
	
	
}

void main()
{
	TMOD |= 0x01;	  //开启定时器0  0x10时使用定时器1  0x11时启动两个
	TH0=0XFC;	//给定时器赋初值,定时1ms   TH1
	TL0=0X18;	 //TL1
	ET0=1;           //定时器0中断打开    ET1
	TR0=1;           //定时器0开关打开    TR1
	EA=1;        //全局中断开
	
	EX0=1;       //外部中断0开()  EX1 为外部中断1 (P3^3)
	IT0=1;        //低电平触发   IT1为中断1
	
	EX1=1;       //外部中断0开()  EX1 为外部中断1 (P3^3)
	IT1=1;        //低电平触发   IT1为中断1	
	
	init();
	Delay_xms(10);
	display_HZ(0,1,HZ0[0]);
	display_HZ(0,2,HZ0[1]);
	display_HZ(0,3,HZ0[2]);
	display_HZ(0,4,HZ0[3]);
	display_HZ(0,5,HZ0[4]);
	display_HZ(0,6,HZ0[5]);
	
	display_HZ(1,0,HZ0[8]);
	display_HZ(1,1,HZ0[9]);		
	display_HZ(1,2,HZ0[12]);
	display_HZ(1,3,HZ0[13]);	
	
	display_HZ(2,0,HZ0[6]);
	display_HZ(2,1,HZ0[7]);
	display_SZ(2,4,SZ[11]);
	
	display_SZ(2,5,SZ[Peo_Number/100]);
	display_SZ(2,6,SZ[Peo_Number/10%10]);
	display_SZ(2,7,SZ[Peo_Number%10]);
	read2543(0);
	display_HZ(3,0,HZ0[14]);
	display_HZ(3,1,HZ0[15]);
	display_HZ(3,2,HZ0[16]);
	display_HZ(3,3,HZ0[17]);
	display_SZ(3,8,SZ[11]);

	display_SZ(3,9,SZ[LDR_value/1000]);
	display_SZ(3,10,SZ[LDR_value/100%10]);
	display_SZ(3,11,SZ[LDR_value/10%10]);
	display_SZ(3,12,SZ[LDR_value%10]);
	
	while(1)
	{
		KEY_Scan();
	}
}

void K_INT1( )  interrupt 0  // 这里0对应下表
{
	   Peo_Number++;       
}


void K_INT2( )  interrupt 2  // 这里0对应下表
{
	   if(Peo_Number!=0)
		 {
			Peo_Number--;
		 }			 
}


void Timer0() interrupt 1     //参考上图  定时器1时为3
{
	static uint i;   //定义一个自变形变量
	TH0=0XFC;	//给定时器赋初值,定时1ms    TH1
	TL0=0X18;   //TL1
	i++;
	PWM_Value++;
	if(i==200)
	{
		i=0;
		read2543(0);
		display_SZ(3,9,SZ[LDR_value/1000]);
		display_SZ(3,10,SZ[LDR_value/100%10]);
		display_SZ(3,11,SZ[LDR_value/10%10]);
		display_SZ(3,12,SZ[LDR_value%10]);
		
		display_SZ(2,5,SZ[Peo_Number/100]);
		display_SZ(2,6,SZ[Peo_Number/10%10]);
		display_SZ(2,7,SZ[Peo_Number%10]);
		if(Peo_Number == 1)
		{
			PWM_SET = 1;
		}else if(Peo_Number > 20)
		{
			PWM_SET = 5;
		}else if(Peo_Number < 20 && Peo_Number >1)
		{
			PWM_SET = Peo_Number/5 + 1;//234
		}else if(Peo_Number==0)
		{
			PWM_SET = 0;
		}
		
		if(LDR_value< 1500)
		{
			flag = 0;
		}else
		{
			flag = 1;
		}
	}	
	
	if(PWM_Value==5)
	{
		PWM_Value = 0;
		
	}
	
	
			if(flag == 1 && Mode == 0)//光线不充足 并且在自动模式下
		{
			if(PWM_Value >= PWM_SET)//1
			{
				LED1 = 1;
			}else
			{
				LED1 = 0;
			}
		}else if(flag == 0 && Mode == 0)
		{
			LED1 = 1;
		}
}



   审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分