天天看點

noob的第一步——基于51單片機的指紋密碼鎖主程式部分

基于51單片機的指紋密碼鎖

  • 主程式部分

主程式部分

/*頭檔案*/ 
#include <reg52.h>
#include <intrins.h>
#include "LCD12864.h"
#include "at24c02.h"


/*定義特殊端口,和特殊寄存器*/
#define buffer1ID 0x01
#define buffer2ID 0x02
#define confirm 0x88
#define quit 0x84
#define backspace 0x82

/*定義使用者*/ 
#define user 1
void begin();

sbit B0=B^0;
sbit B7=B^7;
sbit k2=P3^7;
sbit jidianqi=P3^6;
sbit feng=P2^0;

/*定義全局變量*/
extern unsigned char times[];
unsigned char member=1,sec;
unsigned char errorcount;
unsigned char code buffer[user][6]=
{
	{"000000"}
} ;
unsigned char dz[4];
unsigned char time[4];
unsigned char password[6];
unsigned char passwordid[6]={1,2,3,4,5,6};

unsigned char address1=20,tempx=20;
unsigned char address2=20;

unsigned char data K;         /*K代表按下後産生的數字*/ 
unsigned char data key;       /*key代表按鍵電位情況*/ 

unsigned int pageid;
unsigned char data confirmcode=11;
unsigned char sum[2];
int summaf,summas;

unsigned char xdata userpassword[7]={0};//用來儲存正确的密碼
unsigned char xdata fingerprint_holder[16]={0};//用來儲存正确的指紋

/*定義延時函數*/
void delayms(unsigned int t)
{
	unsigned int i,j;
	for(i=t;i>0;i--);
	for(j=110;j>0;j--);
} 
/*定義指紋脈沖相關函數*/ 
void redray_init(void);
#include "zhiwen.h"
unsigned char redray_change(unsigned char rednum);
/*第一部分-硬體功能定義*/ 
/*第一部分-第一子產品
串行通信子產品,對單片機序列槽進行初始化。*/ 
//設定序列槽
void UsartConfiguration()
{
	SCON=0x50;      //設定為工作方式1 //REN=1 允許接收 
	TMOD=0x21;      //設定計數器工作方式2 
	PCON=0x00;      //SMOD=1 波特率加倍 
	TH1=0xFD;       //計數器初始值設定,波特率9600 
	TL1=0xFD;        
	TR1=1;           //打開總中斷 
	EA=1;           //打開計數器 
}

/*第一部分-第二子產品
矩陣鍵盤子產品,這裡采取整體掃描。*/ 
//整體掃描
void keyboard(unsigned char key)
{
	if(key!=0)//倘若按下了,也就是說有m輸入,m不為零 
	{
		switch(key)
		{
			case(0x11):K=1;break;
			case(0x21):K=2;break;
			case(0x41):K=3;break;
			case(0x81):K='A';break;
			case(0x12):K=4;break;
			case(0x22):K=5;break;
			case(0x42):K=6;break;
			case(0x82):K=34;break;		
			case(0x14):K=7;break;
			case(0x24):K=8;break;
			case(0x44):K=9;break;
			case(0x84):K='C';break;
			case(0x18):K='*';break;
			case(0x28):K=0;break;
			case(0x48):K=11;break;
			case(0x88):K='D';break;
			default:break;						
		}
	} 
}

unsigned char keyscan(void)
{
	unsigned char rowcode,colcode;
	P1=0xf0;
	if((P1&0xf0)!=0xf0)//有鍵按下 
	{
		delayms(1);//延時去按鍵抖動
		if((P1&0xf0)!=0xf0)//再次檢測
		{
			rowcode=0xfe;
			while((rowcode&0x10)!=0)//逐行掃描初值 
			{
				P1=rowcode;//輸出行掃描碼
				if((P1&0xf0)!=0xf0)//本行有鍵按下。 
				{
					colcode=(P1&0xf0)|0x0f;
					while((P1&0xf0)!=0xf0)//按鍵釋放
					return ((~rowcode)+(~colcode)); //傳回鍵的編碼 
				}
				else
				rowcode=(rowcode<<1)|0x01; //行掃描碼左移一位 
			}
		} 
	}
	return 0; 
}
/*這兩部分用額外的函數子產品寫在外部檔案裡面。*/ 
/*第一部分-第三子產品	
LCD12864函數內建子產品,采用的是并行寫法。
具有顯示,清除文字,清除圖檔等功能。*/

/*第一部分-第四子產品
AT24C02晶片部分,是用作存儲密碼的。*/ 

/*第二部分功能實作
第二部分-第一子產品:在部分庫中檢查密碼是否正确,正确傳回1,錯誤傳回0*/
unsigned char check(unsigned char user_password)
{
	unsigned char flag,i,temp[6],address;
	address=user_password*10;
	for(i=0;i<6;i++)//密碼規定6位,故讀到第六位就可以了 
	{
		temp[i]=readoutrom(address);
		delayms(10);
		address++;
	}
	for(i=0;i<6;i++)
	{
		if(temp[i]==userpassword[i])
		flag=1;
		else
		flag=0;
	}
	return flag;
}

/*在全體庫中檢測密碼是否正确*/
unsigned char password_check()
{
	unsigned char i=0;
	while(i<user)
	{
		if(check(i)==1)
		{
			member=i+1;
			return 1;
		}
		i++;
	}
	return 0;
} 
 
/*第二部分-第三子產品:手動開鎖*/
void use_hand()
{
	lcdcleartxt();//在每次顯示新的内容前,先清屏 
	lcddisplay_string(1,2,"門已開啟");
	jidianqi=0;
	delayms(2500);
	jidianqi=1;
	lcddisplay_string(3,0,"按任意鍵繼續");
	while(keyscan()==0);
		lcddisplay_string(0,0,"數字1:增加指紋");
		lcddisplay_string(1,0,"數字2:删去指紋");
		lcddisplay_string(2,0,"數字3:手動開鎖");
		lcddisplay_string(3,0,"數字4:修改密碼");	 
} 

/*第二部分-第二子產品
輸入密碼後開鎖的判斷*/
void use_password()
{
	unsigned char i,j=0,x=1;
	unsigned char flag1;
	lcdcleartxt();
	lcddisplay_string(1,0,"請輸入密碼開鎖:");
	for(i=0;i<6;i++)password[i]=0;
	key=keyscan();
	while(key!=confirm)
	{
		key=keyscan();
		keyboard(key);
		delayms(30);
		if(key==0)K=10;
		if((K>=0)&&(K<=9))
		{
			password[j]=K;
			if(j<6)
			{
				lcdwritecommand(0x89+j);//指定第三行為顯示密碼輸入的空位 
				lcdwrite(0x0f);
			}
			++j;
			if(j==7)
			j=6;
		}//lcd12864并行顯示 
		if(K==34)//按了删除鍵 
		{
			if(j==0)
			{
				lcdwritecommand(0x89);  //指定第三行為顯示密碼輸入的空位
				lcdwrite(0x20); 
			}
			else
			{
				--j;
				lcdwritecommand(0x89+j);//指定第三行為顯示密碼輸入的空位
				lcdwrite(0x20);
			}
		}
	}
	lcdcleartxt();
	for(i=0;i<6;i++)
	{
		userpassword[i]=password[i]+0x30;
	}
	if(j==6)
	{
		flag1=password_check();
	}
	if(flag1==1&&errorcount<3)//判斷輸入是否合規
	{
		flag1=0;
		use_hand();
		errorcount=0;//錯誤次數歸零 
		feng=1;
		for(i=0;i<6;i++)password[i]=0;
	} 
	else
	{
		if(errorcount<3)//如果密碼錯誤次數小于3次 
		{
			errorcount++;
			lcddisplay_string(1,2,"密碼錯誤");
			lcddisplay_string(2,0,"還有 次嘗試");
			lcddisplay_string(3,0,"按任意鍵繼續");
			lcdwritecommand(0x8a);
			lcdwrite(' ');
			lcdwrite(3-errorcount+0x30); 
		}
		if(errorcount==3)
		{
			feng=0;
			lcdcleartxt();
			lcddisplay_string(1,0,"已鎖死");
			lcddisplay_string(2,0,"請使用指紋"); 
		}
		delayms(1000);
	}
	key=0;
	lcdcleartxt();
}
/*第二部分-第三子產品:輸入指紋後的開鎖判斷*/
void use_fingerprint()
{
	unsigned char ids1,ids2,ids3;
	lcdcleartxt();
	lcddisplay_string(1,1,"請按手指開鎖");
	SFG_identify();
	while(confirmcode==2)
	SFG_identify();
	if(confirmcode==0)
	{
		lcdcleartxt();
		lcddisplay_string(1,2,"門已打開");
		ids1=pageid/100;
		ids2=pageid/10%10;
		ids3=pageid%10;
		lcddisplay_string(2,1,"編号為");
		lcdwritecommand(0x8d);
		lcdwrite(0x30+ids1);
		lcdwrite(0x30+ids2);
		lcdwrite(0x30+ids3);
		errorcount=0;
		feng=1;
		jidianqi=0;
		delayms(2500);
		jidianqi=1;
	}
	else if(confirmcode==9)
	{
		lcdcleartxt();
		lcddisplay_string(1,1,"沒找到該指紋");
		lcddisplay_string(2,1,"請重新按壓");
		errorcount=3;
		feng=0;
	} 
	else
	{
		lcdcleartxt();
		lcddisplay_string(1,1,"接受器出錯"); 
	}
	delayms(2000);
}

/*第二部分-第四子產品:修改指紋,分為添加指紋和删除指紋*/
void addfingerprint()
{
	unsigned char ida1,ida2,ida3;
	lcdcleartxt();
	lcddisplay_string(1,2,"請輸入指紋");
	SFG_getimage();
	while(confirmcode!=0)
	SFG_getimage();
	SFG_genchar(buffer1ID);
	UsartConfiguration();
	SFG_fastsearch(buffer1ID);
	while(confirmcode==1)
	SFG_fastsearch(buffer1ID);
	if(confirmcode==0)
	{
		lcdcleartxt();
		lcddisplay_string(1,1,"");
		lcddisplay_string(3,0,"");
		while(keyscan()==0);
	}
	else if(confirmcode==9)
	{
		lcdcleartxt();
		lcddisplay_string(1,1,"請再次輸入指紋");
		SFG_enroll();
		while(confirmcode==2)
		SFG_enroll();
		lcdcleartxt(); 
		if(confirmcode==0)
		{
			ida1=pageid/100;
			ida2=pageid/10%10;
			ida3=pageid%10;
			lcddisplay_string(1,1,"指紋采內建功");
			lcddisplay_string(2,1,"編号為:");
			lcdwritecommand(0x8d);
			lcdwrite(0x30+ida1);
			lcdwrite(0x30+ida2);
			lcdwrite(0x30+ida3);
		}
		else if(confirmcode!=0)
		{
			lcddisplay_string(1,1,"指紋采集失敗");
			lcddisplay_string(2,1,"請重新操作");
		}
		lcddisplay_string(3,0,"按任意鍵繼續");
		while(keyscan()==0); 
	}
	lcdcleartxt();
	lcddisplay_string(0,0,"數字1:增加指紋");
	lcddisplay_string(1,0,"數字2:删去指紋");
	lcddisplay_string(2,0,"數字3:手動開鎖");
	lcddisplay_string(3,0,"數字4:修改密碼");
}

void deletefingerprint()
{
	unsigned char i,j=0;
	lcdcleartxt();
	lcddisplay_string(1,0,"輸入想删除的指紋号");
	for(i=1;i<5;i++)dz[i]=0;
	key=keyscan();
	while(key!=confirm)
	{
		key=keyscan();
		keyboard(key);
		delayms(30);
		if(key==0)K=10;
		if((K>=0)&&(K<=9))
		{
			dz[j]=K;
			if(j<3)
			{
				lcdwritecommand(0x88+j);
				lcdwrite(0x30+dz[j]);
			}
			++j;
			if(j==4)
			j=3;
		}
		if(K==34)//照常删除鍵
		{
			if(j==0)
			{
				lcdwritecommand(0x88);
				lcdwrite(0x20);
			}
			else
			{
				--j;
				lcdwritecommand(0x88+j);
				lcdwrite(0x20);
			}
		} 
	}
	if(j>=2)pageid=dz[2]+dz[1]*10+dz[0]*100;
	if(j==1)pageid=dz[1]+dz[0]*10;
	if(j==0)pageid=dz[0];
	SFG_deletchar(pageid);
	if(confirmcode==0)
	{
		lcdcleartxt();
		lcddisplay_string(1,1,"成功删除指紋号。");
	}
	else
	{
		lcdcleartxt();
		lcddisplay_string(1,2,"删除指紋号失敗。");
	}
	lcddisplay_string(2,0,"按任意鍵繼續");
	while(keyscan()==0);
	lcdcleartxt();
	lcddisplay_string(0,0,"數字1:增加指紋");
	lcddisplay_string(1,0,"數字2:删去指紋");
	lcddisplay_string(2,0,"數字3:手動開鎖");
	lcddisplay_string(3,0,"數字4:修改密碼");	
} 

/*第二部分-第五子產品:修改密碼*/
void changepass()
{
	unsigned char i,j=0,password1[6],password2[6];
	unsigned char k,temp;
	lcdcleartxt();
	lcddisplay_string(1,1,"請輸入新密碼");
	for(i=0;i<6;i++)password1[i]=0;
	key=keyscan();
	while(key!=confirm)
	{
		key=keyscan();
		keyboard(key);
		delayms(30);
		if(key==0)K=10;
		if((K>=0)&&(K<=9))
		{
			password1[j]=K;
			if(j<6)
			{
				lcdwritecommand(0x89+j);
				lcdwrite(0x0f);
			}
			++j;
			if(j==7);
			j=6;
		} 
		if(K==34)
		{
			if(j==0)
			{
				lcdwritecommand(0x89);
				lcdwrite(0x0f);
			}
			else
			{
				--j;
				lcdwritecommand(0x89+j);
				lcdwrite(0x20);
			}
		}
	}
 	lcdcleartxt();
	lcdcleartxt();
	j=0;
	lcddisplay_string(1,0,"請再次輸入新密碼"); 
	for(i=0;i<6;i++)password2[i]=0;
	key=keyscan();
	while(key!=confirm)
	{
		key=keyscan();
		keyboard(key);
		delayms(30);
		if(key==0)K=10;
		if((K>=0)&&(K<=9))
		{
			password2[j]=k;
			if(j<6)
			{
				lcdwritecommand(0x89+j);
				lcdwrite(0x0f);
			}
			++j;
			if(j==7);
			j=6;
		} 
		if(K==34)//按了删除鍵 
		{
			if(j==0)
			{
				lcdwritecommand(0x89);
				lcdwrite(0x20);
			}
			else
			{
				--j;
				lcdwritecommand(0x89+j);
				lcdwrite(0x20);
			}
		}
	}
	lcdcleartxt();
	if((password1[0]==password2[0])&&(password1[1]==password2[1])&&(password1[2]==password2[2])&&(password1[3]==password2[3])&&(password1[4]==password2[4])&&(password1[5]==password2[5]))
	{
		for(i=1;i<6;i++)
		passwordid[i]=password1[i];
		for(i=0;i<6;i++)
		{
			userpassword[i]=password+0x30;
		}
		temp=1;
		delayms(5);
		for(k=0;k<6;k++)
		{
			writeinrom(temp,userpassword[k]);
			delayms(10);
			temp++;
		}
		lcddisplay_string(0,1,"密碼修改成功");
		lcddisplay_string(3,0,"按任意鍵繼續");
		errorcount=0;
		while(keyscan()==0);
	}	
	else
	{
		lcddisplay_string(0,0,"密碼修改失敗");
		lcddisplay_string(1,0,"兩次輸入的密碼不");
		lcddisplay_string(2,0,"一緻,請重新操作");
		lcddisplay_string(3,0,"按任意鍵繼續");
		while(keyscan()==0); 
	}
	lcdcleartxt();
	lcddisplay_string(0,0,"數字1:增加指紋");
	lcddisplay_string(1,0,"數字2:删去指紋");
	lcddisplay_string(2,0,"數字3:手動開鎖");
	lcddisplay_string(3,0,"數字4:修改密碼");
}

/*第二部分-第六子產品:背景管理者設定*/
void administrator()
{
	unsigned char i,j=0,x=1;
	unsigned char flag2;
	lcdcleartxt();
	lcddisplay_string(1,1,"請輸入密碼:");
	for(i=0;i<6;i++)password[i]=0;
	key=keyscan();
	while(key!=confirm)
	{
		key=keyscan();
		keyboard(key);
		delayms(30);
		if(key==0)K=10;
		if((K>=0)&&(K<=9))
		{
			password[j]=K;
			if(j<6)
			{
				lcdwritecommand(0x89+j);//同樣的第三行顯示密碼 
				lcdwrite(0x0f);
			}
			++j;
			if(j==7)
			j=6;
		}
		if(K==34)
		{
			if(j==0)
			{
				lcdwritecommand(0x89);//同樣的第三行顯示密碼 
				lcdwrite(0x20);
			}
			else
			{
				--j;
				lcdwritecommand(0x89+j);
				lcdwrite(0x20);
			}
		}
	}
	lcdcleartxt();
	for(i=0;i<6;i++)
	{
		userpassword[i]=password[i]+0x30;
	} 
	if(j==6)
	{
		if(password[0]==1&&password[1]==2&&password[2]==3&&password[3]==4&&password[4]==5&&password[5]==6)//設定背景管理密碼
		flag2=1;
		else
		flag2=0; 
	}
	if(flag2==1)
	{
		flag2=0;
		for(i=0;i<6;i++)password[i]=0;
		lcddisplay_string(0,0,"數字1:增加指紋");
		lcddisplay_string(1,0,"數字2:删去指紋");
		lcddisplay_string(2,0,"數字3:手動開鎖");
		lcddisplay_string(3,0,"數字4:修改密碼");
		while(i!=quit)
		{
			i=keyscan();
			keyboard(i);
			switch(K)
			{
				case 1:use_hand();K=8;break;
				case 2:changepass();break;
				default:break;
			}
		}
	}
	else
	{
		lcddisplay_string(1,2,"密碼錯誤");
		lcddisplay_string(2,0,"請重新操作");
		lcddisplay_string(3,0,"按任意鍵繼續");
		while(keyscan()==0);
		lcddisplay_string(0,0,"數字1:增加指紋");
		lcddisplay_string(1,0,"數字2:删去指紋");
		lcddisplay_string(2,0,"數字3:手動開鎖");
		lcddisplay_string(3,0,"數字4:修改密碼");
	}
	key=0;
}
 
/*第二部分-第七子產品:界面的設計與邏輯*/
void begin()
{
	if(key!=0x81)   //沒按管理者鍵 
	{
		lcddisplay_string(0,2,"歡迎使用");
		lcddisplay_string(1,1,"密碼鎖");
		lcddisplay_string(2,1,"請按c鍵開鎖");
		lcddisplay_string(3,1,"請輸入指紋開鎖"); 
	}
	key=keyscan();
	if(k2==1)
	{
		lcdcleartxt();
		use_fingerprint();
		lcdcleartxt();
	}
	if(key==0x81)//背景管理者模式 
	{
		lcdcleartxt();
		administrator();
		lcdcleartxt();
	}
	if(key==0x84&&errorcount<3)//選擇用密碼開鎖 
	{
		lcdcleartxt();
		use_password();
		lcdcleartxt();
	}
} 

void main()
{
	UsartConfiguration();
	at24c02_init();
	lcdinit();
	lcdcleartxt();
	while(1)
	{
		begin();
		delayms(100);
	}
}

           

繼續閱讀