天天看点

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);
	}
}

           

继续阅读