44电子密码锁及分析Word格式文档下载.docx
《44电子密码锁及分析Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《44电子密码锁及分析Word格式文档下载.docx(22页珍藏版)》请在冰豆网上搜索。
4行列式键盘的按键功能分布图如图4.33.2所示:
图4.33.2
5.C语言源程序
#include<
AT89X52.H>
unsignedcharps[]={1,2,3,4,5};
初始密码
unsignedcharcodedispbit[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
unsignedcharcodedispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,
0x00,0x40,0x73,0xff};
0X40(-)0x73(P)0xff(日.)
unsignedchardispbuf[8]={18,16,16,16,16,16,16,16};
是否有键按下的标记数
;
组
unsignedchardispcount;
unsignedcharflashcount;
unsignedchartemp;
unsignedcharkey;
unsignedcharkeycount;
unsignedcharpslen=5;
密码长度
unsignedchargetps[6];
存放输入的按键值
bitkeyoverflag;
biterrorflag;
bitrightflag;
unsignedintsecond3;
unsignedintaa,bb;
unsignedintcc;
bitokflag;
bitalarmflag;
bithibitflag;
unsignedcharoka,okb;
voidmain(void)
{
unsignedchari,j;
TMOD=0x01;
一、定时器控制寄存器(TCON)
;
1、TF0(TF1)计数溢出标志位
当计数器计数溢出(计满)时,该位置“1”
查询方式时,此位作状态位供查询,软件清“0”;
中断方式时,此位作中断标志位,硬件自动清“0”。
2、TR0(TR1)定时器运行控制位
TR0(TR1)=0停止定时器/计数器工作
TR0(TR1)=1启动定时器/计数器工作
软件方法使其置“1”或清“0”。
二、工作方式控制寄存器(TMOD)
各位定义如下:
1、GATE门控位
GATE=0以运行控制位TR启动定时器
GATE=1以外中断请求信号(/IMT0或/INT1)启动定时器
2、C/T定时方式或计数方式选择位
C/T=0定时工作方式
C/T=l计数工作方式
3、M1、M0工作方式选择位
M1、M0=00方式0
M1、M0=01方式1
M1、M0=10方式2
M1、M0=11方式3
三、中断允许控制寄存器(IE)
1、EA中断允许总控制位
2、ET0和ET1定时/计数中断允许控制位
ET0(ET1)=0禁止定时/计数中断
ET0(ET1)=1允许定时/计数中断
TH0=(65536-500)/256;
TL0=(65536-500)%256;
0.5
TR0=1;
ET0=1;
EA=1;
while
(1)
P3=0xff;
P3_4=0;
temp=P3;
temp=temp&
0x0f;
11101111&
00001111
if(temp!
=0x0f);
第一行有键按下
for(i=10;
i>
0;
i--)
for(j=248;
j>
j--);
=0x0f);
第一行确实有键按下
switch(temp)
case0x0e:
key=7;
break;
case0x0d:
key=8;
case0x0b:
key=9;
case0x07:
key=10;
};
key选择一个值后跳出,继续。
(判断是0-9的数字键,还是12DEL
键,还是15ENTER键)
P1_1=~P1_1;
if((key>
=0)&
&
(key<
10));
若是数字键则每按一个键keycount加1,同时判
断按键个数是否超出6个
if(keycount<
6)
getps[keycount]=key;
getps[0]=key,按键数小于6时,将值存入
getps[keycount]
dispbuf[keycount+2]=19;
dispbuf[0+2]=19
dispbuf[8]={18,16,19,16,16,16,16,16};
:
dispbuf[8]={18,16,19,19,16,16,16,16}
}
keycount++;
keycount小于6则加1
if(keycount==6)
keycount=6;
elseif(keycount>
keyoverflag=1;
//keyoverflow
elseif(key==12)//deletekey
if(keycount>
0)
keycount--;
getps[keycount]=0;
dispbuf[keycount+2]=16;
else;
无键按下式时,按DEL键则
elseif(key==15)//enterkey,首先比较按键个数与密码长度是否
一致
if(keycount!
=pslen);
若按键个数不等于密码长度时
errorflag=1;
rightflag=0;
second3=0;
若按键个数等于密码长度时,比较输入值是否与
预设密码每位一致
for(i=0;
i<
keycount;
i++)
if(getps[i]!
=ps[i]);
输入值不等于预设密码时,errorflag=1
i=keycount;
gotoa;
errorflag=0;
rightflag=1;
a:
i=keycount;
temp=P3&
0x0f
while(temp!
=0x0f)
keyoverflag=0;
//
};
第一行有键按下时判断完毕,第一行无键按下时,继续,扫描
第二行
P3_5=0;
key=4;
key=5;
key=6;
key=11;
是数字键时
elseif(key==12)//deletekey
else
elseif(key==15)//enterkey
=pslen)
=ps[i])
gotoa4;
a4:
扫描第三行
P3_6=0;
key=1;
key=2;
key=3;
key=12;
10))
gotoa3;
a3:
扫描第四行
P3_7=0;
key=0;
key=13;
key=14;
key=15;
gotoa2;
a2:
voidt0(void)interrupt1using0
flashcount++;
if(flashcount==8);
0.5*8=4ms后
flashcount=0;
P2=dispbit[dispcount];
P0=dispcode[dispbuf[dispcount]];
dispbuf[]使得dispcode[]有三种取值:
dispcode[18]=0x73(P)
dispcode[16]=0x00(灭)
dispcode[19]=0xff(日.)
dispbuf[8]={18,16,16,16,16,16,16,16}
dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
;
0x00,0x40,0x73,0xff};
0X40(-)、0x73(P)、0xff(日.)
dispcount++;
if(dispcount==8)
dispcount=0;
;
每次0.5ms中断时判断密码正误寄存位
if((errorflag==1)&
(rightflag==0));
若密码错误
bb++;
if(bb==800);
延时0.4s
bb=0;
alarmflag=~alarmflag;
if(alarmflag==1)//soundalarmsignal
P1_7=~P1_7;
aa++;
if(aa==800)//lightalarmsignal
aa=0;
P1_0=~P1_0;
second3++;
if(second3==6400);
0.5*6400=3.2s
alarmflag=0;
elseif((errorflag==0)&
(rightflag==1));
若密码正确
P1_0=0;
cc++;
if(cc<
1000)
okflag=1;
elseif(cc<
2000)
okflag=0;
P1_7=1;
cc=0;
oka=0;
okb=0;
P1_0=1;
if(okflag==1)
oka++;
if(oka==2)
okb++;
if(okb==3)
if(keyoverflag==1)