基于单片机密码锁设计.docx
《基于单片机密码锁设计.docx》由会员分享,可在线阅读,更多相关《基于单片机密码锁设计.docx(14页珍藏版)》请在冰豆网上搜索。
基于单片机密码锁设计
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitlcdrs=P1^0;//液晶数据、指令端
sbitwr=P1^1;//读、写端
sbitlcden=P1^2;//液晶使能端
sbitbeep=P1^4;
sbitled=P1^3;//扬声器
ucharcodetable[]={"enterpassword:
"};
ucharcodetable1[]={"error!
tryagain:
"};
ucharcodetable2[]={"welcome!
!
!
"};
ucharcodetable4[]={"setpassword:
"};
ucharcodetable5[]={"inputagain:
"};
ucharcodetable6[]={"badluck!
"};
ucharcodetable7[]={"getout!
!
"};
ucharcodetable8[]={"setsucceed"};
bitflag,flag1,flag2,flag3,flag4,flag5,rst;
ucharkey,count;
voiddelayms(uintx)
{
uinti,j;
for(i=x;i>0;i--)//延时函数
for(j=110;j>0;j--);
}
voidwrite_com(ucharcom)//液晶写指令函数
{
wr=0;
lcdrs=0;
P2=com;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
voidwrite_data(uchardate)//液晶写数据函数
{
wr=0;
lcdrs=1;
P2=date;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
voidlcdinit()//液晶初始化函数
{
lcden=0;
write_com(0x38);
write_com(0x06);
write_com(0x0f);
write_com(0x01);
}
voiddi()//蜂鸣器发生函数
{
beep=0;
led=1;
delayms(5000);
beep=1;
}
voidkeyscan()//键盘扫描函数
{
uchartemp;
P3=0xfe;
if(P3!
=0xfe)
{
delayms(8);
if(P3!
=0xfe)
{
temp=0xf0&P3;
switch(temp)
{
case0xe0:
key=0;flag5=1;break;//数字键盘按下时显示‘*‘字符,把对应的数字放入数组中
case0xd0:
key=1;flag5=1;break;//flag5为1时才能把数据放进数组,只是为了防止删减密码
case0xb0:
key=2;flag5=1;break;//时把key的值装进已输入正确的密码中
case0x70:
key=3;flag5=1;break;
}
while(P3!
=0xfe);
write_data('*');
count++;
}
}
P3=0xfd;
if(P3!
=0xfd)
{
delayms(8);
if(P3!
=0xfd)
{
temp=0xf0&P3;
switch(temp)
{
case0xe0:
key=4;flag5=1;break;
case0xd0:
key=5;flag5=1;break;
case0xb0:
key=6;flag5=1;break;
case0x70:
key=7;flag5=1;break;
}
while(P3!
=0xfd);
write_data('*');
count++;
}
}
P3=0xfb;
if(P3!
=0xfb)
{
delayms(8);
if(P3!
=0xfb)
{
temp=0xf0&P3;
switch(temp)
{
case0xe0:
key=8;write_data('*');flag5=1;count++;break;
case0xd0:
key=9;write_data('*');flag5=1;count++;break;
case0xb0:
flag=1;break;
case0x70:
rst=1;break;
}
while(P3!
=0xfb);
}
}
P3=0xf7;
if(P3!
=0xf7)
{
delayms(8);
if(P3!
=0xf7)
{
temp=0xf0&P3;
switch(temp)
{
case0xe0:
switch(count)
{
case1:
write_com(0xc5);write_data('');write_com(0xc5);break;//当按下clean键时,往前一个地址显示空字符,
case2:
write_com(0xc6);write_data('');write_com(0xc6);break;//再把指针指回前一个地址
case3:
write_com(0xc7);write_data('');write_com(0xc7);break;
case4:
write_com(0xc8);write_data('');write_com(0xc8);break;
case5:
write_com(0xc9);write_data('');write_com(0xc9);break;
case6:
write_com(0xca);write_data('');write_com(0xca);break;
}
if(0break;
}
while(P3!
=0XF7);
}
}
}
voidmain()
{
uchara[6],b[6],i,num,table3[6]={1,2,3,4,5,6};//初始化原始密码为“123456”
lcdinit();//液晶初始化
while
(1)
{
keyscan();//键盘扫描
if(!
flag3)
{
write_com(0x0f);//标志位flag3为0时,
write_com(0x80);//显示“enterpassword:
”字符串
for(i=0;i<15;i++)
write_data(table[i]);
write_com(0xc5);//令光标在液晶第二行中间闪烁
flag3=1;//flag3为1时不显示“enterpassword:
”字符串,因为不停扫描此语句时会造成字符串的闪烁
}
if(num<=2)//控制密码的输入次数为三次,超过了就不能再输入
{
if(flag5)
{
switch(count)
{
case1:
a[count-1]=key;break;//把输入的六位密码
case2:
a[count-1]=key;break;
case3:
a[count-1]=key;break;
case4:
a[count-1]=key;break;
case5:
a[count-1]=key;break;
case6:
a[count-1]=key;break;
}
flag5=0;//防止clean键按下时把正确的密码改掉
}
if(count==6)//输入的数为够六位执行,密码正确时进入
{
if((a[0]==table3[0])&&(a[1]==table3[1])&&(a[2]==table3[2])&&(a[3]==table3[3])&&(a[4]==table3[4])&&(a[5]==table3[5]))
{
if(!
flag4)
{
write_com(0x01);//显示“welconme字符串”
write_com(0x80);
for(i=0;i<13;i++)
write_data(table2[i]);
write_com(0x0c);//光标闪烁关闭
led=0;
delayms(5000);
led=1;
flag=0;
flag4=1;
rst=0;//清零,执行下面程序
}
while(!
rst)
{
keyscan();
if(flag)
break;
}
while(flag)//flag为1时进入修改密码状态
{
keyscan();
if(!
flag1)
{
write_com(0x01);
write_com(0x0f);
write_com(0x80);
for(i=0;i<13;i++)//显示“setpassword:
”字符串
write_data(table4[i]);
write_com(0xc5);
count=0;
flag1=1;
}
if(flag5)
{
switch(count)
{
case1:
table3[count-1]=key;break;
case2:
table3[count-1]=key;break;
case3:
table3[count-1]=key;break;
case4:
table3[count-1]=key;break;
case5:
table3[count-1]=key;break;
case6:
table3[count-1]=key;break;
}
flag5=0;
}
if(count==6)
{
if(!
flag2)
{
write_com(0x01);//显示“inputagain字符串”
write_com(0x80);
for(i=0;i<12;i++)
write_data(table5[i]);
write_com(0xc5);
flag2=1;
count=0;
}
while
(1)
{
keyscan();
if(flag5)
{
switch(count)//再次输入密码
{
case1:
b[count-1]=key;break;
case2:
b[count-1]=key;break;
case3:
b[count-1]=key;break;
case4:
b[count-1]=key;break;
case5:
b[count-1]=key;break;
case6:
b[count-1]=key;break;
}
flag5=0;
}
if(count==6)//如果第一次输入的密码和第二次相同,输出“setsucceed”字符串
{
if((b[0]==table3[0])&&(b[1]==table3[1])&&(b[2]==table3[2])&&(b[3]==table3[3])&&(b[4]==table3[4])&&(b[5]==table3[5]))
{
led=0;
delayms(5000);
led=1;
write_com(0x01);
write_com(0x80);
for(i=0;i<13;i++)//显示“setsucceed”字符串
write_data(table8[i]);
write_com(0x0c);//光标停止闪烁
flag=0;//所有标志位从新清零
flag1=0;
flag2=0;
flag3=0;
flag4=0;
count=0;
num=0;
while(!
rst)
keyscan();
}
else
{
di();//当进入修改状态第二次输入的密码和第一次不相同时再次输入,知道相同为止
count=0;
write_com(0x01);
write_com(0x80);
for(i=0;i<12;i++)
write_data(table5[i]);//显示“inputagain”
write_com(0xc5);
}
}
if(rst)break;
}
}
if(rst)break;
}
}
else//当第一次输入的密码不正确时,再次输入
{
di();
num++;
if(num<=2)
{
write_com(0x01);
write_com(0x80);
for(i=0;i<16;i++)
write_data(table1[i]);
write_com(0xc5);
count=0;
}
else//第三次还是不正确时不能继续输入密码
{
write_com(0x01);
write_com(0x80);
for(i=0;i<12;i++)
write_data(table6[i]);
write_com(0xc0);
for(i=0;i<12;i++)
write_data(table7[i]);
write_com(0x0c);
while
(1);
}
}
}
}
}
}
功能:
可以输入六位密码,初始密码123456,密码正确显示welcome,并且绿灯亮,亮五秒后自动熄灭。
密码错误时有三次另输入机会,每次错后显示errortryagain三次都错点盘锁住,并显示badluck并且每次输错都伴随着红灯亮,蜂鸣器报警,红灯亮五秒后自动熄灭。
可以从设密码,按键会显示setpassword,如两次输入相同,显示setsecceed,如两次设置输入密码不同,inputagain。
可以删除错误数字。
4*¥矩阵键设键安排
0123
4567
89重设密码无用
删除无用无用无用