资源描述
单片机课程设计
电子密码锁实验报告
学院:电子信息工程学院
班级:自***姓名:***
学号:******指导教师:***
单片机课程设计电子密码锁实验报告
(一)实验目的
1、了解电子密码锁工作原理和八段LED数码管显示原理。
2、掌握LED数码管显示器与单片机接口电路设计方法。
3、掌握实现密码锁功能的编程方法。
(二)设计实现功能
(1) 由程序设定初始密码,密码输入正确时锁打开,指示灯亮,发出“叮咚”的声音;密码输入不正确时,指示灯闪亮四次,发出“嘀嘀嘀滴”报警声。
(2) 具有保护密码的功能,输入密码在数码管上显示可改为“88888”的方式,防止别人偷窥密码。
(3) 具有修改密码的功能,密码输入错误可按DEL键进行删除。
(4) 具有防止多次试探密码的电子密码锁并加报警功能,密码输入错误超过三次,将一直发出“滴滴滴滴。。。”报警声。
(5) 具有设定新密码的功能,输入密码后按CHG键,密码将被重新设定。
(三)整体电路设计思路
核心用单片机AT89S52来实现此实验的要求。
用4*4键盘来输入密码。 每个按键有它的行值和列值 ,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU通信。每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
用8个7段数码管来显示密码。数码管的显示用扫描的方式,利用动态接口采用各数码管循环轮流显示的方法,当循环显示频率较高时,利用人眼的暂留特性,看不出闪烁显示现象,这种显示需要一个接口完成字形码的输出(字形选择),另一接口完成各数码管的轮流点亮(数位选择)。 在进行数码显示的时候,要对显示单元开辟8个显示缓冲区,每个显示缓冲区装有显示的不同数据即可。 对于显示的字形码数据我们采用查表方法来完成。
(四)设计总框图
89S52
单片机
数码管显示电路
矩阵
键盘
控制
报警电路
复位电路
电源
LED指示电路
图1总体设计框图
(五)按键说明
按键
键名
功能说明
1-9键
数字
输入密码
C键
退格键DEL
取消刚才输入的密码
D键
清除密码键CLEAR
将数码管上显示的数据清空
E
密码重置键CHG
密码更改
F
确认键ENTER
密码输入完成
(六)仿真原理图
(七)程序框图
开始
系统初始化
提示输入密码
键盘扫描
有键按下
数字键0~9
退格键C
密码重置D
确认键E
灯亮紧接着发出开门的声“叮咚”
存储键值
刷新LED输出数据
清楚上次数字键输入
灯闪四次,发出报警声“滴”
错误3次
报警,并锁定键盘
密码判断
正确?
Y
Y
N
N
N
Y
N
Y
Y
N
N
Y
(八)制作过程中所遇到的问题及解决办法
调试时发现数码管一闪一闪的显示,程序刚开始的是扫描8次数码管才显示,最后改成扫描4次数码管才显示,这样动态显示的数码管显示看起来不会晃眼睛了。
(九)体会与总结
通过本次实验,我对单片机有了更一步的认识,以前学习的都只是书本上的知识,对单片机的认识也只是停留课本。这次单片机课程设计,从选题,查资料,画电路图,编程,Proteus仿真,焊板子,调试。。。在这段单片机课程设计时间里,觉得自己很忙碌但很充实,有时很抓狂,因为程序的设计但很快乐。在实验过程中遇到一些困难,比如蜂鸣器不按照设定的程序发出声音,最后经过和同学的帮忙,发现是蜂鸣器的控制三极管接错了,应该接PNP9012接成了NPN9013。以前模拟电路仿真用的是Multisum,这次单片机课程设计显然不再适合,因为有很多元器件Multisum都不包括,接着我开始学习Proteus仿真软件,最后利用Proteus画出了自己仿真图。最后密码锁设计成功。
这次实验我动手能力得到很大的锻炼,受益匪浅,呼吁学校应该多开设类似课程,锻炼学生的能力。
(十)附件:主要程序
#include <at89x52.h>
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<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)
{
case 0x0e:
key=1;
break;
case 0x0d:
key=5;
break;
case 0x0b:
key=9;
break;
case 0x07:
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;
}
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<6;i++)
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i<5;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<5;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<10))
{
if(keycount1<5)
{
getps[keycount1]=key;
}
keycount1++;
if (keycount2<6)
{
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<6;i++)
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i<5;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<5;i++) {
if(getps[i]!=ps[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<10))
{
if(keycount1<5)
{
getps[keycount1]=key;
}
keycount1++;
if(keycount2<6)
{
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<6;i++)
{
dispbuf[i+2]=16;
}
}
else if(key==14)//change ps 修改密码
{
for(i=0;i<5;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<5;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--)
展开阅读全文