电子密码锁的设计.docx

上传人:b****6 文档编号:4436402 上传时间:2022-12-01 格式:DOCX 页数:19 大小:55.07KB
下载 相关 举报
电子密码锁的设计.docx_第1页
第1页 / 共19页
电子密码锁的设计.docx_第2页
第2页 / 共19页
电子密码锁的设计.docx_第3页
第3页 / 共19页
电子密码锁的设计.docx_第4页
第4页 / 共19页
电子密码锁的设计.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

电子密码锁的设计.docx

《电子密码锁的设计.docx》由会员分享,可在线阅读,更多相关《电子密码锁的设计.docx(19页珍藏版)》请在冰豆网上搜索。

电子密码锁的设计.docx

电子密码锁的设计

结合51单片机设计电子密码锁

【一】实验目的

电子密码锁是一种通过密码输入来控制电路或是芯片工作,从而控制机械开关的闭合,完成开锁、闭锁任务的电子产品。

它的种类很多,有简易的电路产品,也有基于芯片的性价比较高的产品。

现在应用较广的电子密码锁是以芯片为核心,通过编程来实现的。

其性能和安全性已大大超过了机械锁。

其特点如下:

1)保密性好,编码量多,远远大于弹子锁。

随机开锁成功率几乎为零。

2)密码可变,用户可以随时更改密码,防止密码被盗,同时也可以避免因人员的更替而使锁的密级下降。

3)误码输入保护,当输入密码多次错误时,报警系统自动启动。

4)无活动零件,不会磨损,寿命长。

5)使用灵活性好,不像机械锁必须佩带钥匙才能开锁。

6)电子密码锁操作简单易行,一学即会。

本次课程要求电子密码锁的设计是要求实验者具备了解和熟悉电子密码锁的功能和基本实现方法,具备一些电子时代操作人的基本素质。

【二】实验原理

本设计从实用的角度出发,采用单片机AT90C52RC作为主控芯片,AT24C02作为数据库存储单元,与外围的键盘输入、开锁、显示、报警等电路相结合,用C语言编写控制程序,设计的是一款不但具有报警功能而且能够多次更改密码的电子密码锁。

本次设计使用的AT90C52RC芯片实现的基于单片机的电子密码锁的设计,其主要功能如下:

(1)使用数码管显示器来显示密码输入的相关消息及提示。

(2)设置5位数字(0-9)密码,密码通过3x4矩阵键盘输入,若密码正确,则将锁打开,初始化密码为(00000)。

(3)密码可以由用户自己修改设定(5位密码),锁打开后才能修改密码。

再次输入密码,在输入新密码。

(4)密码输入正确则有相应的提示音,蜂鸣器会发出滴声响。

(5)密码输入错误,数码管显示会出现错误提示,若密码输入3次错误,蜂

鸣器报警并且自动锁定键盘。

(6)密码输入功能:

按下一个数字键,实现隐藏功能。

(7)密码清除功能:

当清除键被按下时,清除前面输入的一个值,并可以清除所有示。

(8)断电后密码仍然存在(保存在24C02中)。

【三】实施方案及本人承担的工作

项目名称为电子密码锁,是利用单片机开发板数码管模块,键盘输入模块来实现。

由于此次试验程序比较长,所以在开始编写程序的时候,我们计划一个模块一个模块编写,在开发板上一个一个实现之后再通过调用进主函数来完成,具体思路很清晰,但是具体实现就有点困难了。

这次实验我主要负责的是键盘扫描和主程序的编写,说实话我的单片机学的并不是很好,但是这并不影响我设计键盘扫描和主程序的代码.键盘扫描要的就是找到相关联的那两根线,然后通过输出的端口进行判断到底代码应该是多少.然后进行编写就是不是件困难的事了.在原来显示驱动试验中做过相应的程序,所以模块写入的过程倒不是很难。

主程序的代码由于是用c语言做的,因此在我们理解上而言还是通俗易懂的,我们比较吃力的地方也就是几个循环的位置商讨的较多,除此之外一切还是挺顺利的.还有在程序中扫描函数用的比较多,在扫描函数运用上分歧还是比较大,最后还是统一了。

【四】程序框

本系统共有两部分构成,即硬件部分与软件部分。

其中硬件部分由键盘输入部分、密码存储部分、显示部分、开锁部分组成,软件部分对应的由主程序、初始化程序、键盘扫描程序、启动程序、关闭程序、密码设置程序等组成。

具体原理框图如附录图所示。

【五】实验结果

在keil软件上输入完成程序之后运行逻辑没有错误,然后将程序下载如开发板。

完成之后,依次输入5个数字密码,由于程序中设有原始密码,输入后将与设定好的密码对比,若5个数字相同进入in界面,说明密码正确。

若5个数字不与设定密码相同,系统返回help界面,说明密码不正确。

最后用户在3次内都没能输入正确的密码,则蜂鸣器长时间报警,结束之后开始60秒倒计时,在这一分钟之内用户不能在键盘上进行任何操作,直至60S结束才能重新进行操作。

在输入密码的时候,输入的数字不显示,密码只有操作者自己知道。

在一段时间确认没有键盘输入时,*键上锁或者一段时间后自动上锁,时间由确定的j的大小决定,自动上锁的时间不会很长。

修改密码的时候,密码输入成功之后进入in界面之后才能修改。

【六】设计中遇到的问题及解决方法

这次密码锁设计遇到的最大的两个问题一个是错误三次锁死无法实现,一个是定时器功能无法实现。

一个问题产生的主要原因是因为早期将键盘扫描程序mat_keyget()写在了错误是否小于3次的判断语句之前,导致即使错误3次仍然能执行键盘扫描,未能达到锁死键盘的效果。

后来将mat_keyget()写在了主程序判断错误语句的里面,这样一旦错满3次,自动跳到外面,脱离了键盘扫描,从而达到了锁死键盘的效果。

实习中还遇到了其他些许问题,如定时12s,使用户若未能在12s内输入完密码并且按下确认键,即使密码输入正确也会被判为无效,即错误一次。

在实际操作过程中,t自加一次用时50ms,所以定时12s应为:

50*20*12。

而在实际操作过程中,由于晶振误差和操作误差,实际时间长于12s,因此最后将数值设为200,在循环内进行操作,减小了误差。

【七】总结

实践是检验真理的唯一标准,当然也是检验学习成果的标准。

在经过一段时间的学习之后,我们需要了解自己的所学应该如何应用在实践中,因为任何知识都源于实践,归于实践,所以要将所学的知识在实践中来检验。

从这次试验如果要一个人来做,我想也是做不了这么快的,因此我们不得不归功于集体的力量,分配合作对于这种近乎于模块化设计的东西来说是非常有利的,当然我们也碰到过问题,这在调试错误这一节中也说得很是明白了,但是我们也并没有灰心丧气,也是把问题一点一点地克服了下来.在这个之中我也是深切的感受到了理论知识的重要性,不能光是从手头上从硬件上找问题,我们也要从软的例如程序上或是设计思路上思考这样的解决方案是不是有较大的缺陷.

通过这个不难也不是很简单的实验我们认识到了团结协作,互帮互助的好处,这次课程设计也可以说是考完试后通过实践检验真理的一次宝贵机会,我们都为能够顺利完成本次实验感到无比的骄傲和自豪。

附录:

主要源程序以及原理实现框图

程序代码:

main.c

#include"reg52.h"

#include"string.h"

#include"display.h"

#include"mat_keyget.h"

#include"24c02.h"

#include"status.h"

unsignedchardigital_display[]={16,16,16,16,16,16,16,16};

unsignedchare2prom_addr[]={0x00,0x01,0x02,0x03,0x04};

unsignedcharcodecipher[]={2,2,3,4,5};

unsignedcharcipher_temp[6],password[5];

unsignedcharerror_num=0;

unsignedcharcodedigital_lock[]={26,26,17,18,19,26,26,26};//--OUT---

unsignedcharcodedigital_open[]={26,26,20,21,22,23,26,26};//--OPEN--

unsignedcharcodedigital_help[]={26,26,20,22,25,21,26,26};//--HELP--

unsignedcharcodedigital_in[]={26,26,26,24,25,26,26,26};//---IN---

voidlock(void)//关锁

{

unsignedchari;

for(i=0;i<8;i++)

digital_display[i]=digital_lock[i];

buzzer_on();

delay_500us(200);

buzzer_off();

}

voidopen(void)//开锁

{

unsignedchari;

for(i=0;i<8;i++)

digital_display[i]=digital_open[i];

buzzer_on();

delay_500us(200);

buzzer_off();

delay_500us(200);

buzzer_on();

delay_500us(200);

buzzer_off();

}

voidcipher_change()//修改密码

{

unsignedchari=0;unsignedcharj;

digital_display[0]=26;digital_display[1]=26;digital_display[2]=26;digital_display[3]=26;

digital_display[4]=26;digital_display[5]=16;digital_display[6]=16;digital_display[7]=16;

while(i!

=5)

{

if(mat_keyget()!

=10)

{

j=mat_keyget();

delay_500us(20);

if(mat_keyget()==j)

{

if(j==11)//*键删除,

{

if(i>0){

i--;

digital_display[i]=23;

}

}

else{

if(j==12);//#键无效

else{

cipher_temp[i]=j;

digital_display[i]=27;//隐藏密码

i++;

}

}

}

while(mat_keyget()!

=10)digital_tube(digital_display);//松手检测

}

digital_tube(digital_display);

}

while(mat_keyget()!

=12)digital_tube(digital_display);

for(j=0;j<5;j++)

wrbyte_24c02(e2prom_addr[j],cipher_temp[j]);

for(j=0;j<5;j++)

password[j]=rdbyte_24c02(e2prom_addr[j]);//读取密码

for(j=0;j<8;j++)//显示成功界面

digital_display[j]=digital_in[j];

while(j<200)//*键上锁或者一段时间后自动上锁,时间有I的大小决定;

{

if(mat_keyget()==11)//*键上锁

{

digital_tube(digital_display);

if(mat_keyget()==11)

{lock();break;}

}

digital_tube(digital_display);

}

}

voidcipher_input()

{

unsignedchari=0;

unsignedintj;

digital_display[0]=26;digital_display[1]=26;digital_display[2]=26;digital_display[3]=26;

digital_display[4]=26;digital_display[5]=16;digital_display[6]=16;digital_display[7]=16;

while(i!

=5)

{

if(mat_keyget()!

=10)

{

j=mat_keyget();

delay_500us(20);

if(mat_keyget()==j)

{

if(j==11)//*键删除

{

if(i>0)

{

i--;

digital_display[i]=23;

}

}

else{

if(j==12);//无效按键

else{

cipher_temp[i]=j;

digital_display[i]=27;//隐藏密码

i++;

}

}

}

while(mat_keyget()!

=10)digital_tube(digital_display);

}

digital_tube(digital_display);

}

while(mat_keyget()!

=12)digital_tube(digital_display);

if(memcmp(cipher_temp,password,5)==0)//密码相同,开锁

{

open();j=0;

while(j<500)

{

if(mat_keyget()==11)//*键上锁

{

digital_tube(digital_display);

if(mat_keyget()==11)

{lock();break;}

}//#键修改密码

if(mat_keyget()==12)

{

digital_tube(digital_display);

if(mat_keyget()==12)

{

while(mat_keyget()!

=10)digital_tube(digital_display);

cipher_change();

break;

}

}

digital_tube(digital_display);//界面显示

j++;//一段时间后自动上锁

}

lock();

}

else//错误报警

{

for(j=0;j<8;j++)//显示错误界面

digital_display[j]=digital_help[j];

for(j=0;j<250;j++)

digital_tube(digital_display);

lock();

error_num++;

if(error_num==3)//错误超过三次长报警

{

error_num=0;

buzzer_on();

for(j=0;j<8;j++)

digital_display[j]=digital_help[j];

for(j=0;j<250;j++)

digital_tube(digital_display);

buzzer_off();

j=60;i=0;//显示倒计时

digital_display[0]=16;digital_display[1]=16;digital_display[2]=16;digital_display[3]=16;

digital_display[4]=16;digital_display[5]=16;digital_display[6]=16;digital_display[7]=16;

while(j>0)

{

digital_display[6]=j/10;

digital_display[7]=j%10;

for(i=0;i<150;i++)

{

digital_tube(digital_display);

}

j--;

}

lock();

}

}

}

voidinit(void)

{

unsignedchari;

for(i=0;i<5;i++)

password[i]=rdbyte_24c02(e2prom_addr[i]);//读取密码

lock();

}

voidmain(void)

{

init();

while

(1)

{

if(mat_keyget()==12)//#键开始密码输入

{

digital_tube(digital_display);

if(mat_keyget()==12)

{

while(mat_keyget()!

=10)//松手检测

digital_tube(digital_display);

cipher_input();//输入密码

}

}

digital_tube(digital_display);//待机界面

}

}

键盘扫描模块:

#include"mat_keyget.h"

//3×4键盘矩阵扫描函数

unsignedcharmat_keyget(void)

{

unsignedchartemp=10;

P1=0xfe;

switch(P1)

{

case0xee:

temp=1;break;//对应显示"1"

case0xde:

temp=2;break;//对应显示"2"

case0xbe:

temp=3;break;//对应显示"3"

default:

break;

}

P1=0xfd;

switch(P1)

{

case0xed:

temp=4;break;//对应显示"4"

case0xdd:

temp=5;break;//对应显示"5"

case0xbd:

temp=6;break;//对应显示"6"

default:

break;

}

P1=0xfb;

switch(P1)

{

case0xeb:

temp=7;break;//对应显示"7"

case0xdb:

temp=8;break;//对应显示"8"

case0xbb:

temp=9;break;//对应显示"9"

default:

break;

}

P1=0xf7;

switch(P1)

{

case0xe7:

temp=11;break;//对应显示"*"

case0xd7:

temp=0;break;//对应显示"0"

case0xb7:

temp=12;break;//对应显示"#"

default:

break;

}

return(temp);

}

#ifndef_DISPLAY_H

#ifndef_MAT_KEYGET_H

#define_MAT_KEYGET_H

#include"reg52.h"

unsignedcharmat_keyget();

#endif

数码管显示模块:

#include"display.h"

unsignedchardigital_duan[]={

0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,

0xc6,0xa1,0x86,0x8e,

0xff,0xC0,0xC1,0xCE,//16:

全灭17:

018:

U19:

T

0x89,0x8C,0x86,0xC8,//20:

H21:

P22:

E23:

N

0XCF,0XC7,0xBF,0x00,//24:

I25:

L26:

-27:

全亮

};//全灭;0xff全亮:

0x00;

//OPENO:

0XC0;P:

0X8C;E:

0X86;N:

0XC8-:

0XBF

unsignedchardigital_wei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

//延时nms

voiddelay_500us(unsignedintnms)

{

unsignedinti,j;

for(i=nms;i>0;i--)

for(j=110;j>0;j--);

}

voiddigital_tube(unsignedchardisplay[])

{

unsignedchari;

for(i=0;i<8;i++)

{

P2=digital_wei[i];//打开第i个COM口

P0=digital_duan[display[i]];//送入显示数据

delay_500us

(1);

}

}

#ifndef_DISPLAY_H

#define_DISPLAY_H

#include"reg52.h"

voiddelay_500us(unsignedintnms);

voiddigital_tube(unsignedchardisplay[]);

#endif

蜂鸣器模块:

#include"status.h"

sbitbuzzer=P3^7;

voidbuzzer_off(void)//蜂鸣器打开

{

buzzer=1;

}

voidbuzzer_on(void)//蜂鸣器关闭

{

buzzer=0;

}

#include"reg52.h"

#ifndef_STATUS_H

#define_STATUS_H

voidbuzzer_on(void);

voidbuzzer_off(void);

#endif

24c02存储模块:

#include"24c02.h"

voidiic_start(void)

{

SDA=1;

_nop_();

SCL=1;

somenop;

SDA=0;

somenop;

SCL=0;

}

voidiic_stop(void)

{

SDA=0;

_nop_();

SCL=1;

somenop;

SDA=1;

}

voidiic_ack(bitackbit)

{

if(ackbit)

SDA=0;

else

SDA=1;

somenop;

SCL=1;

somenop;

SCL=0;

SDA=1;

somenop;

}

bitiic_waitack(void)

{

SDA=1;

somenop;

SCL=1;

somenop;

if(SDA)

{

SCL=0;

iic_stop();

return0;

}

else

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 起诉状

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1