单片机课程设计 电子密码锁实验报告
学院:电子信息工程学院 班级:自***姓名:*** 学号:******指导教师:***
单片机课程设计电子密码锁实验报告
(一)实验目的
1、了解电子密码锁工作原理和八段LED数码管显示原理。 2、掌握LED数码管显示器与单片机接口电路设计方法。 3、掌握实现密码锁功能的编程方法。
(二)设计实现功能
(1) 由程序设定初始密码,密码输入正确时锁打开,指示灯亮,发出“叮咚”的声
音;密码输入不正确时,指示灯闪亮四次,发出“嘀嘀嘀滴”报警声。
(2) 具有保护密码的功能,输入密码在数码管上显示可改为“88888”的方式,防止
别人偷窥密码。
(3) 具有修改密码的功能,密码输入错误可按DEL键进行删除。
(4) 具有防止多次试探密码的电子密码锁并加报警功能,密码输入错误超过三次,
将一直发出“滴滴滴滴。。。”报警声。
(5) 具有设定新密码的功能,输入密码后按CHG键,密码将被重新设定。
(三)整体电路设计思路
核心用单片机AT89S52来实现此实验的要求。
用4*4键盘来输入密码。 每个按键有它的行值和列值 ,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU通信。每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
用8个7段数码管来显示密码。数码管的显示用扫描的方式,利用动态接口采用各数码管循环轮流显示的方法,当循环显示频率较高时,利用人眼的暂留特性,看不出闪烁显示现象,这种显示需要一个接口完成字形码的输出(字形选择),另一接口完成各数码管的轮流点亮(数位选择)。 在进行数码显示的时候,要对显示单元开辟8个显示缓冲区,每个显示缓冲区装有显示的不同数据即可。 对于显示的字形码数据我们采用查表方法来完成。
(四)设计总框图
图1总体设计框图
(六)仿真原理图
(七)程序框图
(八)制作过程中所遇到的问题及解决办法
调试时发现数码管一闪一闪的显示,程序刚开始的是扫描8次数码管才显示,最后改成
扫描4次数码管才显示,这样动态显示的数码管显示看起来不会晃眼睛了。
(九)体会与总结
通过本次实验,我对单片机有了更一步的认识,以前学习的都只是书本上的知识,对单片机的认识也只是停留课本。这次单片机课程设计,从选题,查资料,画电路图,编程,Proteus仿真,焊板子,调试。。。在这段单片机课程设计时间里,觉得自己很忙碌但很充实,有时很抓狂,因为程序的设计但很快乐。在实验过程中遇到一些困难,比如蜂鸣器不按照设定的程序发出声音,最后经过和同学的帮忙,发现是蜂鸣器的控制三极管接错了,应该接PNP9012接成了NPN9013。以前模拟电路仿真用的是Multisum,这次单片机课程设计显然不再适合,因为有很多元器件Multisum都不包括,接着我开始学习Proteus仿真软件,最后利用Proteus画出了自己仿真图。最后密码锁设计成功。
这次实验我动手能力得到很大的锻炼,受益匪浅,呼吁学校应该多开设类似课程,锻炼学生的能力。
(十)附件:主要程序
#include
unsigned char ps[5]={1,2,3,4,5};//程序预先设定的密码 unsigned char code dispbit[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f}; //数码管显示位 unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,
0x00,0x40,0x73,0xff}; //每个数码管显示码 共阴极字形码
unsigned char dispbuf[8]={18,16,16,16,16,16,16,16}; //显示缓冲 unsigned char dispcount; //数码管显示计数 unsigned char flashcount; //扫描次数计数 unsigned char temp;
unsigned char key; //按键(0 1 2 3 4 5 6 7 8 9 ENTER DEL) unsigned char keycount1;//按键计数 unsigned char keycount2;//按键计数 unsigned char pslen=5; //密码位数
unsigned char getps[5];//键盘输入密码储存数组 bit keyoverflag; //键值溢出标志 bit errorflag; //错误标志位 bit rightflag; //正确标志位
扫描4次数码管才显示,这样动态显示的数码管显示看起来不会晃眼睛了。
(九)体会与总结
通过本次实验,我对单片机有了更一步的认识,以前学习的都只是书本上的知识,对单片机的认识也只是停留课本。这次单片机课程设计,从选题,查资料,画电路图,编程,Proteus仿真,焊板子,调试。。。在这段单片机课程设计时间里,觉得自己很忙碌但很充实,有时很抓狂,因为程序的设计但很快乐。在实验过程中遇到一些困难,比如蜂鸣器不按照设定的程序发出声音,最后经过和同学的帮忙,发现是蜂鸣器的控制三极管接错了,应该接PNP9012接成了NPN9013。以前模拟电路仿真用的是Multisum,这次单片机课程设计显然不再适合,因为有很多元器件Multisum都不包括,接着我开始学习Proteus仿真软件,最后利用Proteus画出了自己仿真图。最后密码锁设计成功。
这次实验我动手能力得到很大的锻炼,受益匪浅,呼吁学校应该多开设类似课程,锻炼学生的能力。
(十)附件:主要程序
#include
unsigned char ps[5]={1,2,3,4,5};//程序预先设定的密码
unsigned char code dispbit[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f}; //数码管显示位
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,
0x00,0x40,0x73,0xff}; //每个数码管显示码 共阴极字形码
unsigned char dispbuf[8]={18,16,16,16,16,16,16,16}; //显示缓冲
unsigned char dispcount; //数码管显示计数
unsigned char flashcount; //扫描次数计数
unsigned char temp;
unsigned char key; //按键(0 1 2 3 4 5 6 7 8 9 ENTER DEL)
unsigned char keycount1;//按键计数
unsigned char keycount2;//按键计数
unsigned char pslen=5; //密码位数
unsigned char getps[5];//键盘输入密码储存数组
bit keyoverflag; //键值溢出标志
bit errorflag; //错误标志位
bit rightflag; //正确标志位
unsigned int second3;//声音
unsigned int aa,bb;
unsigned int cc,dd;
bit okflag; //ok标志位
bit alarmflag; //报警标志位
unsigned char oka,okb;
void main(void)
{
unsigned char i,j;
TMOD=0x01;//to工作方式1
//重置定时500us
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TR0=1; //启动计数器0
ET0=1;
EA=1;
while(1)
{
if(dd
{
P3=0xff;
P3_4=0;
temp=P3;
temp=temp & 0x0f; //取出低4位
if (temp!=0x0f) //有键按下
{
for(i=10;i>0;i--)
for(j=248;j>0;j--); //延时2.48ms
temp=P3;
temp=temp & 0x0f;//取出低4位
if (temp!=0x0f) //有按键按下
{
temp=P3;
temp=temp & 0x0f;//取出低4位
switch(temp)
{
case 0x0e:
key=1;
break;
case 0x0d:
key=5;
break;
case 0x0b:
key=9;
case 0x07:
key=12;
break;
}
temp=P3;
if((key>=0) && (key
{
if(keycount1
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2
{
dispbuf[keycount2+2]=19; //前两位已经用于显示"P "
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
else if(keycount2>6)
{
keycount2=6;
keyoverflag=1;//key overflow 键值溢出 输入密码长度超过 }
}
else if(key==12)//delete key 删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--;
keycount2--;
getps[keycount1]=0; //最近1次数入的数值清0
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1; //未输入密码,按到功能键,报错!嘀一声。
}
else if(key==13)//clear 密码
{
for(i=0;i
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
else if(key==15)//enter key 进入键值 {
if(keycount1!=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i
{
if(getps[i]!=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
goto a;
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a: i=keycount1;
}
}
temp=temp & 0x0f; //取出低4位 while(temp!=0x0f) //有按键按下
{
temp=P3;
temp=temp & 0x0f; //取出低4位 }
keyoverflag=0;//键值不溢出
}
}
P3=0xff;
P3_5=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=10;i>0;i--)
for(j=248;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=2;
break;
case 0x0d:
key=6;
break;
case 0x0b:
key=0;
break;
case 0x07:
key=13;
break;
}
temp=P3;
if((key>=0) && (key
{
if(keycount1
{
getps[keycount1]=key;
}
keycount1++;
if (keycount2
{
dispbuf[keycount2+2]=19;
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
else if(keycount2>6)
{
keycount2=6;
keyoverflag=1;//key overflow 键值溢出 }
}
else if(key==12)//delete key 删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--;
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1;
}
}
else if(key==13)//clear 密码
{
for(i=0;i
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
else if(key==15)//enter key 进入键值
{
if(keycount1!=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
goto a4;
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a4: i=keycount1;
}
}
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
keyoverflag=0;//?????????
}
}
P3=0xff;
P3_6=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=10;i>0;i--)
for(j=248;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=3;
break;
case 0x0d:
key=7;
break;
case 0x0b:
key=10;
break;
case 0x07:
key=14;
break; //开始处
}
temp=P3;
if((key>=0) && (key
{
if(keycount1
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2
{
dispbuf[keycount2+2]=19; }
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
else if(keycount2>6)
{
keycount2=6;
keyoverflag=1;//key overflow }
}
else if(key==12)//delete key 删除键值 {
if((keycount1>0)&&(keycount2>0)) {
keycount1--; 键值溢出
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16; }
else
{
keyoverflag=1;
}
}
else if(key==13)//clear 密码 {
for(i=0;i
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码 {
for(i=0;i
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0; }
}
else if(key==15)//enter key 进入键值 {
if(keycount1!=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i
{
if(getps[i]!=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
goto a3;
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a3: i=keycount1;
}
}
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
keyoverflag=0;//?????????
}
}
P3=0xff;
P3_7=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=10;i>0;i--)
for(j=248;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=4;
break;
case 0x0d:
key=8;
break;
case 0x0b:
key=11;
break;
case 0x07:
key=15;
break;
}
temp=P3;
if((key>=0) && (key
{
if(keycount1
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2
{
dispbuf[keycount2+2]=19;
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
else if(keycount2>6)
{
keycount2=6;
keyoverflag=1;//key overflow
}
}
else if(key==12)//delete key 删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--; 键值溢出
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1;
}
}
else if(key==13)//clear 密码
{
for(i=0;i
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
else if(key==15)//enter key
{
if(keycount1!=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i
{
if(getps[i]!=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
goto a2; //开始处
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a2: i=keycount1;
}
}
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
keyoverflag=0;//?????????
}
}
}
else
{
bb++;
if(bb==8000)
{
bb=0;
P1_7=~P1_7;
}
}
}
}
//定时器0中断服务程序
void t0(void) interrupt 1 using 0
{
//重置定时500us
TH0=(65536-500)/256;
TL0=(65536-500)%256;
flashcount++;
if(flashcount==4)//扫描8次 数码管才显示第一个按下的密码
{
flashcount=0;
P0=dispcode[dispbuf[dispcount]];
P2=dispbit[dispcount]; //数码管显示密码
dispcount++; //数码管显示计数
if(dispcount==8)
{
dispcount=0;
}
}
if((errorflag==1) && (rightflag==0)) //发出"嘀、嘀"报警声
{
bb++;
if(bb==800)
{
bb=0;
alarmflag=~alarmflag;
}
if(alarmflag==1)//sound alarm signal
{
P1_7=~P1_7;
}
aa++;
if(aa==800)//light alarm signal
{
aa=0;
P1_0=~P1_0; //LED发光二极管闪
}
second3++;
if(second3==6400) //闪4次后(8次变换),自动复位到按ENTER前的状态 {
second3=0;
errorflag=0;
rightflag=0;
alarmflag=0;
bb=0;
aa=0;
}
else if((errorflag==0) && (rightflag==1)) //发出"叮咚"声 {
P1_0=0;//LED发光二极管亮
cc++;
if(cc
{
okflag=1;
}
else if(cc
{
okflag=0;
}
else //自动复位到按ENTER前的状态
{
errorflag=0;
rightflag=0;
P1_7=1;
cc=0;
oka=0;
okb=0;
okflag=0;
P1_0=1; //LED发光二极管灭
}
if(okflag==1)
{
oka++;
if(oka==2)
{
oka=0;
P1_7=~P1_7;
}
}
else
{
okb++;
if(okb==3)
{
okb=0;
P1_7=~P1_7;
}
}
if(keyoverflag==1) //嘀一声
P1_7=~P1_7; }
}
}
单片机课程设计 电子密码锁实验报告
学院:电子信息工程学院 班级:自***姓名:*** 学号:******指导教师:***
单片机课程设计电子密码锁实验报告
(一)实验目的
1、了解电子密码锁工作原理和八段LED数码管显示原理。 2、掌握LED数码管显示器与单片机接口电路设计方法。 3、掌握实现密码锁功能的编程方法。
(二)设计实现功能
(1) 由程序设定初始密码,密码输入正确时锁打开,指示灯亮,发出“叮咚”的声
音;密码输入不正确时,指示灯闪亮四次,发出“嘀嘀嘀滴”报警声。
(2) 具有保护密码的功能,输入密码在数码管上显示可改为“88888”的方式,防止
别人偷窥密码。
(3) 具有修改密码的功能,密码输入错误可按DEL键进行删除。
(4) 具有防止多次试探密码的电子密码锁并加报警功能,密码输入错误超过三次,
将一直发出“滴滴滴滴。。。”报警声。
(5) 具有设定新密码的功能,输入密码后按CHG键,密码将被重新设定。
(三)整体电路设计思路
核心用单片机AT89S52来实现此实验的要求。
用4*4键盘来输入密码。 每个按键有它的行值和列值 ,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU通信。每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
用8个7段数码管来显示密码。数码管的显示用扫描的方式,利用动态接口采用各数码管循环轮流显示的方法,当循环显示频率较高时,利用人眼的暂留特性,看不出闪烁显示现象,这种显示需要一个接口完成字形码的输出(字形选择),另一接口完成各数码管的轮流点亮(数位选择)。 在进行数码显示的时候,要对显示单元开辟8个显示缓冲区,每个显示缓冲区装有显示的不同数据即可。 对于显示的字形码数据我们采用查表方法来完成。
(四)设计总框图
图1总体设计框图
(六)仿真原理图
(七)程序框图
(八)制作过程中所遇到的问题及解决办法
调试时发现数码管一闪一闪的显示,程序刚开始的是扫描8次数码管才显示,最后改成
扫描4次数码管才显示,这样动态显示的数码管显示看起来不会晃眼睛了。
(九)体会与总结
通过本次实验,我对单片机有了更一步的认识,以前学习的都只是书本上的知识,对单片机的认识也只是停留课本。这次单片机课程设计,从选题,查资料,画电路图,编程,Proteus仿真,焊板子,调试。。。在这段单片机课程设计时间里,觉得自己很忙碌但很充实,有时很抓狂,因为程序的设计但很快乐。在实验过程中遇到一些困难,比如蜂鸣器不按照设定的程序发出声音,最后经过和同学的帮忙,发现是蜂鸣器的控制三极管接错了,应该接PNP9012接成了NPN9013。以前模拟电路仿真用的是Multisum,这次单片机课程设计显然不再适合,因为有很多元器件Multisum都不包括,接着我开始学习Proteus仿真软件,最后利用Proteus画出了自己仿真图。最后密码锁设计成功。
这次实验我动手能力得到很大的锻炼,受益匪浅,呼吁学校应该多开设类似课程,锻炼学生的能力。
(十)附件:主要程序
#include
unsigned char ps[5]={1,2,3,4,5};//程序预先设定的密码 unsigned char code dispbit[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f}; //数码管显示位 unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,
0x00,0x40,0x73,0xff}; //每个数码管显示码 共阴极字形码
unsigned char dispbuf[8]={18,16,16,16,16,16,16,16}; //显示缓冲 unsigned char dispcount; //数码管显示计数 unsigned char flashcount; //扫描次数计数 unsigned char temp;
unsigned char key; //按键(0 1 2 3 4 5 6 7 8 9 ENTER DEL) unsigned char keycount1;//按键计数 unsigned char keycount2;//按键计数 unsigned char pslen=5; //密码位数
unsigned char getps[5];//键盘输入密码储存数组 bit keyoverflag; //键值溢出标志 bit errorflag; //错误标志位 bit rightflag; //正确标志位
扫描4次数码管才显示,这样动态显示的数码管显示看起来不会晃眼睛了。
(九)体会与总结
通过本次实验,我对单片机有了更一步的认识,以前学习的都只是书本上的知识,对单片机的认识也只是停留课本。这次单片机课程设计,从选题,查资料,画电路图,编程,Proteus仿真,焊板子,调试。。。在这段单片机课程设计时间里,觉得自己很忙碌但很充实,有时很抓狂,因为程序的设计但很快乐。在实验过程中遇到一些困难,比如蜂鸣器不按照设定的程序发出声音,最后经过和同学的帮忙,发现是蜂鸣器的控制三极管接错了,应该接PNP9012接成了NPN9013。以前模拟电路仿真用的是Multisum,这次单片机课程设计显然不再适合,因为有很多元器件Multisum都不包括,接着我开始学习Proteus仿真软件,最后利用Proteus画出了自己仿真图。最后密码锁设计成功。
这次实验我动手能力得到很大的锻炼,受益匪浅,呼吁学校应该多开设类似课程,锻炼学生的能力。
(十)附件:主要程序
#include
unsigned char ps[5]={1,2,3,4,5};//程序预先设定的密码
unsigned char code dispbit[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f}; //数码管显示位
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,
0x00,0x40,0x73,0xff}; //每个数码管显示码 共阴极字形码
unsigned char dispbuf[8]={18,16,16,16,16,16,16,16}; //显示缓冲
unsigned char dispcount; //数码管显示计数
unsigned char flashcount; //扫描次数计数
unsigned char temp;
unsigned char key; //按键(0 1 2 3 4 5 6 7 8 9 ENTER DEL)
unsigned char keycount1;//按键计数
unsigned char keycount2;//按键计数
unsigned char pslen=5; //密码位数
unsigned char getps[5];//键盘输入密码储存数组
bit keyoverflag; //键值溢出标志
bit errorflag; //错误标志位
bit rightflag; //正确标志位
unsigned int second3;//声音
unsigned int aa,bb;
unsigned int cc,dd;
bit okflag; //ok标志位
bit alarmflag; //报警标志位
unsigned char oka,okb;
void main(void)
{
unsigned char i,j;
TMOD=0x01;//to工作方式1
//重置定时500us
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TR0=1; //启动计数器0
ET0=1;
EA=1;
while(1)
{
if(dd
{
P3=0xff;
P3_4=0;
temp=P3;
temp=temp & 0x0f; //取出低4位
if (temp!=0x0f) //有键按下
{
for(i=10;i>0;i--)
for(j=248;j>0;j--); //延时2.48ms
temp=P3;
temp=temp & 0x0f;//取出低4位
if (temp!=0x0f) //有按键按下
{
temp=P3;
temp=temp & 0x0f;//取出低4位
switch(temp)
{
case 0x0e:
key=1;
break;
case 0x0d:
key=5;
break;
case 0x0b:
key=9;
case 0x07:
key=12;
break;
}
temp=P3;
if((key>=0) && (key
{
if(keycount1
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2
{
dispbuf[keycount2+2]=19; //前两位已经用于显示"P "
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
else if(keycount2>6)
{
keycount2=6;
keyoverflag=1;//key overflow 键值溢出 输入密码长度超过 }
}
else if(key==12)//delete key 删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--;
keycount2--;
getps[keycount1]=0; //最近1次数入的数值清0
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1; //未输入密码,按到功能键,报错!嘀一声。
}
else if(key==13)//clear 密码
{
for(i=0;i
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
else if(key==15)//enter key 进入键值 {
if(keycount1!=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i
{
if(getps[i]!=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
goto a;
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a: i=keycount1;
}
}
temp=temp & 0x0f; //取出低4位 while(temp!=0x0f) //有按键按下
{
temp=P3;
temp=temp & 0x0f; //取出低4位 }
keyoverflag=0;//键值不溢出
}
}
P3=0xff;
P3_5=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=10;i>0;i--)
for(j=248;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=2;
break;
case 0x0d:
key=6;
break;
case 0x0b:
key=0;
break;
case 0x07:
key=13;
break;
}
temp=P3;
if((key>=0) && (key
{
if(keycount1
{
getps[keycount1]=key;
}
keycount1++;
if (keycount2
{
dispbuf[keycount2+2]=19;
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
else if(keycount2>6)
{
keycount2=6;
keyoverflag=1;//key overflow 键值溢出 }
}
else if(key==12)//delete key 删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--;
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1;
}
}
else if(key==13)//clear 密码
{
for(i=0;i
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
else if(key==15)//enter key 进入键值
{
if(keycount1!=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
goto a4;
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a4: i=keycount1;
}
}
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
keyoverflag=0;//?????????
}
}
P3=0xff;
P3_6=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=10;i>0;i--)
for(j=248;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=3;
break;
case 0x0d:
key=7;
break;
case 0x0b:
key=10;
break;
case 0x07:
key=14;
break; //开始处
}
temp=P3;
if((key>=0) && (key
{
if(keycount1
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2
{
dispbuf[keycount2+2]=19; }
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
else if(keycount2>6)
{
keycount2=6;
keyoverflag=1;//key overflow }
}
else if(key==12)//delete key 删除键值 {
if((keycount1>0)&&(keycount2>0)) {
keycount1--; 键值溢出
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16; }
else
{
keyoverflag=1;
}
}
else if(key==13)//clear 密码 {
for(i=0;i
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码 {
for(i=0;i
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0; }
}
else if(key==15)//enter key 进入键值 {
if(keycount1!=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i
{
if(getps[i]!=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
goto a3;
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a3: i=keycount1;
}
}
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
keyoverflag=0;//?????????
}
}
P3=0xff;
P3_7=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=10;i>0;i--)
for(j=248;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=4;
break;
case 0x0d:
key=8;
break;
case 0x0b:
key=11;
break;
case 0x07:
key=15;
break;
}
temp=P3;
if((key>=0) && (key
{
if(keycount1
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2
{
dispbuf[keycount2+2]=19;
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
else if(keycount2>6)
{
keycount2=6;
keyoverflag=1;//key overflow
}
}
else if(key==12)//delete key 删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--; 键值溢出
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1;
}
}
else if(key==13)//clear 密码
{
for(i=0;i
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
else if(key==15)//enter key
{
if(keycount1!=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i
{
if(getps[i]!=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
goto a2; //开始处
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a2: i=keycount1;
}
}
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
keyoverflag=0;//?????????
}
}
}
else
{
bb++;
if(bb==8000)
{
bb=0;
P1_7=~P1_7;
}
}
}
}
//定时器0中断服务程序
void t0(void) interrupt 1 using 0
{
//重置定时500us
TH0=(65536-500)/256;
TL0=(65536-500)%256;
flashcount++;
if(flashcount==4)//扫描8次 数码管才显示第一个按下的密码
{
flashcount=0;
P0=dispcode[dispbuf[dispcount]];
P2=dispbit[dispcount]; //数码管显示密码
dispcount++; //数码管显示计数
if(dispcount==8)
{
dispcount=0;
}
}
if((errorflag==1) && (rightflag==0)) //发出"嘀、嘀"报警声
{
bb++;
if(bb==800)
{
bb=0;
alarmflag=~alarmflag;
}
if(alarmflag==1)//sound alarm signal
{
P1_7=~P1_7;
}
aa++;
if(aa==800)//light alarm signal
{
aa=0;
P1_0=~P1_0; //LED发光二极管闪
}
second3++;
if(second3==6400) //闪4次后(8次变换),自动复位到按ENTER前的状态 {
second3=0;
errorflag=0;
rightflag=0;
alarmflag=0;
bb=0;
aa=0;
}
else if((errorflag==0) && (rightflag==1)) //发出"叮咚"声 {
P1_0=0;//LED发光二极管亮
cc++;
if(cc
{
okflag=1;
}
else if(cc
{
okflag=0;
}
else //自动复位到按ENTER前的状态
{
errorflag=0;
rightflag=0;
P1_7=1;
cc=0;
oka=0;
okb=0;
okflag=0;
P1_0=1; //LED发光二极管灭
}
if(okflag==1)
{
oka++;
if(oka==2)
{
oka=0;
P1_7=~P1_7;
}
}
else
{
okb++;
if(okb==3)
{
okb=0;
P1_7=~P1_7;
}
}
if(keyoverflag==1) //嘀一声
P1_7=~P1_7; }
}
}