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