基于51单片机的门禁系统之电子密码锁.docx
《基于51单片机的门禁系统之电子密码锁.docx》由会员分享,可在线阅读,更多相关《基于51单片机的门禁系统之电子密码锁.docx(71页珍藏版)》请在冰豆网上搜索。
基于51单片机的门禁系统之电子密码锁
在日常的生活和工作中,住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。
若使用传统的机械式钥匙开锁,人们常需携带多把钥匙,使用极不方便,且钥匙丢失后安全性即大打折扣。
随着科学技术的不断发展,人们对日常生活中的安全保险器件的要求越来越高。
为满足人们对锁的使用要求,增加其安全性,用密码代替钥匙的密码锁应运而生。
密码锁具有安全性高、成本低、功耗低、易操作等优点。
在安全技术防范领域,具有防盗报警功能的电子密码锁逐渐代替传统的机械式密码锁,克服了机械式密码锁密码量少、安全性能差的缺点,使密码锁无论在技术上还是在性能上都大大提高一步。
随着大规模集成电路技术的发展,特别是单片机的问世,出现了带微处理器的智能密码锁,它除具有电子密码锁的功能外,还引入了智能化管理、专家分析系统等功能,从而使密码锁具有很高的安全性、可靠性,应用日益广泛。
本文中电子密码锁将实现以下功能:
1.通过矩阵键盘来输入密码,如果密码正确则门打开,如果密码不正确提示剩余输入次数,次数为0则锁定2分钟后才能再输入。
2.门打开后等待关门信号(本文中用P3^4接按键模拟),待收到信号后表示门已关闭。
3.可以通过按键来修改密码,修改前需要验证原密码。
4.支持掉电保存功能。
5.为了防止密码被窃取,本文中的密码采用ASCII存放,并且存放地址无规则(可根据自己需求修改)。
特别说明:
1.由于代码长度过大,请大家用大内存的单片机测试(本文中采用STC90C58RD+12T单片机);
2.CPU时钟请用11.0592MHz(液晶画点部分用22.1184MHz测试时失败!
估计是速度过高);
3.本文中的EEprom采用的是STC单片机内部EEProm,如果大家要用24Cxx系列或其它存储器请自行修改代码;
4.由于测试最小系统接口限制,请大家测试时自行修改接口定义(液晶接口、矩阵接口、独立按键接口);
5.本文中开、关门控制接口程序中没有引出,只用到“Door”这个逻辑型变量,大家在做实物时请自行定义一个接口,并赋该变量值即可!
6.第一次使用时(用STC自带EEProm)请先写入初始密码(将主程序屏蔽的那7行代码解除屏蔽,写入后再屏蔽掉即可!
),程序中的初始密码为“888888”;
7.本文中采用的是12864图形液晶(不带字库的),请大家务必注意
8. 本文只简单的实现的密码锁的基础功能,需要更高级功能的朋友请自行添加!
9.由于个人能力有限,程序中难免存在BUG, 遇到BUG请大家及时反馈以便在后期加以修正。
最后祝大家身体健康,万事如意!
★后附源代码
外观图:
欢迎界面:
工作界面:
门开启提示:
门关闭提示:
密码输入错误提示:
密码输入错误提示:
系统锁死提示:
系统锁死提示:
修改密码界面:
原密码校验失败:
输入新密码界面:
再次输入新密码界面:
密码修改成功界面:
外观:
★====================主程序====================
#include"reg52.h"
#include"intrins.h"
#include"Variable.h"
#include"EEProm.h"
#include"Function.h"
#include"L12864.h"
#include"L12864_Windows.h"
#include"Key_Alone.h"
#include"Key_44.h"
#include"math.h"
voidmain(void)
{
//IapEraseSector(0x8000);//擦除第一个扇区
//IapProgramunsigned(1,0x38);//写数据
//IapProgramunsigned(9,0x38);//写数据
//IapProgramunsigned(6,0x38);//写数据
//IapProgramunsigned(8,0x38);//写数据
//IapProgramunsigned(0,0x38);//写数据
//IapProgramunsigned(3,0x38);//写数据
ReadPassWord();//读出密码到本地
InitTimer0();//定时器中断初始化
L12864_init();
L12864_Windows_Init();//载入初始化界面
L12864_Delay1S();
L12864_Windows_Input(0);//载入密码输入0次界面
MODE=1;//置模式一输入开门密码模式
while
(1)
{
Key_44_KeySan();
Key_44_KeyHandle();
}
}
voidTimer0Interrupt(void)interrupt1
{
TH0=0x0B8;
TL0=0x00;
ms++;
if(ms==50)
{
ms=0;
s--;
if(s==-1)
{
s=59;
fen--;
}
if(fen>=2)
{
Unit=0;
}
else
{
Unit=1;
}
}
}
★===================主程序结束===================
★=================== 全局变量 ===================
#defineCount3
#defineErrMin2
unsignedcharjianzhi;
unsignedcharMODE;//模式0=不能输入1=输入开门密码2=修改密码3=输入新密码14=输入新密码25=门已经开启6=等待时间
unsignedcharInPutCount=0;//输入计次
unsignedcharErrCount=Count;//输入错误计次
unsignedcharErrWait=ErrMin;//错误等待时间
bitKeyAvailable;//key按键可用
bitDoor=1;//门状态0=开1=关
bitNextCycle_MODE3,NextCycle_MODE4;
unsignedcharInPutPassWord[6];
unsignedcharInPutPassWordNew1[6];
unsignedcharInPutPassWordNew2[6];
unsignedcharPassWord[6]={0,0,0,0,0,0};
unsignedcharms,NewS,Newfen,s=59,fen=ErrMin;
bitUnit;//倒计时单位0为分钟1为秒
★==================全局变量结束===================
★================== EEProm代码===================
sfrIAP_DATA = 0xE2; //Flash数据注册
sfrIAP_ADDRH = 0xE3; //Flash地址高位
sfrIAP_ADDRL = 0xE4; //Flash地址低位
sfrIAP_CMD = 0xE5; //Flash命令注册
sfrIAP_TRIG = 0xE6; //Flash命令触发
sfrIAP_CONTR = 0xE7; //Flash控制方式注册
#defineCMD_IDLE 0 //Stand-By
#defineCMD_READ 1 //字节读取
#defineCMD_PROGRAM2 //字节编程
#defineCMD_ERASE 3 //扇区擦除
#defineENABLE_IAP 0x81 //ifSYSCLK<20MHz
#defineIAP_ADDRESS0x08000//注意地址必须加上这个8000 不然就是操作的单片机内存
voidIapIdle(void)
{
IAP_CONTR=0;
IAP_CMD=0;
IAP_TRIG=0;
IAP_ADDRH=0x80;
IAP_ADDRL=0;
}
unsignedcharIapReadunsigned(unsignedintV)
{
unsignedchardat;
unsignedintaddr;
addr=V+IAP_ADDRESS;
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_READ;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x46;
IAP_TRIG=0xb9;
_nop_();
dat=IAP_DATA;
IapIdle();
returndat;
}
voidIapProgramunsigned(unsignedintV,unsignedchardat)
{
unsignedintaddr;
addr=V+IAP_ADDRESS;
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_PROGRAM;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_DATA=dat;
IAP_TRIG=0x46;
IAP_TRIG=0xb9;
_nop_();
IapIdle();
}
voidIapEraseSector(unsignedintaddr)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_ERASE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x46;
IAP_TRIG=0xb9;
_nop_();
IapIdle();
}
★================EEProm代码结束===================
★=================Function代码====================
voidInitTimer0(void)//20ms中断初始化
{
TMOD=0x01;
TH0=0x0B8;
TL0=0x00;
EA=1;
ET0=1;
TR0=0;
}
bitPassWordCheck(void)
{
unsignedchari;
bitReturnV;
ReturnV=1;
for(i=0;i<6;i++)
{
if(InPutPassWord[i]!
=PassWord[i])
{
ReturnV=0;
}
}
returnReturnV;
}
bitPassWordCheckNew(void)
{
unsignedchari;
bitReturnV;
ReturnV=1;
for(i=0;i<6;i++)
{
if(InPutPassWordNew1[i]!
=InPutPassWordNew2[i])
{
ReturnV=0;
}
}
returnReturnV;
}
voidClrarPassBuf(void)
{unsignedchari;
for(i=0;i<6;i++)
{
InPutPassWord[i]=0;
InPutPassWordNew1[i]=0;
InPutPassWordNew2[i]=0;
}
}
voidReadPassWord(void)
{
PassWord[0]=IapReadunsigned
(1);
PassWord[1]=IapReadunsigned(9);
PassWord[2]=IapReadunsigned(6);
PassWord[3]=IapReadunsigned(8);
PassWord[4]=IapReadunsigned(0);
PassWord[5]=IapReadunsigned(3);
}
voidWriteNewPassWord(void)
{
unsignedchari;
IapEraseSector(0x8000);//擦除第一个扇区不擦除写不了
IapProgramunsigned(1,InPutPassWordNew2[0]);
IapProgramunsigned(9,InPutPassWordNew2[1]);
IapProgramunsigned(6,InPutPassWordNew2[2]);
IapProgramunsigned(8,InPutPassWordNew2[3]);
IapProgramunsigned(0,InPutPassWordNew2[4]);
IapProgramunsigned(3,InPutPassWordNew2[5]);
for(i=0;i<6;i++)
{
PassWord[i]=InPutPassWordNew2[i];
}
}
★===============Function代码结束===================
★================12864底层代码====================
/*◆------L12864驱动底层函数------◆
STC90C58RD+
11.0592MHz 画点只能在11.0592MHz下运行
改变晶振请重写延时函数
*/
#include"L12864_CODE.h"
#defineL12864_PortP0
#defineL12864_DataP2
#defineL12864_comm0//常量写命令
#defineL12864_data1//常量写数据
#defineL12864_Screen_L1//常量左屏
#defineL12864_Screen_R2//常量右屏
#defineL12864_Screen_LR3//常量左右屏
#defineL12864_Screen_NULL0//常量无
/******************************************************************
-说明:
端口定义
-备注:
无
******************************************************************/
sbitL12864_RST=L12864_Port^3; //复位端,低电平有效。
sbitL12864_CS2=L12864_Port^2;//右屏片选(高电平有效)
sbitL12864_CS1=L12864_Port^4;//左屏片选(高电平有效)
sbitL12864_E =L12864_Port^5;//读写使能,高电平有效,下降沿锁定数据。
sbitL12864_RW =L12864_Port^6;//读/写选择:
高电平为读数据,低电平为写数据。
sbitL12864_RS =L12864_Port^7;//数据/指令选择:
高电平为数据,低电平为指令。
/******************************************************************
-功能描述:
延时子程序
-入口参数:
长整数型
-参数值:
0-65535
-返回说明:
无
-备 注:
无
******************************************************************/
voidL12864_Delayus(unsignedintV)
{
while(V--);
}
voidL12864_Delay50us(void)
{
unsignedchara,b;
for(b=1;b>0;b--)
for(a=20;a>0;a--);
}
voidL12864_Delay1S(void)
{
unsignedchara,b,c;
for(c=175;c>0;c--)
for(b=22;b>0;b--)
for(a=118;a>0;a--);
}
/******************************************************************
-功能描述:
写数据(命令)子函数
-入口参数:
x,dat
-参数值:
x=0ro1dat=0x00-0xff;
-返回说明:
无
-备 注:
X=0写命令x=1写数据
******************************************************************/
voidL12864_Write(bitx,unsignedchardat)
{
if(x)
L12864_RS=1;
else
L12864_RS=0;//RS置高电平
L12864_RW=0;//RW置低电平
L12864_Data=dat;//写入数据
L12864_E=1;//E下降沿
L12864_Delayus(5);
L12864_E=0;
}
/******************************************************************
-功能描述:
读数据子程序
-入口参数:
无
-参数值:
无
-返回说明:
无
-备 注:
******************************************************************/
unsignedcharL12864_Read(void)
{
unsignedchardat;
L12864_Data=0xff;//读空操作
L12864_RS=1;//thedata
L12864_RW=1;//read
L12864_E=1;//E下降沿
L12864_E=1;//
L12864_E=0;//
L12864_Data=0xff;//读空操作
L12864_RS=1;//thedata
L12864_RW=1;//read
L12864_E=1;//E下降沿
dat=L12864_Data;//
L12864_E=0;//
returndat;//
}
/******************************************************************
-功能描述:
初始化子程序
-入口参数:
无
-参数值:
无
-返回说明:
无
-备 注:
******************************************************************/
voidL12864_init(void)//初始化12864
{
L12864_Delay50us();//延时40ms以上
L12864_RST=1;//RST上升沿复位
L12864_Delayus
(2);
L12864_RST=0;
L12864_Delayus(5);
L12864_RST=1;
L12864_CS1=1;//片选
L12864_CS2=1;
L12864_Delayus(5);
L12864_Write(L12864_comm,0x3e);//关显示
L12864_Delayus(5);
L12864_Write(L12864_comm,0x3f);//开显示
L12864_Delayus(5);
L12864_CS1=0;//关闭片选
L12864_CS2=0;
}
/******************************************************************
-功能描述:
清屏子程序
-入口参数:
无
-参数值:
无
-返回说明:
无
-备 注:
******************************************************************/
voidL12864_ClearScreen(void)
{unsignedcharx,y;
L12864_CS1=L12864_CS2=1;//选中屏
L12864_Write(L12864_comm,0xc0);//定义起始行
for(x=0;x<8;x++)
{
L12864_Write(L12864_comm,0xb8+x);//定义页
for(y=0;y<64;y++)
{
L12864_Write(L12864_comm,0x40+y);//定义列
L12864_Write(L12864_data,0x00);//写数据
}
}
}
/******************************************************************
-功能描述:
画点子程序
-入口参数:
X,Y,DOT
-参数值:
X=0-127Y=0-63DOT=0or1
-返回说明:
无
-备 注:
X,Y为要画点的坐标位置DOT表示画点
(1)或清点(0)
******************************************************************/
voidL12864_DrawDot(unsignedcharX,unsignedcharY,bitDOT)
{
unsignedch