单片机课程设计电子密码锁实验报告.docx
《单片机课程设计电子密码锁实验报告.docx》由会员分享,可在线阅读,更多相关《单片机课程设计电子密码锁实验报告.docx(32页珍藏版)》请在冰豆网上搜索。
单片机课程设计电子密码锁实验报告
单片机课程设计
电子密码锁实验报告
学院:
电子信息工程学院
班级:
自***姓名:
***
学号:
******指导教师:
***
单片机课程设计电子密码锁实验报告
(一)实验目的
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总体设计框图
(五)按键说明
按键
键名
功能说明
1-9键
数字
输入密码
C键
退格键DEL
取消刚才输入的密码
D键
清除密码键CLEAR
将数码管上显示的数据清空
E
密码重置键CHG
密码更改
F
确认键ENTER
密码输入完成
(六)仿真原理图
(七)程序框图
(八)制作过程中所遇到的问题及解决办法
调试时发现数码管一闪一闪的显示,程序刚开始的是扫描8次数码管才显示,最后改成扫描4次数码管才显示,这样动态显示的数码管显示看起来不会晃眼睛了。
(九)体会与总结
通过本次实验,我对单片机有了更一步的认识,以前学习的都只是书本上的知识,对单片机的认识也只是停留课本。
这次单片机课程设计,从选题,查资料,画电路图,编程,Proteus仿真,焊板子,调试。
。
。
在这段单片机课程设计时间里,觉得自己很忙碌但很充实,有时很抓狂,因为程序的设计但很快乐。
在实验过程中遇到一些困难,比如蜂鸣器不按照设定的程序发出声音,最后经过和同学的帮忙,发现是蜂鸣器的控制三极管接错了,应该接PNP9012接成了NPN9013。
以前模拟电路仿真用的是Multisum,这次单片机课程设计显然不再适合,因为有很多元器件Multisum都不包括,接着我开始学习Proteus仿真软件,最后利用Proteus画出了自己仿真图。
最后密码锁设计成功。
这次实验我动手能力得到很大的锻炼,受益匪浅,呼吁学校应该多开设类似课程,锻炼学生的能力。
(十)附件:
主要程序
#include
unsignedcharps[5]={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};//每个数码管显示码共阴极字形码
unsignedchardispbuf[8]={18,16,16,16,16,16,16,16};//显示缓冲
unsignedchardispcount;//数码管显示计数
unsignedcharflashcount;//扫描次数计数
unsignedchartemp;
unsignedcharkey;//按键(0123456789ENTERDEL)
unsignedcharkeycount1;//按键计数
unsignedcharkeycount2;//按键计数
unsignedcharpslen=5;//密码位数
unsignedchargetps[5];//键盘输入密码储存数组
bitkeyoverflag;//键值溢出标志
biterrorflag;//错误标志位
bitrightflag;//正确标志位
unsignedintsecond3;//声音
unsignedintaa,bb;
unsignedintcc,dd;
bitokflag;//ok标志位
bitalarmflag;//报警标志位
unsignedcharoka,okb;
voidmain(void)
{
unsignedchari,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<4)
{
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)
{
case0x0e:
key=1;
break;
case0x0d:
key=5;
break;
case0x0b:
key=9;
break;
case0x07:
key=12;
break;
}
temp=P3;
if((key>=0)&&(key<10))
{
if(keycount1<5)
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2<6)
{
dispbuf[keycount2+2]=19;//前两位已经用于显示"P"
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
elseif(keycount2>6)
{
keycount2=6;
keyoverflag=1;//keyoverflow键值溢出输入密码长度超过
}
}
elseif(key==12)//deletekey删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--;
keycount2--;
getps[keycount1]=0;//最近1次数入的数值清0
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1;//未输入密码,按到功能键,报错!
嘀一声。
}
}
elseif(key==13)//clear密码
{
for(i=0;i<6;i++)
{
dispbuf[i+2]=16;
}
}
elseif(key==14)//changeps修改密码
{
for(i=0;i<5;i++)
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
elseif(key==15)//enterkey进入键值
{
if(keycount1!
=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i<5;i++)
{
if(getps[i]!
=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
gotoa;
}
}
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)
{
case0x0e:
key=2;
break;
case0x0d:
key=6;
break;
case0x0b:
key=0;
break;
case0x07:
key=13;
break;
}
temp=P3;
if((key>=0)&&(key<10))
{
if(keycount1<5)
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2<6)
{
dispbuf[keycount2+2]=19;
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
elseif(keycount2>6)
{
keycount2=6;
keyoverflag=1;//keyoverflow键值溢出
}
}
elseif(key==12)//deletekey删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--;
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1;
}
}
elseif(key==13)//clear密码
{
for(i=0;i<6;i++)
{
dispbuf[i+2]=16;
}
}
elseif(key==14)//changeps修改密码
{
for(i=0;i<5;i++)
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
elseif(key==15)//enterkey进入键值
{
if(keycount1!
=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i<5;i++){
if(getps[i]!
=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
gotoa4;
}
}
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)
{
case0x0e:
key=3;
break;
case0x0d:
key=7;
break;
case0x0b:
key=10;
break;
case0x07:
key=14;
break;//开始处
}
temp=P3;
if((key>=0)&&(key<10))
{
if(keycount1<5)
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2<6)
{
dispbuf[keycount2+2]=19;
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
elseif(keycount2>6)
{
keycount2=6;
keyoverflag=1;//keyoverflow键值溢出
}
}
elseif(key==12)//deletekey删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--;
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1;
}
}
elseif(key==13)//clear密码
{
for(i=0;i<6;i++)
{
dispbuf[i+2]=16;
}
}
elseif(key==14)//changeps修改密码
{
for(i=0;i<5;i++)
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
elseif(key==15)//enterkey进入键值
{
if(keycount1!
=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i<5;i++)
{
if(getps[i]!
=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
gotoa3;
}
}
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)
{
case0x0e:
key=4;
break;
case0x0d:
key=8;
break;
case0x0b:
key=11;
break;
case0x07:
key=15;
break;
}
temp=P3;
if((key>=0)&&(key<10))
{
if(keycount1<5)
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2<6)
{
dispbuf[keycount2+2]=19;
}
keycount2++;
if(keycount2==6)
{
keycount2=6;
}
elseif(keycount2>6)
{
keycount2=6;
keyoverflag=1;//keyoverflow键值溢出
}
}
elseif(key==12)//deletekey删除键值
{
if((keycount1>0)&&(keycount2>0))
{
keycount1--;
keycount2--;
getps[keycount1]=0;
dispbuf[keycount2+2]=16;
}
else
{
keyoverflag=1;
}
}
elseif(key==13)//clear密码
{
for(i=0;i<6;i++)
{
dispbuf[i+2]=16;
}
}
elseif(key==14)//changeps修改密码
{
for(i=0;i<5;i++)
{
ps[i]=getps[i];
getps[i]=0;
keycount1=0;
keycount2=0;
}
}
elseif(key==15)//enterkey
{
if(keycount1!
=pslen)
{
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
}
else
{
for(i=0;i<5;i++)
{
if(getps[i]!
=ps[i])
{
i=keycount1;
errorflag=1;
rightflag=0;
second3=0;
keycount1=0;
keycount2=0;
dd++;
gotoa2;//开始处
}
}
errorflag=0;
rightflag=1;
keycount1=0;
keycount2=0;
a2:
i=keycount1