12864电子密码锁.docx
《12864电子密码锁.docx》由会员分享,可在线阅读,更多相关《12864电子密码锁.docx(36页珍藏版)》请在冰豆网上搜索。
![12864电子密码锁.docx](https://file1.bdocx.com/fileroot1/2023-2/2/37d59815-bd62-47cd-b8e5-32211c9cb8bf/37d59815-bd62-47cd-b8e5-32211c9cb8bf1.gif)
12864电子密码锁
《电子密码锁》
制作人:
张家文(09光信息)
时间:
2011年12月2日
摘要
随着电子技术的发展,电子产品的智能化越来越受到推崇。
其中密码锁也随着老式的机械式控制发展到今天的智能化控制。
本文主要阐述了该密码锁各模块电路的结构与工作原理,软件程序的设计与硬件电路的设计制作。
并基于STC89C52单片机、24C02存储模块、12864液晶显示模块与开关锁模块等构成了电子密码锁,实现了液晶显示、密码存储与更改、系统自动报警等多种功能。
关键字:
STC89C5224C0212864继电器步进电机
系统整体设计
一设计要求
1、能够实现密码开关锁功能。
2、能更改原密码。
3、系统有报警功能。
4、24C02能存储密码。
5、采用12864液晶显示。
二系统硬件设计方案
设计的目的是开发一种功能多,电路简单,性能稳定可靠的电子密码锁,该密码锁系统通过STC89C52系列单片机对各个模块电路进行控制,并对输入信号进行分析、运算、处理,从而控制继电器开锁与12864准确的显示。
该系统主要分7大模块:
微处理模块、存储模块、信号输入模块、电源模块、继电器模块、报警模块、显示模块,如图所示。
信号输入模块:
利用矩阵键盘按键电平的变化实现密码输入和密码更改。
系统结构框图
三微处理模块
1主要元件介绍
STC89C52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
使用宏晶公司公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。
片上Flash允许程序存储器在系统可编程,亦适于常规编程器。
在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
STC89C52具有以下标准功能:
8k字节Flash,256字节RAM,32位I/O口线,看门狗定时器,2个数据指针,三个16位定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。
另外,STC89C52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
如图所示。
2微处理模块电路
单片机系统由STC89C52芯片、时钟电路和复位电路三部分组成,主要是控制和处理各模块电路的数据输入、数据输出、显示、报警等,如图所示。
微处理模块电路
3存储模块
AT24C02是一个I2C总线接口E2PROM存储器,用于存储电子密码锁的密码数据。
主要元件介绍
AT24C02是美国ATEML公司生产的低功耗COMS型,I2C总线接口的E2PROM存储器,其内含256x8为存储空间,具有工作电压宽(2.5V~5.5V)、擦写次数多(大于1000次)、写入速度快(小于10mS)、抗干扰能力强、数据不易丢失、体积小等特点。
采用了I2C总线进行数据读写的串行器件,占用很少的资源和I/O线,而且支持在线编程,实时存取数据十分方便,如图所示。
24C02引脚排列图
24c08管脚功能:
管脚描述:
SCL:
串口时钟24c08串口时钟输入管脚用于产生机器件所有数据发送或接收的时钟,这是一个输入管脚。
SDA:
串口数据地址
24C08双向串行数据地址管脚用于器件所有数据的发送或接收,SDA是一个开路输出管脚,可与其他开路输出或集电极开路输出进行或(wire-OR)。
A0、A1、A2、A3:
器件地址输入端
这些输入脚用于多个器件级联时设置器件地址,当这些脚悬空时默认值为0,(24C01除外)
使用24C08时最多只可以连接2个器件,所有地址管脚A0、A1、A3都未使用,管脚可以连接到VSS或悬空,如果只用到一个24C08A2管脚可以连接到VSS或悬空。
WP:
写保护
如果WP管脚连接到VCC所有内容都被写保护(只能读取)。
当WP连接到VSS或被悬空,允许器件进行正常的读/写操作。
时序图
II2C总线协议定义:
(1)只有在总线空闲时候才允许启动数据传送。
(2)在数据传送过程中,当时钟线为高电平是,数据线必须保持稳定状态,不允许有跳变。
时钟线为高电平时,数据线的任意电平变化将被看作总显的起始或停止信号。
起始信号:
时钟线保持高电平期间,数据线电平从高到底的跳变作为IIC总线的起始信号。
停止信号:
时钟线保持高电平期间,数据线电平从低电平到高电平的跳变作为IIC总线的停止信号。
24C02时序图
4存储模块电路
图中上拉电阻的作用是减少AT24C02的静态功耗,由于AT24C02的数据线和地址线是复用的,采用串口的方式传送数据,所以只用两根线SCL(移位脉冲)和SDA(数据/地址)与单片机传送数。
每当成功修改一次密码,系统就自动调用存储程序,将新密码保存在芯片内;当系统需要进行密码识别时,通过程序读取存储器中的密码值存入缓冲区,与所输入密码进行比较,完成密码锁的开锁控制,如图所示。
AT24C02模块模块电路
5键盘输入模块
键盘可以分为独立连接式和行列式(矩阵式)两类。
根据设计要求,本电路设计采用4×4行列式键盘,同时也能减少键盘与单片机接口时所占用的I/O线的数目。
矩阵式键盘又叫行列式键盘。
用I/O口线组成行列结构,按键设置在行列的交叉点上。
本电路采用4条行线和4条列线,即可组成具有4×4个按键的键盘。
其电路图如下图2.4所示。
对键的识别通常用逐行扫描查询法。
首先判别键盘中有无按键按下,由单片机I/O口向键盘送(输出)全扫描字,然后读入(输入)列线状态来判断。
方法是:
向行线输出全扫描字00H,把全部行线置为低电平,然后将列线的电平状态读入累加器A中。
如果有键按下,总会有一根列线电平拉至低电平,从而使列输入不全为1。
键盘中哪一个键按下,是由行线逐行置低电平后,检查列输入状态实现的,其方法是:
依次给行线送低电平,然后查所有列线状态,如果全为1,则所按下的键不在此行,如果不全为1,则所按下的键必在此行,而且是在与零电平列线相交的交点上的那个键,矩阵键盘如图所示。
矩阵键盘
四电源模块
给整个电路模块提供所需的能量,使电路能够正常工作。
我们采用性能稳定可靠、价格低廉的LM7805系列稳压块如图所示,由于它内部有电流的限制以及过热保护和安全工作区的保护使得它不会轻易损坏,电源模块如图所示。
7805引脚排列图
电源模块模块电路
五控制开关锁模块
通过ULN2003来控制步进电机和继电器来控制开关锁,ULN2003内部还集成了一个消线圈反电动势的二极管,可用来驱动继电器。
它是双列16脚封装,NPN晶体管矩阵,最大驱动电压=50V,电流=500mA,输入电压=5V,适用于TTLCOMS,由达林顿管组成驱动电路。
ULN是集成达林顿管IC,内部还集成了一个消线圈反电动势的二极管,它的输出端允许通过电流为200mA,饱和压降VCE约1V左右,耐压BVCEO约为36V。
用户输出口的外接负载可根据以上参数估算。
采用集电极开路输出,输出电流大,故可直接驱动继电器或固体继电器,也可直接驱动低压灯泡。
通常单片机驱动ULN2003时,上拉2K的电阻较为合适,同时,COM引脚应该悬空或接电源。
ULN2003是一个非门电路,包含7个单元,单独每个单元驱动电流最大可达350mA,9脚可以悬空。
比如1脚输入,16脚输出,你的负载接在VCC与16脚之间,不用9脚。
ULN2003是大电流驱动阵列,多用于单片机、智能仪表、PLC、数字量输出卡等控制电路中。
可直接驱动继电器等负载。
输入5VTTL电平,输出可达500mA/50V。
ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。
该电路的特点如下:
ULN2003的每一对达林顿都串联一个2.7K的基极电阻,在5V的工作电压下它能与TTL和CMOS电路直接相连,可以直接处理原先需要标准逻辑缓冲器。
六报警模块
报警部分由蜂鸣器发声装置及ULN2003组成,高电平不发声,当输入三次密码错误时,输出低电平通过驱动ULN2003来控制蜂鸣器发出声音。
七显示模块
本系统采用LCD12864液晶显示,用于直观地提示用户输入开锁密码、密码信息的正误提示、开锁信息的显示等,显示整个电子密码锁的工作状态,如图2.12所示。
图12864液晶显示模块电路
参考文献
[1]王文海,彭可,周欢喜,单片机应用与实践项目化教程.北京化学工业出版社。
[2]郭天祥,新概念51单片机C语言教程—入门、提高、开发、扩展全攻略.北京:
电子工业出版社。
[3]竞赛组委会(汪学刚),AD大学生创新设计竞赛优秀论文选编,电子工业出版社。
[4]张毅刚,彭喜元,姜守达,乔立岩,新编MCS-51单片机应用设计第三版,哈尔滨工业大学出版社。
C语言程序
/*-----------------------------------------------------------------------
电子密码锁程序
----------------------------------------------------------------------**/
#include
#include
//#include
//#include
//#include<24c02.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineOP_READ0xa1
#defineOP_WRITE0xa0
#defineMAX_ADDR0xff
sbitrs=P3^0;
sbitrw=P3^1;
sbiten=P3^5;
sbitpsb=P2^3;
sbitret=P2^5;
sbitSDA=P3^4;
sbitSCL=P3^3;
ucharcommand,data0,data1,count;
ucharcodedis_code[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x08,0x39};
voidstart();
voidstop();
ucharshin();
bitshout(ucharwrite_data);
ucharread_random(ucharrandom_addr);
voidwrite_byte(ucharaddr,ucharwrite_data);
voidfill_byte(ucharfill_data);
voiddelayms(ucharms);
voidclear_lcd();
voiddelay(uintm);
voidcheckbusy();
voidwritecommand(ucharcommand);
voidwritedata(uchardate);
voidlcdset(void);
voiddisplay(uchary,ucharx,uchar*p);
voiddisplayNumber(uchary,ucharx,ucharnumber);
voidcursor(uchary,ucharx);
voidconvert(ucharyy);
ucharkey_scan(void);
intv;//保存键子字节
inti,j;//循环变量
inttt;//定时次数
interror_time=0;//保存错误次数字节
intopen_bz;//密码锁正确开锁标志
intclose_bz=1;
intsuper_bz=0;//超级密码启动标志
intkey_time=0;//存下按下的密码个数
intchang_bz=0;//是否修改过密码的标志
intover_bz=0;//输入密码错误超过三次的标志
intkey_sure=0;//确认键的标志
inttable_first[6];//从24c20中读取密码后暂存
inttable_chang[6];//输入密码保存区
intjm_numb=0;//界面标志
intyes_bz=0;//开锁标志
intno_bz=0;//密码错误标志
intnumb_able=0;//密码输入允许标志
intnumb_able2=1;//只12键允许输入标志
sbitp32=P3^2;//蜂鸣器接在p3.2
//蜂鸣器函数//
spark(uchari)
{
p32=0;
delay(50000*i);
p32=1;
}
//比较密码函数
bj_numb(void)
{
for(j=0;j<6;j++)
{
if(table_first[j]==table_chang[j])
open_bz=1;
else
close_bz=0;//只要有一位不等close_bz=0
}
open_bz=close_bz&open_bz;
close_bz=1;//为下次比较做准备
return(open_bz);
}
//保存超级密码函数
chaoji_numb()
{
write_byte(0x20,2);
write_byte(0x21,0);
write_byte(0x22,0);
write_byte(0x23,8);
write_byte(0x24,0);
write_byte(0x25,9);
}
//保存原始密码函数
yuansi_numb()
{
for(j=0;j<6;j++)
{
write_byte(j,8);
}
}
//只允许输入非数字键或1,2键
fszj(void)
{
if(!
numb_able2)
{
if(v==0x11||v==0x81||v==0x12||v==0x22||v==0x42||v==0x82||v==0x14||v==0x24||v==0x44||v==0x84||v==0x18||v==0x28||v==0x48||v==0x88)
{
v=0x88;
}
else
if(v==0x11||v==0x21||v==0x41||v==0x81||v==0x12||v==0x22||v==0x42||v==0x82||v==0x14||v==0x24)
{
v=0x88;
};
return(v);
}
}
//主函数
voidmain()
{
chaoji_numb();
if(!
read_random(30))
{
for(j=0;j<6;j++)
{
write_byte(j,8);
}
}
lcdset();
display(2,3,"贵州民族学院");
while
(1)
{
while(!
over_bz)//输入密码错误三次锁上键盘
{
v=key_scan();
if(!
numb_able)
{
fszj();
}
if(v==0x11||v==0x21||v==0x81||v==0x12||v==0x22||v==0x42||v==0x82||v==0x14||v==0x24||v==0x44||v==0x84||v==0x18||v==0x28||v==0x48||v==0x88)
{
switch(v)
{
case0x11:
//0键
if(key_time<6)
{
table_chang[key_time++]=0;
}
display(2,key_time,"*");
spark
(1);
break;
case0x21:
//1键
if(jm_numb==1)//在第一界面选择输入用户密码
{
spark
(1);
jm_numb=2;
key_sure=1;
}
if(jm_numb==4)//选择修改密码
{
spark
(1);
key_time=0;
jm_numb=5;
key_sure=1;
}
elseif(jm_numb==6)//选择返回
{
spark
(1);
key_time=0;
jm_numb=1;
key_sure=1;
}
//2键
else
{
if(key_time<6)
{
table_chang[key_time++]=2;
}
spark
(1);
display(2,key_time,"*");
}
break;
case0x41:
//在第一界面选择输入超级密码
if(jm_numb==1)
{
spark
(1);
jm_numb=3;
key_sure=1;
super_bz=0x20;
}
if(jm_numb==4)//在第四界面时选择进入
{
spark
(1);
key_sure=1;
jm_numb=7;
}
if(jm_numb==6)//在第六界面时选择进入
{
spark
(1);
key_sure=1;
jm_numb=7;
}
else
{
if(key_time<6)
{
table_chang[key_time++]=1;
}
spark
(1);
display(2,key_time,"*");
}
break;
case0x81:
//3键
if(key_time<6)
{
table_chang[key_time++]=3;
}
spark
(1);
display(2,key_time,"*");
break;
case0x12:
//4键
if(key_time<6)
{
table_chang[key_time++]=4;
}
spark
(1);
display(2,key_time,"*");
break;
case0x22:
//5键
if(key_time<6)
{
table_chang[key_time++]=5;
}
spark
(1);
display(2,key_time,"*");
break;
case0x42:
//6键
if(key_time<6)
{
table_chang[key_time++]=6;
}
spark
(1);
display(2,key_time,"*");
break;
case0x82:
//7键
if(key_time<6)
{
table_chang[key_time++]=7;
}
spark
(1);
display(2,key_time,"*");
break;
case0x14:
//8键
if(key_time<6)
{
table_chang[key_time++]=8;
}
spark
(1);
display(2,key_time,"*");
break;
case0x24:
//9键
delay(5000);
if(key_time<6)
{
table_chang[key_time++]=9;
}
spark
(1);
display(2,key_time,"*");
break;
case0x44:
//确认键
key_time=0;
key_sure=1;
jm_numb++;
if(jm_numb>7)
{
jm_numb=4;
}
spark
(1);
break;
case0x84:
//返回键
jm_numb--;
if(jm_numb<0)
{
jm_numb=0;
}
key_sure=1;
break;
case0x18:
//总推出键
jm_numb=0;
key_sure=1;
break;
case0x28:
spark
(1);
display(2,key_time,"");
key_time--;
break;
case0x48:
//无效键
spark
(1);
break;
case0x88:
//无效键
spark
(1);
break;
default:
spark
(1);
break;
}
}
if(key_sure==1)
{
key_sure=0;
switch(jm_numb)
{
case0:
lcdset();
display(2,2,"贵州民族学院");//显示界面0
numb_able2=1;//只能输入功能键
numb_able=0;
break;
case1:
lcdset();//显示界面1
display(1,1,"我的设计:
密码锁");
display(2,1,"1.输入用户密码");
display(3,1,"2.输入超级密码");
numb_able=0;//只能输入12键
numb_able2=0;
break;
case2:
lcdset();//显示界面2
display(1,1,"请输入用户密码:
");
key_time=0;
jm_numb++;
numb_able=1;
break;
case3:
lcdset();//显示界面3
display(1,1,"请输入超级密码:
");
key_time=0;
numb_able=1;
break;
case4:
for(j=0;j<6;j++)
{
table_first[j