//S1-S9为数字密码输入键0-9
//S10-S13为功能键
//S10为单个数字删除键,S11为所以数字清除键,S12为密码确认键,S13为修改密码键
#include<reg52.h> //包含头文件
#include"IIC.h" //包含IIC总线头文件
#include"1602.h" //包含1602头文件
#include"keyboard.h" //包含键盘扫描头文件
sbit led_gre = P2^6; //位定义绿灯,密码输入正确时显示
sbit led_red = P2^7; //位定义红灯,密码输入错误时显示
sbit spk=P3^7;
uchar ASC[]={'0','1','2','3','4','5','6','7','8','9'}; //将数字转换成字符型数据供1602显示
uchar one=0,two=1,three=2,four=3; //初始密码0123
uint t0,t1; //定时器0、1分别溢出的次数
void Init_time0(void) //定时器0初始化函数
{
TMOD=0x11;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
TH1=(65535-2000)/256;
TL1=(65535-2000)%256;
EA=1;
ET0=1;
ET1=1;
TR0=0;
TR1=0;
}
void main(void) //主函数
{
uchar flag=0,cflag=0;
//flag、cflag分别为修改密码标志和修改密码时初始密码输入正确标志(输入新密码标志)
uchar i=0,k=0;
//i为输入密码时输入数字密码的个数
//k为修改密码时输入数字密码的个数
uchar j=0,t=0,shu=1;
//j用于for循环中判断输入密码和存储密码对比
//t=0为进入修改密码状态,只要是为了修改密码时的初始显示
//shu用于输入新密码时,四位密码的地址
uchar num,newpassword[4];
//num为按键值,newpassword数组存放每次输入的数字密码S0-S13和0-13对应
Init_IIC(); //初始化IIC
Init_1602(); //初始化1602
Init_time0(); //初始化定时器0
led_red=0; //熄灭绿灯和红灯
led_gre=0;
spk=0;
write_add(1,one); //写入初始密码0123到E2PROM
delay_ms(5);
write_add(2,two);
delay_ms(5);
write_add(3,three);
delay_ms(5);
write_add(4,four);
delay_ms(5);
displaylistchar(0,0,"Input Password:"); //1602初始化后显示Input Password:
led_red = 1;
while(1)
{
/*检测是否有按键按下,若没有则不停扫描*/
num=KeyPro(); //扫描按键
if(num!=0xff) //如果有键按下
{
/*******************************************************************************************/
/*输入密码*/
if((num!=12)&&(flag==0)) //S12为修改密码键,flag为修改密码标志,flag=1时修改密码,判断是否修改密码
{
displaylistchar(0,0,"Input Password:");
if(num>=0&&num<=9) //如果是0-9按下,则输入0-9并在液晶上显示0-9
{
TR0=~TR0; //若按键后五秒内没有打开锁,则报警
t0=0;
displayonechar(i,1,ASC[num]); //显示输入的数字密码
newpassword[i++]=num;
}
if(num==15) //如果10按下,在有数字输入的情况下删除上次输入的数字
{
TR0=~TR0; //若按键后五秒内没有打开锁,则报警
t0=0;
if(i>0)
{
i=i-1;
displayonechar(i,1,' ');
}
}
if(num==14) //如果是14按下,清除所有输入的数据,重新输入
{
TR0=0;
i=0;
displaylistchar(0,1," ");//清除该行
}
if(num==11) //上锁
{
TR0=0;
i=0;
led_gre=0;
led_red=1; //亮红灯
displaylistchar(0,1," ");//清除该行
}
if(num==10) //确认键,如果密码正确,则绿灯亮红灯熄,否则则红灯亮绿灯熄
{
TR0=0;
if(i==4) //四位密码,所以只在输入四个密码的情况下检测密码是否正确
{
for(j=0;j<4;j++)
{
if(newpassword[j]!=read_add(j+1)) //输入的密码和存储的密码对比,若有一个错误,则跳出密码对比
break;
}
if(j==i) //若j=i成立,则密码正确
{
led_gre=1; //亮绿灯
led_red=0;
displaylistchar(0,1,"Right Open!"); //显示输入正确
delay_ms(1000);
i=0; //按键输入数置0
displaylistchar(0,1," ");//清除该行
}
else //若不成立则密码不正确
{
led_gre=0; //亮红灯
led_red=1;
displaylistchar(0,1,"Wrong Retry!"); //显示输入错误
delay_ms(1000);
i=0; //按键输入数置0
displaylistchar(0,1," ");//清除该行
}
}
else //若按键输入数i不等于4,则密码肯定错误
{
led_gre=0; //亮红灯
led_red=1;
displaylistchar(0,1,"Wrong Retry!"); //显示输入错误
delay_ms(1000);
i=0; //按键输入数置0
displaylistchar(0,1," ");//清除该行
}
}
if(i==6) //虚设六位密码,数字按键输入六次后还没有按确定的话,则提示密码错误
{
TR0=0;
led_gre=0; //亮红灯
led_red=1;
displaylistchar(0,1,"Wrong Retry!"); //显示输入错误
delay_ms(1000);
i=0; //按键输入数置0
displaylistchar(0,1," ");//清除该行
}
}
/*******************************************************************************************/
/*******************************************************************************************/
/*修改密码*/
else //有S13键按下或修改密码标志flag置1
{
if(cflag==0) //修改密码时初始密码输入正确标志cflag置0时为输入初始密码检测状态,类似前面的密码输入
{
i=0; //按键输入数置0
flag=1; //S13键按下,修改密码标志置1
if(t==0) //t=0为进入修改密码状态,只要是为了修改密码时的初始显示
{
displaylistchar(0,0,"Change Password:");
delay_ms(500);
displaylistchar(0,1,"Old Password:");
delay_ms(500);
displaylistchar(0,1," ");//清除该行
}
t++; //正在修改密码状态,则不用再次进入修改密码状态
if(num>=0&&num<=9) //如果是0-9按下,则输入0-9并在液晶上显示0-9
{
TR0=~TR0; //若按键后五秒内没有打开锁,则报警
t0=0;
displayonechar(k,1,ASC[num]);
newpassword[k++]=num;
}
if(num==15) //单个密码删除键,和输入密码时一样
{
TR0=~TR0; //若按键后五秒内没有打开锁,则报警
t0=0;
if(k>0)
{
k=k-1;
displayonechar(i,1,' ');
}
}
if(num==14) //所以密码清除键,和输入密码时一样
{
TR0=0;
k=0;
flag=0;
displaylistchar(0,1," ");//清除该行
}
if(num==10) //确认键,和输入密码时一样
{
TR0=0;
if(k==4)
{
for(j=0;j<4;j++)
{
if(newpassword[j]!=read_add(j+1))
break;
}
if(j==k) //若初始密码输入正确后提示输入新密码,并将输入新密码标志cflag置1
{
led_gre=1;
led_red=0;
displaylistchar(0,1,"Right Open!");
delay_ms(500);
displaylistchar(0,1," ");//清除该行
displaylistchar(0,1,"New Password:");
delay_ms(500);
displaylistchar(0,1," ");//清除该行
k=0;
cflag=1;
}
else //若输入错误,则跳出密码修改,flag=0
{
led_gre=0;
led_red=1;
displaylistchar(0,1,"Wrong Retry!");
delay_ms(1000);
k=0;
flag=0;
displaylistchar(0,1," ");//清除该行
displaylistchar(0,0," ");//清除该行
displaylistchar(0,0,"Input Password:");
}
}
else //修改密码时输入原密码数不等于4,显然密码错误,跳出密码修改
{
led_gre=0;
led_red=1;
displaylistchar(0,1,"Wrong Retry!");
delay_ms(1000);
k=0;
flag=0;
displaylistchar(0,1," ");//清除该行
displaylistchar(0,0," ");//清除该行
displaylistchar(0,0,"Input Password:");
}
}
if(k==6) //数字按键输入六次后还没有按确定的话,则提示密码错误 ,跳出密码修改
{
TR0=0;
led_gre=0;
led_red=1;
displaylistchar(0,1,"Wrong Retry!");
delay_ms(1000);
k=0;
flag=0;
displaylistchar(0,1," ");//清除该行
displaylistchar(0,0," ");//清除该行
displaylistchar(0,0,"Input Password:");
}
}
else //输入新密码标志置1,输入新密码并显示新输入的密码
{
if(num>=0&&num<=9)
{
write_add(shu,num);
displayonechar(shu-1,1,ASC[num]);
shu++;
if(shu==5)
{
t=0;
shu=1;
cflag=0;
flag=0;
displaylistchar(0,1,"Change Success!");
delay_ms(500);
displaylistchar(0,0," ");//清除该行
displaylistchar(0,1," ");//清除该行
displaylistchar(0,0,"Input Password:");
}
}
}
}
}
}
}
void time0(void) interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
t0++;
if(t0==100)
{
t0=0;
TR0=0;
TR1=1;
}
}
void time1(void) interrupt 3
{
TH1=(65535-2000)/256;
TL1=(65535-2000)%256;
t1++;
spk=~spk;
if(t1==5000)
{
t1=0;
TR1=0;
}
}
AT89C51实现proteus密码锁仿真
最新推荐文章于 2024-01-21 17:33:59 发布