基于单片机的电子密码锁设计.docx
《基于单片机的电子密码锁设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的电子密码锁设计.docx(28页珍藏版)》请在冰豆网上搜索。
基于单片机的电子密码锁设计
嵌入式系统项目实践
课程报告
题目基于单片机的电子密码锁设计
团队成员
专业网络工程
指导教师
2014年10月9日
基于单片机的电子密码锁设计
摘要:
随着信息技术的不断发展,信息化时代也逐步进入普通家庭,人们对个人的信息安全以及隐私等私密信息的安全要求不断提高,传统的机械锁已经不能满足要求。
针对此现状设计一款安全可靠廉价的电子密码锁。
该设计以AT89C51为主控芯片,带有一个密码输入键盘、外围时钟复位电路、存储单元24C04、显示单元1602LCD,通过LED灯的亮与灭表示电子锁的锁闭与打开。
利用单片机灵活的编程设计和丰富的IO端口,能实现密码锁的基本功能。
为了提高可读性采用了1602作为显示单元,使用户对密码锁的运行情况一目了然。
该系统经软硬件测试,达到要求,系统运行良好。
关键词:
单片机;AT89C51;1602LCD;24C04;电子密码锁
1绪论
1.1选题背景
在人们的生活中,财产与人身安全是被一直关注的问题,于是“锁”也就与人们的生活密不可分了,无论在何地,我们都能看到“锁”的身影,但随着社会的发展,传统的机械锁越来越不能满足人们的生活需求了,传统的机械锁由于其构造的简单,被撬的事件屡见不鲜。
锁具发展到现在已有若干年的历史了,人们对它的结构、机理也研究得很透彻,因此,不用钥匙就能打开的方法和工具也层出不穷。
为了应对这种情况,电子密码锁也就被发明出来了,相比传统的机械锁,电子密码锁具有更高的安全性。
1.2研究意义
电子锁可以在日常生活和现代办公中、住宅与办公室的安全防范、单位的文件档案、财务报表以及一些个人资料的保存等多种场合使用,大大提高了主人物资的安全性。
此次项目实践选择基于单片机的电子密码锁设计题目,采用存储单元24C04和显示单元1602LCD来进行设计。
单片机技术是智能化检测与控制领域应用非常普及并且具有很大潜力的技术。
论文阐述一个基于单片机的液晶显示电子密码锁的设计与实现。
系统采用美国Atmel公司的AT89C51单片机作为系统核心,用串行的24C04作为存储器,液晶显示器LCD1602作为输出设备显示系统提示信息,4*4矩阵薄膜键盘作为输入设备,配合蜂鸣器、继电器等电路构成整个系统硬件;系统软件采用汇编语言编写。
设计的系统液晶显示,密码修改方便,具有报警、锁定等功能,使用便捷简单,符合住宅、办公用锁需求,具有一定的实用价值.而且使用AT89C51单片机价格相对低廉,成本较低,便于推广。
1.3内容与结构
本系统设计实现一个基于单片机控制的电子密码锁。
该系统能够实现上锁、开锁、修改开锁密码和报警功能,用串行的24C04作为存储器,液晶显示器LCD1602作为输出设备显示系统提示信息。
该文档主要包括五个部分,第一部分绪论,主要包括选题背景、研究意义和内容与结构;第二部分系统整体设计方案,主要包括相关知识介绍和系统总体结构设计;第三部分硬件电路,主要包括单元电路设计和系统总硬件电路图,其中单元电路设计包括单片机最小系统模块,24C04存储电路模块,1602LCD数码管显示电路和矩阵键盘电路设计模块;第四部分软件模块设计,主要包括系统开发工具使用和系统主要开发流程和各软件设计模块;第五部分结果分析,主要包括测试过程和测试结果分析。
2系统整体设计方案
2.1相关知识介绍
2.1.1AT89C51引脚功能描述
AT89C51是这几年我国非常流行的单片机,由美国ATMEL公司生产,是低电压,高性能CMOS8位单片机,片内含4k bytes的可反复擦写的只读程序存储器(PEROM)和128 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和Flash存储单元。
其中的40个引脚大致可以分为4类:
电源、时钟、控制和I/O引脚。
(1)电源 :
VCC为芯片电源端,一般为+5V,GND为接地端;
(2)时钟 :
XTAL1为晶体振荡电路的反相输入端 ,XTAL2为晶体振荡电路的输出端;
(3)控制线 :
MCS-51单片机的控制线有4根,其中3根是复用线,具有两种功能。
ALE/PROG为地址锁存允许/编程脉冲信号端 ,PSEN为外部ROM读选通信号 ,RST为复位引脚 ;EA/VPP为内外ROM选择/EPROM编程电源 ;
(4)I/O引脚 :
MCS-51单片机共有4个8位并行I/O端口,共32个可编程I/O引脚。
其外形引脚如图2-1所示:
图2.1AT89C51实物图(左)及其引脚图(右)
2.1.2LCD1602性能描述
LCD1602是工业字符型液晶,能够同时显示16x02即32个字符,是一种专门用来显示字母、数字、符号等的点阵型液晶模块,字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样[6]。
LCD引脚图如下图2.6所示:
图2.2LCD1602功能引脚图
2.1.324C04性能描述
24C04是采用铁电技术生产的EEPROM,掉电后数据不丢失。
相比传统的EEPROM具有寿命长,读写速度快的优点,采用I2C总线与外界通讯,容量应该是512字节。
主要用于存储掉电后需要保存的数据。
24C04存储电路如图2.3所示:
图2.324C04存储电路
2.2系统总体设计
此设计的主要内容与任务如下:
(1)设计一单片机控制的智能报警系统,通过按键输入密码,并用LCD显示相关信息 ;
(2)密码可由键盘设置,键盘有数字键、还有确认按键;
(3)密码可通过按键修改;
(4)输入字符时,LCD上显示“*”号,若密码正确,则可以修改密码;
(5)系统设置默认初始密码,且可以修改,修改后系统按新密码进行操作。
依据设计的要求,可以得到系统软件模块图,如图2.4所示:
基于单片机的电子密码器
时钟震荡电路
模块
矩阵
键盘输入模块
LCD显示模块
密码存储模块
蜂鸣器报警电路模块
图2.4系统的软件模块图
3硬件电路
用单片机做主机运算器,能进行密码修改和管理员密码设置,可复位,设置有退出键、管理员模式键、设定键、删除键和确定键。
LCD在开锁前显示youpassword,然后根据密码正确与否显示出相应的提示。
本设计初始密码为123456,密码输入正确后,可以修改密码,密码个数可以是0-9的数字。
采用24C04存储密码,有掉电保护功能,本设计采用4*4的矩阵键盘作为输入,AT89C51单片机作为主机, 二极管指示灯和喇叭组成发声系统。
根据系统拟达到的总体功能得到系统整体框图如图3.1所示:
LCD显示
键盘输入
AT89C51
蜂鸣器报警与开锁电路
掉电存储电路
图3.1系统整体框图
3.1单元电路设计
要实现基于单片机电子密码锁的功能。
硬件设计包括单片机最小系统的设计,1602LCD数码管显示电路设计,矩阵键盘电路设计和系统总电路的设计。
3.1.1单片机最小系统
单片机最小系统都是由组成单片机应用系统所必需的一些部件和电路构成的。
无论应用系统要完成什么功能,这些部件和电路都是必须的。
一个单片机应用系统至少有:
单片机芯片、保证单片机正常工作必须要有电源、产生时钟信号的晶体振荡器,还需要能使单片机复位的电路等。
单片机最小系统如图3.2所示:
图3.2单片机最小系统
3.1.21602LCD数码管显示电路
1602LCD液晶显示器是一种字符点阵式LCD显示器模块。
它不仅能够显示阿拉伯数字,而且还能够显示特殊的符号,以及英文字母(即英文语句提示信息),因此其用途比较灵活,应用比较广泛,当然价格也较高。
单片机AT89C51从接收器得到的数据运算程序后,结果传送给1602LCD数据端并在液晶屏上显示出。
显示电路如图3.3所示:
图3.31602LCD数码管显示电路
3.1.3矩阵键盘电路
矩阵式键盘又叫行列式键盘。
用I/O接口线组成行、列结构,键位设置在行、列的交点上。
例如本设计4*4的行、列结构可组成16个键盘,比一个键位用一根I/O口线的独立式键盘少了一半的I/O接口线。
而且键位越多,情况越明显。
因此,在按键比较多时,往往采用矩阵式键盘。
矩阵式键盘的按键识别方法 有“行扫描法”。
行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,介绍过程如下。
(1)判断键盘中有无键按下 将全部行线Y0-Y3置低电平,然后检测列线的状态。
只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。
若所有列线均为高电平,则键盘中无键按下。
(2)判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。
其方法是:
依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。
在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。
若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
矩阵键盘电路如图3.4所示:
图3.4矩阵键盘电路图
3.2系统总硬件电路图
各模块组合之后的总体硬件电路图如下图3.5所示:
图3.5总体硬件电路图
4软件模块设计
4.1系统开发工具使用
本系统使用keil软件,打开软件后的界面,如下图4.1所示,
图4.1软件运行界面
单击Project选择NewProject...,弹出CreateNewProject对话框,
图4.2新建系统工程
选择工程文件要存放的路径,输入工程文件名,最后单击保存,
图4.3设置工程路径
在弹出的对话框中选择CPU厂商及型号,选择好Atmel公司的89C51后,单击确定,
图4.4选择芯片厂商和型号
新建一个C51文件,点击file菜单下的NEW,或单击左上角的NewFile快捷键如图4.5,
图4.5新建文件
保存新建的文件,单击SAVE,在出现的对话框中输入保存文件名LCD_18b20.c(注意后缀名必须为.C),再单击“保存”,保存好后把此文件加入到工程中方法如下:
用鼠标在SourceGroup1上单击右键,然后再单击AddFilestoGroup‘SourceGroup1'如图4.6,
图4.6将文件添加到工程中
在编辑框里输入如下代码,到此我们完成了工程项目的建立以及文件加入工程,现在我们开始编译工程,即单击快捷键或单击Project/Rebuildallthefiles,如果在错误与警告处看到0Error(s)表示编译通过。
生成.hex烧写文件,先单击OptionsforTarget,如图4.7,
图4.7生成.hex
在下图中,我们单击Output,选中CreateHEXFi。
再单击“确定”,然后我们必须再次编译才能产生HEX文件
图4.8对系统进行配置
4.2系统开发流程图
程序主要完成的任务,开始时LCD显示“YourPassword”提示输入密码,输入密码后按确认键,系统会将所输入的密码与系统密码进行对比,如果输入正确则显示“UnlockOK”开锁,然后可以选择上锁或者修改密码,如果密码错误则显示“Error”,如果连续输入三次错误密码系统会发出报警声音,程序流程图如图4.9所示:
图4.9系统总体流程图
4.3系统软件设计模块
4.3.1键盘扫描软件设计
在按键当中,有与输入、开锁、清除、设置、确认的程序相对应的按键,并按顺序与输入的数相比较,当输入正确时,进入密码程序,错误时进行清除,输入两次新密码正确时,可进行重新设置密码,最后确认程序。
按键的检测主要是通过查询的方法来实现的,利用按键进行密码的输入及设置。
图4.10键盘扫描流程图
4.3.224C04读写操作的软件设计
图4.1124C04读写操作流程图
4.3.224C04读写操作的软件设计
图4.12开锁流程图
4.3.4修改密码软件设计
图4.13修改密码流程图
5结果分析
程序编写完之后,单击Rebuild(
)按钮,进行编辑,单击build(
)按钮,进行编译,将.hex文件下载到ATC89C51开发板中。
图5.1配置电路图参数
单击左下角的
中的按钮进行仿真。
5.1电子密码锁开锁和上锁
在矩阵键盘上输入初始密码123456,并点击开锁按钮,如果输入密码错误,则LCD显示“ERROR!
”,无法开锁;若输入正确,则显示“UnlockOK!
”,表示开锁成功,如图5.2所示:
图5.2开锁后LCD显示图
再按下上锁按键后,电子密码锁重新上锁,需要重新输入开锁密码才可开锁,当三次输入错误密码时,蜂鸣器会发出响声报警。
5.2修改电子密码锁密码
在已经开锁的状态下,按下输入新密码按钮,可重新输入密码,设置成你想要改的密码,再按下保存新密码按钮,新密码就设置成功了,这时开锁需要输入新密码了,如图5.3所示
图5.3电子密码锁修改密码
此次项目实践的基于单片机电子密码锁设计比较成功,能实现开锁上锁、修改密码、报警防盗等功能。
结论
本次项目实践过程中,对我所学的所有的嵌入式知识进行一个总结性的复习,特别是对AT89C51单片机方面的知识有了更深的了解。
同时也巩固了对LCD1602,数据存储等方面的知识,为我以后的学习以及工作奠定了一定的专业基础。
在这次设计中,遇到了一些设计上的难题,通过查阅相关图书资料和询问同学帮助解决了难题。
参考文献
[1]祁伟,杨亭.单片机C51程序设计教程与实验[M].北京航空航天大学出版社,2006.
[2]刘文涛.单片机语言C51典型应用设计[M].人民邮电出版社,2005.
[3]谭浩强.C程序设计(第三版)[M].清华大学出版社,2005.
[4]沈德金.MCS-51系列单片机接口电路与应用程序实例[M].北京航空航天大学出版社,1990.
[5]赖麒文.8051单片机C语言彻底应用[M].科学出版社,2002.
[6]余永权.单片机在控制系统中的应用[M].电子工业出版社,2003.
[7]张艳丽,杨仁弟.数字温湿度传感器SHT11及其应用[J].工矿自动化,2007.6第3期.
[8]沈庆阳.8051单片机实践与应用[M].清华大学出版社2004.
[9]高卫东.51单片机原理与实践(C语言版)[M].北京航空航天大学出版社,2011.
[10]蒋辉平,周国雄.基于Protues的单片机系统设计与仿真实例[M].机械工业出版社,2009.
附录:
程序代码:
#include
#include
#defineucharunsignedchar
#defineunitunsignedint
ucharPre_KeyNo=16,KeyNo=16;
ucharcodeTitle_Text[]="YourPassword...";
ucharDSY_BUFFER[10]="";
ucharUserPassword[10]="";
voidLCD_Init();
voidDisplay_String(uchar*str,ucharLineNo);
voidIIC_24C04_Init();
ucharRecString(ucharSlave,ucharSubaddr,uchar*Buffer,ucharN);
ucharSendString(ucharSlave,ucharSubaddr,uchar*Buffer,ucharN);
ucharKeys_Scan();
sbitLED_OPEN=P2^7;
voidDelayMS(intx)
{
uchari;
while(x--)for(i=0;i<120;i++);
}
voidClear_Password()
{
UserPassword[0]='\0';
DSY_BUFFER[0]='\0';
}
voidmain()
{
uchari=0;
ucharIIC_Password[10];
ucharIS_Valid_User=0;
P0=P1=P2=0xFF;
TMOD=0X02;
TH0=175;
TL0=175;
TR0=1;
DelayMS(10);
LCD_Init();
IIC_24C04_Init();
Display_String(Title_Text,0x00);
RecString(0xa0,0,IIC_Password,6);
IIC_Password[6]='\0';
while
(1)
{
P1=0xF0;
if(P1!
=0xF0)KeyNo=Keys_Scan();
if(Pre_KeyNo!
=KeyNo)
{
if(i<10)
{
switch(KeyNo)
{
case0:
case1:
case2:
case3:
case4:
case5:
case6:
case7:
case8:
case9:
if(i==0)Display_String("",0x40);
UserPassword[i]=KeyNo+'0';
UserPassword[i+1]='\0';
DSY_BUFFER[i]='*';
DSY_BUFFER[i+1]='\0';
Display_String(DSY_BUFFER,0X40);
i++;
break;
case10:
if(strcmp(UserPassword,IIC_Password)==0)
{
LED_OPEN=0;
Clear_Password();
Display_String("UnlockOK!
",0x40);
IS_Valid_User=1;
}
else
{
LED_OPEN=1;
Clear_Password();
Display_String("ERROR!
",0x40);
IS_Valid_User=0;
}
i=0;
break;
case11:
LED_OPEN=1;
Clear_password();
Display_String(Title_Text,0x00);
Display_String("",0x40);
i=0;
IS_Valid_User=0;
break;
case12:
if(!
IS_Valid_User)Display_String("Norights!
",0x40);
else
{
i=0;
Display_String("NewPassword:
",0x00);
Display_String("",0x40);
}
break;
case13:
if(!
IS_Valid_User)Display_String("Norights!
",0x40);
else
{
SendString(0xa0,0,UserPassword,6);
RecString(0xa0,0,IIC_Password,6);
IIC_Password[6]='\0';
i=0;
Display_String(Title_Text,0x00);
Display_String("PasswordSaved!
",0x40);
}
break;
case14:
i=0;
Clear_Password();
Display_String("",0x40);
}
}
Pre_KeyNo=KeyNo;
}
DelayMS(100);
}
}
#include
#include
#defineucharunsignedchar
#defineunitunsignedint
#defineDelay4us();{_nop_();_nop_();_nop_();_nop_();}
sbitSCL=P3^2;
sbitSDA=P3^3;
voidStart()
{
SDA=1;SCL=1;Delay4us();SDA=0;Delay4us();SCL=0;
}
voidStop()
{
SDA=0;SCL=1;Delay4us();SDA=1;Delay4us();SCL=0;
}
voidIIC_24C04_Init()
{
SCL=0;Stop();
}
voidACK()
{
SDA=0;SCL=1;Delay4us();SCL=0;SDA=1;
}
voidNo_ACK()
{
SDA=1;SCL=1;Delay4us();SCL=0;SDA=0;
}
ucharRecByte()
{
uchari,rd;
rd=0x00;
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;rd<<=1;rd|=SDA;Delay4us();SCL=0;Delay4us();
}
SCL=0;
Delay4us();
returnrd;
}
ucharSendByte(ucharwd)
{
uchari;
bitack0;
for(i=0;i<8;i++)
{
SDA=(bit)(wd&0x80);
_nop_();_nop_();SCL=1;Delay4us();SCL=0;wd<<=1;
}
Delay4us();
SDA=1;
SCL=1;
Delay4us();
ack0=!
SDA;
SCL=0;
Delay4us();
returnack0;
}
ucharSendString(ucharSlave,ucharSubaddr,uchar*Buffer,ucharN)
{
uchari;
Start();
if(!
SendByte(Slave))return0;
if(!
SendByte(Subaddr))return0;
for(i=0;i{
if(!
SendByte(Buffer[i]))return0;
}
Stop();
return1;
}
ucharRecS