1、 前言 随着电子技术的发展,具有防盗报警等功能的电子密码锁代替密码量少、安全性差的机械式密码锁已是必然趋势。电子密码锁与普通机械锁相比,具有许多独特的优点:保密性好,防盗性强,可以不用钥匙,记住密码即可开锁等。目前使用的电子密码锁大部分是基于单片机技术,以单片机为主要器件,其编码器与解码器的生成为软件方式。 下面就是现在主流电子密码锁:目前常见的遥控式电子防盗锁主要有光遥控和无线电遥控两类。键盘式电子密码锁从目前的技术水平和市场认可程度看,使用最为广泛的是键盘式电子密码锁,该产品主要应用于保险箱、保险柜和金库,还有一部分应用于保管
2、箱和运钞车。卡式电子防盗锁使用各种“卡”作为钥匙的电子防盗锁是当前最为活跃的产品,无论卡的种类如何多种多样,按照输入卡的操作方式,都可分为接触式卡和非接 触式卡两大类。生物特征防盗锁人的某些与生俱来的个性特征(如手、眼睛、声音的 特征)几乎不可重复,作为“钥匙”就是唯一的(除非被逼迫或伤害)。因此,利用生物特征做密码的电子防盗锁,也特别适合金融业注重“验明正身”的行业特点。 人们生活水平的提高和安全意识的加强,对安全的要求也就越来越高。锁自 古以来就是把守护门的铁将军,人们对它要求甚高,既要安全可靠的防盗,又要使用方便,这也是制锁者长期以来研制的主题。随着电子技术的发展,各类电子产品应运而生
3、电子密码锁就是其中之一。据有关资料介绍,电子密码锁的研究从20世纪30年代就开始了,在一些特殊场所早就有所应用。这种锁是通过键盘输入一组密码完成开锁过程。研究这种锁的初衷,就是为提高锁的安全性。由于电子锁的密钥量(密码 量)极大,可以与机械锁配合使用,并且可以避免因钥匙被仿制而留下安全隐患。电子锁只需记住一组密码,无需携带金属钥匙,免除了人们携带金属钥匙的烦恼,而被越来越多的人所欣赏。电子锁的种类繁多,例如数码锁,指纹锁,磁卡锁,IC 卡锁,生物锁等。但较实用的还是按键式电子密码锁。20世纪80年代后,随着电子锁专用集成电路的出现,电子锁的体积缩小,可靠性提高,成本较高,是适合使用在安全性要
4、求较高的场合,且需要有电源提供能量,使用还局限在一定范围,难以普及,所以对它的研究一直没有明显进展。 目前,在西方发达国家,电子密码锁技术相对先进,种类齐全,电子密码锁已被 广泛应用于智能门禁系统中,通过多种更加安全,更加可靠的技术实现大门的管理。 在我国电子锁整体水平尚处于国际上70年代左右,电子密码锁的成本还很高,市场上仍以按键电子锁为主,按键式和卡片钥匙式电子锁已引进国际先进水平,现国内有几个厂生产供应市场。但国内自行研制开发的电子锁,其市场结构尚未形成,应用还不广泛。国内的不少企业也引进了世界上先进的技术,发展前景非常可观。希望通过不断的努力,使电子密码锁在我国也能得到广泛应用。
5、 一、 作品功能: 1、设置6位密码,密码通过键盘输入,若密码正确,则将锁打开。 2、密码可以由用户自己修改设定(只支持6位密码),锁打开后才能修改密码。修改密码之前必须再次输入密码,在输入新密码时候需要二次确认,以防止误操作。 3、报警、锁定键盘功能。密码输入错误显示器会出现错误提示,若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘。 4、AT24C02保存密码,支持复位保存,掉电保存功能。 二、按键说明 按键定义图 如图示:采用4X4键盘输入,键盘对应名称如下: 1 2 3 A 4 5 6 B 7 8 9 C
6、 * 0 # D 其中, 【0—9】为数字键,用于输入相应的密码, 【*】号键为取消当前操作 【#】号键为确认 【D】键为修改密码 其它键无功能及定义 三、操作说明: 密码锁初始密码为:000000. 1、 开锁:插上电源后,程序自动调入初始密码,此时依次输 入:000000,然后按【#】(确认)键,此时锁会打开,可以看到显示open,密码锁打开。 2、 退出并关锁:按下【*】(取消)键,此时锁关闭,所有输入清除。 3、 修改密码:在开锁状态下,再次输入正确的密码并按下【#】(确认)键,此 4、 5、 6、 时
7、听到两声提示,输入新的六位密码并按【D】(重设)键,再重复输入一次新密码并按【D】,会听到两声提示音,表示重设密码成功,内部保存新密码并存储到AT24C02。(如两次输入的新密码不一样,则重设密码失败)。 7、 报警并锁定键盘:当输入密码错误后,报警并锁定键盘3秒,如3秒内又有按键,3秒再启动。 8、 当重置新密码时,新密码会保存于AT24C02存储器里。 四、框图及流程图 1、系统结构框图 AT89S52 显示模块 键盘输入模块 报警电路 复位电路
8、开锁电路 密码存储模块 2、主程序设计流程图 初始化 修改 开锁 密码正确 输入旧密码 N 原密码相同 Y 开锁 出错报警 N N Y 设新密码 返回 3、键功能程序流程图。 键功能程序 键值=0~9? 键值=开锁? 键值=确认? 键值=设置? 返回 密码输入程序 确认程
9、序 设置程序 开锁程序 Y N Y N Y N Y N 4、开锁程序流程图 LCD初始化 按开锁键 输入密码 确认程序 开锁 N 输入密码正确? 报警程序 开锁成功 返回 Y 5.电子密码锁原理图 程序(c语言) #
10、include
11、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,0x
12、FD,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 code
13、pass[] = {" 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[]
14、 = {"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;
15、 //密码输入位数记数 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; whil
16、e(TempCyc--); } //===================400ms延时============================== void Delay400Ms(void) { unsigned char TempCycA = 5; unsigned int TempCycB; while(TempCycA--) { TempCycB=7269; while(TempCycB--); } } //================================24C02===============================
17、 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 Sto
18、p(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 BitCoun
19、ter=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(voi
20、d) { 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
21、uchar Data[],uchar Address,uchar Num)
{
uchar i;
uchar *PData;
PData=Data;
for(i=0;i 22、{
uchar i;
uchar *PData;
PData=Data;
for(i=0;i 23、//#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--);
}
//------- 24、写指令---------------------------
write_1602com(uchar com)//****液晶写入指令函数****
{
lcd1602_rs=0;//数据/指令选择置为指令
lcd1602_rw=0; //读写选择置为写
P0=com;//送入数据
delay(1);
lcd1602_en=1;//拉高使能端,为制造有效的下降沿做准备
delay(1);
lcd1602_en=0;//en由高变低,产生下降沿,液晶执行命令
}
//-------------------------写数 25、据-----------------------------
write_1602dat(uchar dat)//***液晶写入数据函数****
{
lcd1602_rs=1;//数据/指令选择置为数据
lcd1602_rw=0; //读写选择置为写
P0=dat;//送入数据
delay(1);
lcd1602_en=1; //en置高电平,为制造下降沿做准备
delay(1);
lcd1602_en=0; //en由高变低,产生下降沿,液晶执行命令
}
//-------------------------初始化------------------- 26、
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 27、
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 28、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, 29、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; 30、 //已定位后提前退出
}
else
{
i++;
P1=a[i];
}
}
}
else
{
return 0;
}
while((P1&0xf0)!=0xf0);
return (row|col); //行线与列线组合后返回
}
else return 0; //无键按下时返回0
}
//=======================一声提示音,表示有效输入====== 31、
void OneAlam(void)
{
ALAM=0;
Delay5Ms();
ALAM=1;
}
//========================二声提示音,表示操作成功========================
void TwoAlam(void)
{
ALAM=0;
Delay5Ms();
ALAM=1;
Delay5Ms();
ALAM=0;
Delay5Ms();
ALAM=1;
}
//========================三声提示音, 32、表示错误========================
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)
{
33、// 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_1602 34、dat(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_ 35、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]);
}
}
}
//========================重置密码============================= 36、
//==================================================================================
void ResetPassword(void)
{
unsigned char i;
unsigned char j;
if(pass==0)
{
pass=0;
DisplayChar();
ThreeAlam();
}
else
{
if(ReInputEn==1)
{
if(N==6)
{ 37、
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(Er 38、ror[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++)
{
39、
write_1602dat(ResetOK[j]);
}
TwoAlam(); //操作成功提示
WrToROM(TempPassword,0,6); //将新密码写入24C02存储
ReInputEn=0;
}
ReInputCont=0;
CorrectCont=0;
}
else
{
OneAlam();
//DisplayListChar(0, 1, again); //显示再次输入一次
w 40、rite_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(again[j]);
}
for(i=0;i<6;i++)
{
TempPassword[i]=InputData[i]; //将第一次输入的数据暂存起来
}
}
N=0; //输入数据位数计数器清零
}
}
}
}
//=======================输入密码错误超过三过,报警并锁死 41、键盘======================
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 42、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 43、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里读出存储 44、密码
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 45、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(Corr 46、ectCont==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; //开启定时
47、 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]);
}
Two 48、Alam(); //操作成功提示
ReInputEn=1; //允许重置密码输入
CorrectCont=0; //正确计数器清零
}
}
else //=========================当第一次使用或忘记密码时可以用131420对其密码初始化============
{
if((InputData[0]==1)&&(InputData[1]==3)&&(InputData[2]==1)&&(InputData[3]==4)&&(InputData[4]== 49、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; 50、
}
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






