前言
随着电子技术的发展,具有防盗报警等功能的电子密码锁代替密码量少、安全性差的机械式密码锁已是必然趋势。电子密码锁与普通机械锁相比,具有许多独特的优点:保密性好,防盗性强,可以不用钥匙,记住密码即可开锁等。目前使用的电子密码锁大部分是基于单片机技术,以单片机为主要器件,其编码器与解码器的生成为软件方式。
下面就是现在主流电子密码锁:目前常见的遥控式电子防盗锁主要有光遥控和无线电遥控两类。键盘式电子密码锁从目前的技术水平和市场认可程度看,使用最为广泛的是键盘式电子密码锁,该产品主要应用于保险箱、保险柜和金库,还有一部分应用于保管箱和运钞车。卡式电子防盗锁使用各种“卡”作为钥匙的电子防盗锁是当前最为活跃的产品,无论卡的种类如何多种多样,按照输入卡的操作方式,都可分为接触式卡和非接 触式卡两大类。生物特征防盗锁人的某些与生俱来的个性特征(如手、眼睛、声音的 特征)几乎不可重复,作为“钥匙”就是唯一的(除非被逼迫或伤害)。因此,利用生物特征做密码的电子防盗锁,也特别适合金融业注重“验明正身”的行业特点。
人们生活水平的提高和安全意识的加强,对安全的要求也就越来越高。锁自 古以来就是把守护门的铁将军,人们对它要求甚高,既要安全可靠的防盗,又要使用方便,这也是制锁者长期以来研制的主题。随着电子技术的发展,各类电子产品应运而生,电子密码锁就是其中之一。据有关资料介绍,电子密码锁的研究从20世纪30年代就开始了,在一些特殊场所早就有所应用。这种锁是通过键盘输入一组密码完成开锁过程。研究这种锁的初衷,就是为提高锁的安全性。由于电子锁的密钥量(密码 量)极大,可以与机械锁配合使用,并且可以避免因钥匙被仿制而留下安全隐患。电子锁只需记住一组密码,无需携带金属钥匙,免除了人们携带金属钥匙的烦恼,而被越来越多的人所欣赏。电子锁的种类繁多,例如数码锁,指纹锁,磁卡锁,IC 卡锁,生物锁等。但较实用的还是按键式电子密码锁。20世纪80年代后,随着电子锁专用集成电路的出现,电子锁的体积缩小,可靠性提高,成本较高,是适合使用在安全性要求较高的场合,且需要有电源提供能量,使用还局限在一定范围,难以普及,所以对它的研究一直没有明显进展。 目前,在西方发达国家,电子密码锁技术相对先进,种类齐全,电子密码锁已被 广泛应用于智能门禁系统中,通过多种更加安全,更加可靠的技术实现大门的管理。
在我国电子锁整体水平尚处于国际上70年代左右,电子密码锁的成本还很高,市场上仍以按键电子锁为主,按键式和卡片钥匙式电子锁已引进国际先进水平,现国内有几个厂生产供应市场。但国内自行研制开发的电子锁,其市场结构尚未形成,应用还不广泛。国内的不少企业也引进了世界上先进的技术,发展前景非常可观。希望通过不断的努力,使电子密码锁在我国也能得到广泛应用。
一、 作品功能:
1、设置6位密码,密码通过键盘输入,若密码正确,则将锁打开。 2、密码可以由用户自己修改设定(只支持6位密码),锁打开后才能修改密
码。修改密码之前必须再次输入密码,在输入新密码时候需要二次确认,以防止误操作。
3、报警、锁定键盘功能。密码输入错误显示器会出现错误提示,若密码输
入错误次数超过3次,蜂鸣器报警并且锁定键盘。 4、AT24C02保存密码,支持复位保存,掉电保存功能。 二、按键说明
按键定义图
如图示:采用4X4键盘输入,键盘对应名称如下:
1 2 3 A 4 5 6 B 7 8 9 C * 0 # D
其中, 【0—9】为数字键,用于输入相应的密码, 【*】号键为取消当前操作 【#】号键为确认 【D】键为修改密码 其它键无功能及定义 三、操作说明:
密码锁初始密码为:000000.
1、开锁:插上电源后,程序自动调入初始密码,此时依次输 入:000000,然后按【#】(确认)键,此时锁会打开,可以看到显示open,密码锁打开。 2、退出并关锁:按下【*】(取消)键,此时锁关闭,所有输入清除。 3、修改密码:在开锁状态下,再次输入正确的密码并按下【#】(确认)键,此
时听到两声提示,输入新的六位密码并按【D】(重设)键,再重复输入一次新密码并按【D】,会听到两声提示音,表示重设密码成功,内部保存新密码并存储到AT24C02。(如两次输入的新密码不一样,则重设密码失败)。 4、报警并锁定键盘:当输入密码错误后,报警并锁定键盘3秒,如3秒内又有按键,3秒再启动。
5、当重置新密码时,新密码会保存于AT24C02存储器里。
四、框图及流程图 1、系统结构框图
键盘输入模块 AT89S52 显示模块 复位电路 密码存储模块 报警电路 开锁电路
2、主程序设计流程图
初始化
开锁 修改
输入旧密码 密码正确 N Y N N 开锁 出错报警 原密码相同 Y
设新密码
返回
3、键功能程序流程图。
N Y N 键值=设置? 键值=0~9? 键功能程序 Y 密码输入程序 N Y 开锁程序 键值=开锁? Y 设置程序 键值=确认? 确认程序
N 返回
4、开锁程序流程图
输入密码 按开锁键 LCD初始化 开锁
Y 返回 开锁成功 N 输入密码正确? 报警程序 确认程序
5.电子密码锁原理图
程序(c语言)
#include #define uchar unsigned char #define uint unsigned int #define w 6 //定义密码位数 sbit lcd1602_rs=P2^5; sbit lcd1602_rw=P2^6; sbit lcd1602_en=P2^7; sbit Scl=P3^4; //24C02串行时钟 sbit Sda=P3^5; //24C02串行数据 sbit ALAM = P2^1; //报警 sbit KEY = P2^0; //开锁 sbit open_led=P2^2; //开锁指示灯 bit operation=0; //操作标志位 bit pass=0; //密码正确标志 bit ReInputEn=0; //重置输入充许标志 bit s3_keydown=0; //3秒按键标志位 bit key_disable=0; //锁定键盘标志 unsigned char countt0,second; //t0中断计数器,秒计数器 void Delay5Ms(void); unsigned char code a[]={0xFE,0xFD,0xFB,0xF7}; //控盘扫描控制表 unsigned char code start_line[] = {\"password: \ unsigned char code name[] = {\"===Coded Lock===\显示名称 unsigned char code Correct[] = {\" correct \//输入正确 unsigned char code Error[] = {\" error \//输入错误unsigned char code codepass[] = {\" pass \ unsigned char code LockOpen[] = {\" open \ //OPEN unsigned char code SetNew[] = {\"SetNewWordEnable\ unsigned char code Input[] = {\"input: \ //INPUT unsigned char code ResetOK[] = {\"ResetPasswordOK \unsigned char code initword[] = {\"Init password...\unsigned char code Er_try[] = {\"error,try again!\unsigned char code again[] = {\"input again \ unsigned char InputData[6]; //输入密码暂存区unsigned char CurrentPassword[6]={1,3,1,4,2,0}; //当前密码值 unsigned char TempPassword[6]; unsigned char N=0; //密码输入位数记数 unsigned char ErrorCont; //错误次数计数 unsigned char CorrectCont; //正确输入计数 unsigned char ReInputCont; //重新输入计数 unsigned char code initpassword[6]={0,0,0,0,0,0}; //=====================5ms延时============================== void Delay5Ms(void) { unsigned int TempCyc = 5552; while(TempCyc--); } //===================400ms延时============================== void Delay400Ms(void) { unsigned char TempCycA = 5; unsigned int TempCycB; while(TempCycA--) { TempCycB=7269; while(TempCycB--); } } //================================24C02====================================== void mDelay(uint t) //延时 { uchar i; while(t--) { for(i=0;i<125;i++) {;} } } void Nop(void) //空操作 { _nop_(); _nop_(); _nop_(); _nop_(); } /*起始条件*/ void Start(void) { Sda=1; Scl=1; Nop(); Sda=0; Nop(); } /*停止条件*/ void Stop(void) { Sda=0; Scl=1; Nop(); Sda=1; Nop(); } /*应答位*/ void Ack(void) { Sda=0; Nop(); Scl=1; Nop(); Scl=0; } /*反向应答位*/ void NoAck(void) { Sda=1; Nop(); Scl=1; Nop(); Scl=0; } /*发送数据子程序,Data为要求发送的数据*/ void Send(uchar Data) { uchar BitCounter=8; uchar temp; do { temp=Data; Scl=0; Nop(); if((temp&0x80)==0x80) Sda=1; else Sda=0; Scl=1; temp=Data<<1; Data=temp; BitCounter--; } while(BitCounter); Scl=0; } /*读一字节的数据,并返回该字节值*/ uchar Read(void) { uchar temp=0; uchar temp1=0; uchar BitCounter=8; Sda=1; do{ Scl=0; Nop(); Scl=1; Nop(); if(Sda) temp=temp|0x01; else temp=temp&0xfe; if(BitCounter-1) { temp1=temp<<1; temp=temp1; } BitCounter--; } while(BitCounter); return(temp); } void WrToROM(uchar Data[],uchar Address,uchar Num) { uchar i; uchar *PData; PData=Data; for(i=0;i Ack(); Send(Address+i); Ack(); Send(*(PData+i)); Ack(); Stop(); mDelay(20); } } void RdFromROM(uchar Data[],uchar Address,uchar Num) { uchar i; uchar *PData; PData=Data; for(i=0;i Send(Address+i); Ack(); Start(); Send(0xa1); Ack(); *(PData+i)=Read(); Scl=0; NoAck(); Stop(); } } //=======================================LCD1602=============================//#define yi 0x80 //LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80) #define er 0x80+0x40 //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40) //----------------延时函数,后面经常调用---------------------- void delay(uint xms)//延时函数,有参函数 { uint x,y; for(x=xms;x>0;x--) for(y=110;y>0;y--); } //--------------------------写指令--------------------------- write_1602com(uchar com)//****液晶写入指令函数**** { lcd1602_rs=0;//数据/指令选择置为指令 lcd1602_rw=0; //读写选择置为写 P0=com;//送入数据 delay(1); lcd1602_en=1;//拉高使能端,为制造有效的下降沿做准备 delay(1); lcd1602_en=0;//en由高变低,产生下降沿,液晶执行命令 } //-------------------------写数据----------------------------- write_1602dat(uchar dat)//***液晶写入数据函数**** { lcd1602_rs=1;//数据/指令选择置为数据 lcd1602_rw=0; //读写选择置为写 P0=dat;//送入数据 delay(1); lcd1602_en=1; //en置高电平,为制造下降沿做准备 delay(1); lcd1602_en=0; //en由高变低,产生下降沿,液晶执行命令 } //-------------------------初始化------------------------- void lcd_init(void) { write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据 write_1602com(0x0c);//开显示不显示光标 write_1602com(0x06);//整屏不移动,光标自动右移 write_1602com(0x01);//清显示 } //==============将按键值编码为数值========================= unsigned char coding(unsigned char m) { unsigned char k; switch(m) { case (0x18): k=1;break; case (0x28): k=2;break; case (0x48): k=3;break; case (0x88): k='A';break; case (0x14): k=4;break; case (0x24): k=5;break; case (0x44): k=6;break; case (0x84): k='B';break; case (0x12): k=7;break; case (0x22): k=8;break; case (0x42): k=9;break; case (0x82): k='C';break; case (0x11): k='*';break; case (0x21): k=0;break; case (0x41): k='#';break; case (0x81): k='D';break; } return(k); } //=====================按键检测并返回按键值=============================== unsigned char keynum(void) { unsigned char row,col,i; P1=0xf0; if((P1&0xf0)!=0xf0) { Delay5Ms(); Delay5Ms(); if((P1&0xf0)!=0xf0) { row=P1^0xf0; //确定行线 i=0; P1=a[i]; //精确定位 while(i<4) { if((P1&0xf0)!=0xf0) { col=~(P1&0xff); //确定列线 break; //已定位后提前退出 } else { i++; P1=a[i]; } } } else { return 0; } while((P1&0xf0)!=0xf0); return (row|col); //行线与列线组合后返回 } else return 0; //无键按下时返回0 } //=======================一声提示音,表示有效输入======================== void OneAlam(void) { ALAM=0; Delay5Ms(); ALAM=1; } //========================二声提示音,表示操作成功======================== void TwoAlam(void) { ALAM=0; Delay5Ms(); ALAM=1; Delay5Ms(); ALAM=0; Delay5Ms(); ALAM=1; } //========================三声提示音,表示错误======================== void ThreeAlam(void) { ALAM=0; Delay5Ms(); ALAM=1; Delay5Ms(); ALAM=0; Delay5Ms(); ALAM=1; Delay5Ms(); ALAM=0; Delay5Ms(); ALAM=1; } //=====================显示输入的N个数字,用H代替以便隐藏============================ void DisplayOne(void) { // DisplayOneChar(9+N,1,'*'); write_1602com(yi+5+N); write_1602dat('*'); } //=======================显示提示输入========================= void DisplayChar(void) { unsigned char i; if(pass==1) { //DisplayListChar(0,1,LockOpen); write_1602com(er); for(i=0;i<16;i++) { write_1602dat(LockOpen[i]); } } else { if(N==0) { //DisplayListChar(0,1,Error); write_1602com(er); for(i=0;i<16;i++) { write_1602dat(Error[i]); } } else { //DisplayListChar(0,1,start_line); write_1602com(er); for(i=0;i<16;i++) { write_1602dat(start_line[i]); } } } } void DisplayInput(void) { unsigned char i; if(CorrectCont==1) { //DisplayListChar(0,0,Input); write_1602com(er); for(i=0;i<16;i++) { write_1602dat(Input[i]); } } } //========================重置密码================================================== //================================================================================== void ResetPassword(void) { unsigned char i; unsigned char j; if(pass==0) { pass=0; DisplayChar(); ThreeAlam(); } else { if(ReInputEn==1) { if(N==6) { ReInputCont++; if(ReInputCont==2) { for(i=0;i<6;) { if(TempPassword[i]==InputData[i]) //将两次输入的新密码作对比 i++; else { //DisplayListChar(0,1,Error); write_1602com(er); for(j=0;j<16;j++) { write_1602dat(Error[j]); } ThreeAlam(); //错误提示 pass=0; ReInputEn=0; //关闭重置功能, ReInputCont=0; DisplayChar(); break; } } if(i==6) { //DisplayListChar(0,1,ResetOK); write_1602com(er); for(j=0;j<16;j++) { write_1602dat(ResetOK[j]); } TwoAlam(); //操作成功提示 WrToROM(TempPassword,0,6); //将新密码写入24C02存储 ReInputEn=0; } ReInputCont=0; CorrectCont=0; } else { OneAlam(); //DisplayListChar(0, 1, again); //显示再次输入一次 write_1602com(er); for(j=0;j<16;j++) { write_1602dat(again[j]); } for(i=0;i<6;i++) { TempPassword[i]=InputData[i]; //将第一次输入的数据暂存起来 } } N=0; //输入数据位数计数器清零 } } } } //=======================输入密码错误超过三过,报警并锁死键盘====================== void Alam_KeyUnable(void) { P1=0x00; { ALAM=~ALAM; Delay5Ms(); } } //=======================取消所有操作============================================ void Cancel(void) { unsigned char i; unsigned char j; //DisplayListChar(0, 1, start_line); write_1602com(er); for(j=0;j<16;j++) { write_1602dat(start_line[j]); } TwoAlam(); //提示音 for(i=0;i<6;i++) { InputData[i]=0; } KEY=1; //关闭锁 ALAM=1; //报警关 operation=0; //操作标志位清零 pass=0; //密码正确标志清零 ReInputEn=0; //重置输入充许标志清零 ErrorCont=0; //密码错误输入次数清零 CorrectCont=0; //密码正确输入次数清零 ReInputCont=0; //重置密码输入次数清零 open_led=1; s3_keydown=0; key_disable=0; N=0; //输入位数计数器清零 } //==========================确认键,并通过相应标志位执行相应功能 =============================== void Ensure(void) { unsigned char i,j; RdFromROM(CurrentPassword,0,6); //从24C02里读出存储密码 if(N==6) { if(ReInputEn==0) //重置密码功能未开启 { for(i=0;i<6;) { if(CurrentPassword[i]==InputData[i]) { i++; } else { ErrorCont++; if(ErrorCont==3) //错误输入计数达三次时,报警并锁定键盘 { write_1602com(er); for(i=0;i<16;i++) { write_1602dat(Error[i]); } do Alam_KeyUnable(); while(1); } else { TR0=1; //开启定时 key_disable=1; //锁定键盘 pass=0; break; } } } if(i==6) { CorrectCont++; if(CorrectCont==1) //正确输入计数,当只有一次正确输 入时,开锁, { //DisplayListChar(0,1,LockOpen); write_1602com(er); for(j=0;j<16;j++) { write_1602dat(LockOpen[j]); } TwoAlam(); //操作成功提示音 KEY=0; //开锁 pass=1; //置正确标志位 TR0=1; //开启定时 open_led=0; //开锁指示灯亮 for(j=0;j<6;j++) //将输入清除 { InputData[i]=0; } } else //当两次正确输入时,开启重置密码功能 { //DisplayListChar(0,1,SetNew); write_1602com(er); for(j=0;j<16;j++) { write_1602dat(SetNew[j]); } TwoAlam(); //操作成功提示 ReInputEn=1; //允许重置密码输入 CorrectCont=0; //正确计数器清零 } } else //=========================当第一次使用或忘记密码时可以用131420对其密码初始化============ { if((InputData[0]==1)&&(InputData[1]==3)&&(InputData[2]==1)&&(InputData[3]== 4)&&(InputData[4]==2)&&(InputData[5]==0)) { WrToROM(initpassword,0,6); 入24C02存储 //DisplayListChar(0,1,initword); 码 write_1602com(er); for(j=0;j<16;j++) { write_1602dat(initword[j]); } TwoAlam(); Delay400Ms(); TwoAlam(); N=0; } else { //DisplayListChar(0,1,Error); write_1602com(er); for(j=0;j<16;j++) { write_1602dat(Error[j]); } ThreeAlam(); 提示音 pass=0; } } } else 能时,而按下开锁键, { //DisplayListChar(0,1,Er_try); write_1602com(er); for(j=0;j<16;j++) { write_1602dat(Er_try[j]); } ThreeAlam(); } } //强制将初始密码写 //显示初始化密 //错误 //当已经开启重置密码功 else { //DisplayListChar(0,1,Error); write_1602com(er); for(j=0;j<16;j++) { write_1602dat(Error[j]); } ThreeAlam(); //错误提示音 pass=0; } N=0; //将输入数据计数器清零,为下一次输入作准备 operation=1; } //==============================主函数=============================== void main(void) { unsigned char KEY,NUM; unsigned char i,j; P1=0xFF; TMOD=0x11; TL0=0xB0; TH0=0x3C; EA=1; ET0=1; TR0=0; Delay400Ms(); //启动等待,等LCM讲入工作状态 lcd_init(); //LCD初始化 write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示 for(i=0;i<16;i++) { write_1602dat(name[i]);//向液晶屏写日历显示的固定符号部分 } write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示 for(i=0;i<16;i++) { write_1602dat(start_line[i]);//写显示时间固定符号,两个冒号 } write_1602com(er+9); //设置光标位置 write_1602com(0x0f); //设置光标为闪烁 Delay5Ms(); //延时片刻(可不要) N=0; 入位数 while(1) { if(key_disable==1) Alam_KeyUnable(); else ALAM=1; //关报警 KEY=keynum(); if(KEY!=0) { if(key_disable==1) { second=0; } else { NUM=coding(KEY); { switch(NUM) { case ('A'): ; case ('B'): ; case ('C'): ; case ('D'): ResetPassword(); 设置密码 case ('*'): Cancel(); 当前输入 case ('#'): Ensure(); 键, default: { //DisplayListChar(0,1,Input); write_1602com(er); for(i=0;i<16;i++) { write_1602dat(Input[i]); } operation=0; if(N<6) 入的密码少于6位时,接受输入并保存,大于6位时则无效。 { //初始化数据输 break; break; break; break; //重新break; //取消break; //确认 //当输 OneAlam(); 提示音 //DisplayOneChar(6+N,1,'*'); for(j=0;j<=N;j++) { write_1602com(er+6+j); write_1602dat('*'); //按键 } InputData[N]=NUM; N++; } else 数据位数大于6后,忽略输入 { N=6; break; } } } } } } } } //*********************************中断************************************** void time0_int(void) interrupt 1 { TL0=0xB0; TH0=0x3C; //TR0=1; countt0++; if(countt0==20) { countt0=0; second++; if(pass==1) { if(second==1) { open_led=1; //关指示灯 TR0=0; //关定时器 TL0=0xB0; 服务 //输入 函数 TH0=0x3C; second=0; } } else { } } } if(second==3) { TR0=0; second=0; key_disable=0; s3_keydown=0; TL0=0xB0; TH0=0x3C; } else TR0=1; 结论,致谢,参考文献,原理图放在程序前 毕业设计是学生即将完成学业的最后一次作业,它既是对所学知识的全面总结和综合应用,又是今后走向社会的实际操作应用铸就了一个良好开端,毕业设计是我对所学知识理论的检验与总结,此次毕业设计是一次非常难得的理论与实际相结合的机会,通过这次比较难完整的毕业设计,我摆脱了单纯的理论知识学习状态,和实际设计的结合锻炼了我的综合运用所学的专业基础知识,同时也提高我查阅文献资料、设计手册、设计规范以及电脑制图等其它专业能力水平,而且通过对整体的掌控,对局部的取舍,以及对细节的斟酌处理,都使我的能力得到了锻炼,经验得到了丰富,并且使我的意志和耐力都得到了不同的提升,这是我们希望看到的也正是我们进行毕业设计的目的所在。 在此次试验中,我通过查阅大量的有关资料,与同学交流经验和自学,并向老师请教等方式完成的, 岁月如梭,三年的大学时光即将结束,这个实验和论文是在电子教研室105所有老师的知道与鼓励下完成的,老师们渊博的学识、严谨的治学态度、精益求精的工作态度和诲人不倦的高尚师德都深深感染和激励着我。在三年时光里,老师们不仅在学习上照顾我,同时也在思想和生活上给与我无微不至的关怀。在此,谨向105所有老师致以诚挚的感谢。 我还要感谢的是09电气数控的所有同学,是他们让我的大学生活变得更加丰富多彩,他们给予了我生活和学习上的帮助。 因篇幅问题不能全部显示,请点此查看更多更全内容