电路设计密码锁.docx
《电路设计密码锁.docx》由会员分享,可在线阅读,更多相关《电路设计密码锁.docx(32页珍藏版)》请在冰豆网上搜索。
电路设计密码锁
题目基于单片机的电子密码锁设计
一、设计的目的
1.了解单片机开发系统的组成及结构;
2.掌握I/O口的操作方法;
3.能够熟练使用protues和keil软件进行连线和编程,并熟练掌握仿真方法;
4.掌握数码管的显示原理;
5.掌握C语言编程方法;
6.培养查找错误和改正错误的能力。
二、设计的内容及要求
本设计采用单片机为主控芯片,结合外围电路组成电子密码控制系统。
设计主要功能有:
1.设置6位密码,密码通过键盘输入,若密码正确,则锁打开,代表锁的二极管亮。
2.初始密码由单片机内部决定,在开锁后20S内用户可对密码进行修改。
3.重设密码时显示数字。
4.密码只能输入6位数字,超过6位的输入无效。
5.具有自动报警功能:
当密码输入错误三次,报警,蜂鸣器响10S。
6.LED数码管显示输入密码,为确保安全性所有密码均用“—”表示。
基于单片机的电子密码锁设计
摘要
电子锁可以在日常生活和现代办公中,住宅与办公室的安全防范、单位的文件档案、财务报表以及一些个人资料的保存等多种场合使用。
大大提高了主人物资的安全性,安全可以代替老式机械锁。
目前使用的密码锁种类繁多,各具特色。
本文从经济实用的角度出发,采用AT89C2051单机,研制了一款具有防盗自动报警功能的电子密码锁。
结合外围的矩阵键盘输入、数码管显示、开锁、报警等,用C语言编写程序,并用keil软件进行编译设计了一款可以更改密码,具有报警功能的电子密码控制系统。
本设计采用矩阵键盘对密码进行输入,具有较高的优势,减少了I/O口的占用数目。
密码的显示采用6位数码管实现,为确保安全性统一使用“—”显示密码。
当重新设置密码时数码管显示数字。
采用采用蜂鸣器模拟报警系统,增加了密码锁的安全能力。
软件使用C语言编程,运用自上而下的模块化设计思想,使系统朝着分布式、小型化方向发展,增强系统的可扩展性和运行的稳定性。
测试结果表明,设计达到电子密码锁的功能。
关键字:
密码锁、AT89C51、矩阵键盘、报警
一背景
随着社会科技的进步,锁已发展到了密码锁、磁性锁、电子锁、激光锁、声控锁等等。
在传统钥匙的基础上,加了一组或多组密码,不同声音,不同磁场,不同声波,不同光束光波,不同图像。
(如指纹、眼底视网膜等)来控制锁的开启。
从而大大提高了锁的安全性,使不法之徒无从下手,人们也就能对自身财产安全有了更多的保障。
当今安全信息系统应用越来越广泛,特别在保护机密、维护隐私和财产保护方面起到重大作用,而基于电子密码锁的安全系统是其中的组成部分,因此研究它具有重大的现实意义。
二设计目的
了解单片机开发系统的组成及结构;
掌握I/O口的操作方法;
能够熟练使用protues和keil软件进行连线和编程,并熟练掌握仿真方法;
掌握数码管的显示原理;
掌握C语言编程方法;
培养查找错误和改正错误的能力。
三本设计所要实现的目标
本次设计使用ATMEL公司的AT89S51实现一基于单片机的电子密码锁的设计,其主要具有如下功能:
(1)密码通过键盘输入,若密码正确,LED灯亮,则将密码锁打开。
(2)报警、锁定键盘功能。
密码输入错误数码显示器会出现错误提示,若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘。
电子密码锁的设计主要由三部分组成:
4×4矩阵键盘接口电路、密码锁的控制电路、输出八段显示电路。
另外系统还有LED提示灯,报警蜂鸣器等。
四设计原理和硬件仿真方案
4.1矩阵键盘
密码的输入用矩阵键盘实现,包括数字键和功能键。
具体功能设计如表一:
表一键盘具体功能设计表
按键
键名
功能
0~9键
数字键
输入密码
A键
重设密码键
设定新密码
C键
清除键
使显示器清零
D键
确定键
比较密码
如图一所示,矩阵键盘的每一条水平(行线)与垂直线(列线)的交叉处不相通,而是通过一个按键来连通,利用这种行列式矩阵结构只需要N条行线和M条列线即可组成有
个按键的键盘。
图一矩阵键盘
本次设计需要0~9十个数字按键、一个清零键、一个确认键和一个重置密码键共13个按键,所以选用4X4的矩阵按键。
在这种行列式矩阵键盘编码的单片机系统中,键盘处理程序首先执行等待按键并确认有无按键按下的程序段,还要对按键进行消抖处理。
当确认有按键按下后,就要识别是哪一个按键被按下。
本次设计使用的是线反转法。
给行线置为0x0f,给列线置为0xf0,再将行列进行逻辑或结果为0xff,当有按键按下时相应的按键位行列均为0,行列逻辑或不为0xff,由此可利用行列逻辑或后的值是否为0xff来判断是否有按键按下。
再根据扫描结果判断按下键的位置。
给相应的按键赋值即可实现数字键和功能键。
对功能键进行相应的软件编程即可实现按键功能。
使用矩阵键盘能减少键盘和单片机接口所占用的I/O线数目,当按键较多的时候通常采用这种方法。
4.2开锁电路
在本次设计中用发光二极管代替电磁锁,二极管亮表示锁开,二极管灭表示没有开锁。
如图二所示,当输入密码与内置密码相配合时将P3.0置0,二极管亮。
否则LED灯不亮。
图二发光二极管电路
4.3报警电路
报警电路由单片机和蜂鸣器组成,如图三所示,当P3.1为高电平时蜂鸣器发出声音报警。
每次输入的密码与正确密码进行比较,如果相同,锁开灯亮。
如果输入错误则用一个变量来记录输入错误的次数,当输入密码错误达到三次时,蜂鸣器工作发出报警声音,本次设计使用的是声音间断蜂鸣器声音报警来报警,即声音持续时间20ms后又将P3.1置0时间为20ms,如此循环,即可听到“嘟嘟嘟”的间断响声。
设置报警总时间为10S。
图三
4.4数码管显示电路
密码显示电路由单片机、电阻排和6位数码管组成。
显示电路如图四所示。
P0口控制段选,P2口控制位选。
为保证密码的保密性,本设计采用“—”显示所有输入密码,如图四所示。
当重设密码时,为了防止手动错误,数码管显示数字,如图五所示。
本设计只允许输入数字密码6位,超过6位以后的数字无效,在C语言程序中以一个while循环实现。
数码管显示原理:
(1)“—”显示原理:
在选择位选的情况下,段选仅点亮“g”管即可显示当位为“—”;
(2)实现右移逐渐点亮原理:
当输入一个数字时,第五位(从左往右数)赋值给第六位,第四位的值赋给第五位,第三位的值赋给第四位,第二位的值赋给第三位,第一位的值赋给第二位,输入的值赋给第一位,同时点亮第一位数码管。
当输入第二个数字时,每一位与输入第一位时相同均向左移一位,将输入的值赋给第一位,同时点亮第一位和第二位数码管。
如此每输入一个数字数码管就向右移动了一位,输入的数字赋值给第一位数码管,并相应点亮左边的数码管。
(3)当按下功能键时,相应的功能键实现相应的功能,而数码管全部回零熄灭。
直到再一次输入数字。
图四数码管显示电路
图五重设密码数码管显示数字
图六密码正确显示黄灯
五软件程序设计
本系统软件设计由主程序、初始化程序、键盘扫描程序、密码输入程序、功能键定义程序、重置密码程序、数码管显示程序、中断延时程序、报警程序、延时程序组成。
5.1主程序流程图
如图六所示为主程序流程图,开始接上电源,程序进行初始化设置,然后在键盘上输入密码,此系统进行键盘扫描,判断密码是否正确,密码正确开锁,密码不正确统计错误密码次数加1。
在开锁情况下进行修改密码,点击确认密码修改成功,否则结束返回。
若密码修改成功则再执行之前的操作。
图六主程序流程图
5.2键盘扫描程序
键盘扫描主要就是对按键进行扫描、消抖并被定位。
键盘扫描流程图如图七所示。
图七键盘扫描流程图
键盘扫描C语言程序为:
voidget_key()
{P1=0xf0;
lie=P1;
P1=0x0f;
hang=P1;
addres=hang|lie;//行列寄存器中的值相或得到按键值
while(addres!
=0xff)
//判断是否有键按下,若adres的值不为0xff则有键按下
{delay(5);//延时消抖
P1=0xf0;
lie=P1;
P1=0x0f;
hang=P1;
addres=hang|lie;
if(addres!
=0xff)
{flag++;
switch(addres)//读取键值
{
case0xee:
num=1;break;//按键1动作,设num=1
case0xde:
num=2;break;//按键2动作,设num=2
case0xbe:
num=3;break;//按键3动作,设num=3
case0x7e:
num='A';break;//按键A动作,设num=Acase0xed:
num=4;break;//按键4动作,设num=4
case0xdd:
num=5;break;//按键5动作,设num=5case0xbd:
num=6;break;//按键6动作,设num=6
case0x7d:
num='B';break;//按键B动作,设num=B
case0xeb:
num=7;break;//按键7动作,设num=7case0xdb:
num=8;break;//按键8动作,设num=8
case0xbb:
num=9;break;//按键9动作,设num=9
case0x7b:
num='C';break;//按键C动作,设num=C
case0xd7:
num=0;break;//按键0动作,设num=0
case0x77:
num='D';break;//按键D动作,设num=D
}
}
}
}
5.3数码管显示子程序
数码管显示流程图如图八所示:
数码管显示程序为:
voiddisplay(ucharN)//显示
{if(N==1)//判断输入密码个数是否为1
{temp=0xfe;
P0=0x40;//点亮g段使显示为“—”
P2=temp;
delay
(1);//延时使左边第一位不停闪烁
P2=0xff;//点亮数码管右边N位
}
if(N==2)//判断输入密码个数是否为2
{temp=0xfe;
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);//带循环,使其挨个点亮
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
}
if(N==3)//判断输入密码个数是否为3
{temp=0xfe;
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
}
if(N==4)//判断输入密码个数是否为4
{temp=0xfe;
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
}
if(N==5)//判断输入密码个数是否为5
{temp=0xfe;
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
}
if(N==6)//判断输入密码个数是否为6
{temp=0xfe;
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
P0=0x40;
P2=temp;
delay
(1);
P2=0xff;
temp=_crol_(temp,1);
}
}
5.4报警电路
报警电路流程图如图九所示:
图九报警电路流程图
报警电路C语言程序:
voidalarm()
{if(km==3)判断输入错误密码的次数
{ucharn,m;
km=0;
for(m=50;m>0;m--)
{for(n=200;n>0;n--)
{K=~K;p3.1口取反
delay_us(1000);调用延时函数
}
K=0;p3.1口置零
delay(100);调用延时函数
}}
}
5.6密码重置子程序
密码重置的条件是在锁开,即灯亮的情况下进行的,所以调用密码子程序开始必须对显示器进行清零并熄灭,关闭发光二极管。
然后再调用输入密码子程序、键盘扫描子程序进行密码修改。
密码重置程序流程图如图十所示:
图十密码重置流程图
重置密码C语言程序:
voidrest_cipher()
{a=b=c=d=e=f=0;//熄灭数码管
N=0;//输入密码个数清零
D0=1;//p3.0口置1,led灯熄灭
while(con)
{get_key();//调用键盘扫描程序
if(N<6)//判断输入密码个数
cou_dis(num);//调用数字显示函数
disp(a,b,c,d,e,f);//6位数字显示子函数
if(num=='D')//D键按下
{con=0;}
if(num=='C')//C键按下
{a=b=c=d=e=f=0;//熄灭数码管
N=0;}//输入密码位数清零
a1=a;
b1=b;
c1=c;
d1=d;
e1=e;
f1=f;
}
a=b=c=d=e=f=0;//熄灭数码管
N=0;
}
六系统调试
本次调试采用的是protues和keil软件进行仿真。
首先运用keil软件编写电子密码锁的源程序,本设计主要运用C语言编写。
源程序编写后运行生成目标文件供protues仿真调试。
图十一为LED数码管显示六位密码的情况
图十一数码管显示密码图
当密码正确按下确认键发光二极管亮,锁开。
如图十二
图十二密码正确锁开灯亮
当密码输入错误三次蜂鸣器发出声音报警,如图十三所示
图十三蜂鸣器报警
由图十三可以看到蜂鸣器非接地端为红色,即此时为高电平,所以蜂鸣器正在发出报警声音。
Protues仿真电路图如图十四所示
图十四protues仿真电路图
Keil调试程序图(图十五)
七设计总结与展望
课程设计是培养学生综合运用所学知识发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。
随着科学技术发展的日新月异,单片机已经成为当今计算机应用中空前活跃的领域,在生活中可以说是无处不在。
因此作为二十一世纪的大学生来说掌握单片机的开发技术是十分重要的。
本设计经过多次修改和整理,可以满足基本的要求。
密码正确,锁开;密码输入错误三次,报警;输入密码超过6位之后的数无效;数码管显示屏显示密码为“—”。
在设计的过程中遇到了各种各样的问题,譬如说断电密码保护的设计,由于电路和编程都过于复杂,本设计并未加入。
在编程的过程中问题也是很多,由于程序较长,当实现了这个功能另外一个功能有不能很好的实现,所以要做到模块与模块之间的衔接。
遇到的一些问题也经过努力一一克服。
回顾此次单片机课程设计,至今我仍感触颇多。
在设计过程中从理论到实践我们可以到很多很多东西,巩固了以前学过的知识,还懂得了如何将理论联系实际。
只有理论知识是远远不够的,只有将理论运用到实际中对我们来说才是有意义的,这样才能真正的为社会服务。
八参考文献
【1】周向红.51单片机课程设计.华中科技大学出版社.2011年1月
【2】潘育山.单片机原理及51单片机开发技术.西南交通大学出版社.2009
【3】何利民.单片机高级教程.北京航空航天大学出版社.2006
【4】江志红.51单片机技术于应用系统开发.清华大学出版社.2008
九附录
源程序清单:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};//字模定义
voiddelay(uintz);//延时函数
voidget_key();//键盘扫描子程序
voidfun_key();//按键C,D子程序
voidinit();//初始化设置
voidexter0();//定时器T0中断服务
voiddisp(uchara,ucharb,ucharc,uchard,uchare,ucharf);
//6位数字显示子函数
voidrest_cipher();//重置密码子程序
ucharcou_dis(uchar);//数字右移函数
voiddisplay(uchar);//数码管显示程序
voidalarm();//报警电路程序
voiddelay_us(uchar);//延时函数
ucharhang,lie,addres,num,temp,flag,sum,fun,mark,con,N,km;
uintto,aa;
uchara,b,c,d,e,f;//数码管显示位数
uchara1,b1,c1,d1,e1,f1;
sbitD0=P3^0;
sbitK=P3^1;
voidmain()
{init();//初始化设置
while
(1)
{
get_key();//键盘扫描子程序
if(N<6)
cou_dis(num);//数字右移函数
fun_key();//按键C,D子程序
display(N);//数码管显示程序
if(to==2000)
{
to=0;
D0=1;//数码管熄灭
TR0=0;
mark=0;
}
alarm();//报警电路程序if(num=='A')
{to=0;
TR0=0;
while(mark)
{
rest_cipher();//重置密码子程序
mark=0;
}
}
}
}
voidinit()//初始化设置
{
K=0;//p3.1口置零
con=1;
mark=0;
temp=0xfe;
flag=0;
fun=0;
a1=6;//从右往左数第六位密码
b1=5;//第五位密码
c1=4;//第四位密码
d1=3;//第三位密码
e1=2;//第二位密码
f1=1;//第一位密码
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=0;
}
voidrest_cipher()//重置密码子程序
{a=b=c=d=e=f=0;//熄灭数码管
N=0;//输入密码个数清零
D0=1;//熄灭led灯
while(con)
{
get_key();//键盘扫描子程序
if(N<6)//判断输入密码的个数
cou_dis(num);//数字右移函数
disp(a,b,c,d,e,f);//数字显示函数
if(num=='D')
{con=0;}
if(num=='C')
{a=b=c=d=e=f=0;//熄灭数码管
N=0;}
a1=a;
b1=b;
c1=c