AT89C51單片機制作簡易密碼鎖

51單片機課程設計—製作密碼鎖

1.設計要求

1.1能設定一組4位的數字開啓密碼(設定密碼功能)
1.2用LED小燈代替鎖開啓顯示,輸入密碼正確,則小燈亮起(開鎖功能)
1.3如果3次密碼錯誤,則進行鳴叫報警,並在1分鐘之內不能再次輸入(報警)
1.4.密碼輸入顯示在數碼管上,輸入正確顯示on,輸入錯誤顯示err(顯示功能)
可在以上功能上擴展。

2.設計流程圖

在這裏插入圖片描述

3.重要代碼解釋

3.1 本次開發爲使用按鍵中斷,只進行了矩陣按鍵的使用,在第一次按鍵與第二次按鍵的過程間,均進行了按鍵的等待釋放,以及等待按鍵按下的判斷,提高程序的正確性
在這裏插入圖片描述3.2 合理的設置按鍵掃描函數,達到按鍵的準確判斷
在這裏插入圖片描述3.3 輸入密碼時嚴格控制密碼設置的位數,代碼精簡
在這裏插入圖片描述

4.仿真電路設計

在這裏插入圖片描述

5.完整代碼設計

#include<reg51.h>
//定義IO口
sbit Beep=P3^6;
sbit LED1=P3^7;
//定義全局變量
int count=-1;
int count1=0;//用於記錄輸入密碼錯誤的次數
int counter;//用於計數是定時器能夠定時1分鐘
int counter1=0;
int temp=99,signal=0;
//初始化密碼
int key_word[4]={99,99,99,99};
//用於接收按鍵接收的值
int get_word[4]={0,0,0,0};
char key_buf[]={0xee,0xde,0xbe,0x7e,
				0xed,0xdd,0xbd,0x7d,
				0xeb,0xdb,0xbb,0x7b,
                0xe7,0xd7,0xb7,0x77};//鍵模
//LED字模
char led[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0-9
//函數聲明
void set_key();
void show1(int);
void open_key();
void input_key();
void show2(int);
void show3();
void show4();
int get_key();
//延時函數
void delay(int x)
{
	int j=0;
	for(;x>0;x--)
		for(j=0;j<125;j++);
}

//設定密碼功能
void set_key()
{
	int i;
	for(i=0;i<4;i++)
	{	
		while(get_key()==-1)//等待按鍵按下
		{
			if(count!=0&&count!=-1)
			{
				show1(count);//顯示設置的密碼
			}
		}
		if(signal==1)//將按鍵的值保存
		{
			key_word[i]=get_key();
			count++;
			show1(count);
			signal=0;
			temp=99;
		}
		while(temp==get_key())//一旦長時間按按鍵,就一直顯示密碼
		{	
			show1(count);
		}
	}
}

//輸入密碼
void input_key()
{
	int i;
	for(i=0;i<4;i++)
	{	
		while(get_key()==-1)//等待按鍵按下
		{
			if(count!=0&&count!=-1)
			{
				show2(count);//顯示設置的密碼
			}
		}
		if(signal==1)//將按鍵的值保存
		{
			get_word[i]=get_key();
			count++;
			show2(count);
			signal=0;
			//temp=99;
		}
		while(temp==get_key())//一旦長時間按按鍵,就一直顯示密碼
		{	
			show2(count);
		}
	}
}
//顯示輸入的密碼
void show2(int count)
{
	if(count==0)//顯示1位數據
	{
		P1=0x0e;
		P0=led[get_word[0]];
	}
	if(count==1)//顯示2位數據
	{
		P1=0x0e;
		P0=led[get_word[0]];
		delay(10);
		P1=0x0d;
		P0=led[get_word[1]];
		delay(10);
	}
	
	if(count==2)//顯示3位數據
	{
		P1=0x0e;
		P0=led[get_word[0]];
		delay(10);
		P1=0x0d;
		P0=led[get_word[1]];
		delay(10);
		P1=0x0b;
		P0=led[get_word[2]];
		delay(10);
	}
	if(count==3)//顯示4位數據
	{
			P1=0x0e;
			P0=led[get_word[0]];
			delay(10);
			P1=0x0d;
			P0=led[get_word[1]];
			delay(10);
			P1=0x0b;
			P0=led[get_word[2]];
			delay(10);
			P1=0x07;
			P0=led[get_word[3]];
			delay(10);
			P0=0;
			//count=-1;
			signal=0;
	} 
}
//顯示設置的密碼
void show1(int count)
{
	int i;
	if(count==0)//顯示一位數據
	{
		P1=0x0e;
		i=key_word[0];
		P0=led[i];
	}
	if(count==1)//顯示兩位數據
	{
		P1=0x0e;
		P0=led[key_word[0]];
		delay(10);
		P1=0x0d;
		P0=led[key_word[1]];
		delay(10);
	}
	
	if(count==2)//顯示三位數據
	{
		P1=0x0e;
		P0=led[key_word[0]];
		delay(10);
		P1=0x0d;
		P0=led[key_word[1]];
		delay(10);
		P1=0x0b;
		P0=led[key_word[2]];
		delay(10);
	}
	if(count==3)//顯示四位數據
	{
		P1=0x0e;
		P0=led[key_word[0]];
		delay(10);
		P1=0x0d;
		P0=led[key_word[1]];
		delay(10);
		P1=0x0b;
		P0=led[key_word[2]];
		delay(10);
		P1=0x07;
		P0=led[key_word[3]];
		delay(10);
		P0=0;
		count=-1;
		signal=0;
	}
}


//主函數
void main()
{
	int op;
	LED1=0;
	Beep=1;
	while(1)
	{
		op=get_key();
		switch(op)
		{
			case 13:
					while(temp==get_key());//等待選擇功能按鍵釋放後再進行設置密碼
					count=-1;//在使用標誌位時將標誌位進行初始化
					signal=1;
					set_key();
					break;
			
			case 14:
					while(temp==get_key());
					count=-1;//初始化標誌位
					signal=1;
					input_key();
					while(get_key()!=15)//當按下登陸鍵,輸入的密碼不再顯示
					{
						show2(count);
					}
					if(compare()==-1)
					{
						count1++;
						while(get_key()!=14&&count1!=3)
						{
							show3();//密碼錯誤,顯示ERR
						}
						P0=0;//按下輸入密碼鍵後,清屏
						if(count1==3)
						{
							//開啓定時器中斷
							TMOD=0x01;
							TH0=0x9E;//裝載初值25ms
							TL0=0x58;
							EA=1; //開總中斷
							ET0=1;//開定時器0
							TR0=1;  //開啓定時器0
							while(counter1<60);//只有當蜂鳴器響完一分鐘之後,才能退出循環
							TR0=0;//關閉定時器
					     }
					}
					else
					{	
						LED1=1;//當輸入密碼正確時,開啓LED燈
						while(get_key()!=12)//直到按下退出鍵,屏幕一直顯示on
						{
							show4();
						}
						LED1=0;//退出後關閉LED燈
						P0=0;//清屏
					}
					break;
			default:break;		
		}
	}

}

//獲取鍵值
int get_key()
{
	char key_scan[]={0xef,0xdf,0xbf,0x7f};
	int i=0;
	int j=0;
	for(i=0;i<4;i++)//判斷
	{
		P2=key_scan[i];
		if((P2&0x0f)!=0x0f)
		{
			for(j=0;j<16;j++)
			{
				if(key_buf[j]==P2)
				{
					if(temp!=key_buf[j])//一旦長時間按鍵,將只會讀取一次按鍵的值
					{
						signal=1;
						temp=j;
						return j;
					}
					else signal=0;
				}
			}
		}
	}
	return -1;
}




//輸入的密碼和設定的密碼比較
int compare()
{
	int i;
	for(i=0;i<4;i++)
	{
		if(get_word[i]!=key_word[i])
			return -1;//輸入密碼不等於設定的密碼返回-1
	}
	return 1;//輸入的密碼等於設定密碼返回1
}

void show3()//顯示ERR
{
	P1=0x0e;
	P0=0x79;
	delay(10);
	P1=0x0d;
	P0=0x77;
	delay(10);
	P1=0x0b;
	delay(10);
}
void show4()//顯示on
{
	P1=0x0e;
	P0=0x5c;
	delay(10);
	P1=0x0d;
	P0=0x54;
	delay(10);
}

//定時器中斷函數,定時1分鐘
call_police() interrupt 1
{
	counter++;
	if(counter==39)
	{	
		counter=0;
		Beep=~Beep;
		counter1++;
		if(counter1==60)//定時一分鐘
		{
			count1=0;
			Beep=1;//關閉定時器
		}
	}
	else
	{
		TH0=0x9E;
		TL0=0x58;
	}
}

6.仿真結果圖

在這裏插入圖片描述

7.工程源碼及protues仿真下載

點擊下載工程源碼
點擊下載protues仿真程序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章