概要
门禁系统是一种面向人们生活的社区,家庭,旅馆等地方,并且可以通过一个锁一张卡进行独立管理,或者一个锁多张卡进行集中管理的系统。本文设计了一种使用方便,安全性高的基于单片机的RFID门禁系统。
本设计主要利用STC89C52单片机对系统进行控制,由最小系统、射频识别模块、液晶显示模块等组成的硬件系统,以及通过C语言开发程序进行代码的设计和编写的软件系统,最终实现射频识别功能以及密码识别功能。本设计的目标是使设计出来的系统能提高安全指数,刷卡识别准确,给生活带来方便,被更多人所应用。
结果表明本设计很好地实现了射频识别功能以及密码识别功能,预期功能全部实现。使用单片机进行控制保证了系统的稳定性,RFID技术的应用使得门禁系统的管理和使用更加方便和安全。RFID技术已经被应用在了便携式和小型轻量化方向上的许多电子产品中,且已经开发出了许多的非接触式RFID卡控制系统。目前,非接触式RFID卡已经在公交卡、金融卡、门禁卡、校园一卡通等许多领域得到了广泛的应用。这使人们在实际生活中不需要为环境是否安全而困扰,也让许多管理更加详细,高效和准确。
关键词:RFID; 门禁系统; 液晶显示; 单片机控制
一、控制系统设计
1 项目总体设计
本项目基于单片机的RFID门禁系统设计由:STC89C52单片机、矩阵键盘、12864液晶显示、报警、继电器驱动模块、RFID-RC522射频识别模块、AT24C02存储模块组成。通过密码识别和射频识别控制门锁,构成完整的门禁系统。由如下模块组成:
(1)最小系统模块:STC89C52单片机作为系统的主控制器,接收密码识别模块和射频识别模块的信息[21],经过处理再传递到液晶显示模块和继电器驱动模块;
(2)液晶显示模块:LCD12864液晶显示屏,接收密码识别模块和射频识别模块的信息,显示密码或RFID卡是否正确,是否可以通过;
(3)密码识别模块:由存储器、解调器、键盘等组成,通过对键盘输入密码信息进行分析识别,最终传递到液晶显示模块,实现密码识别功能[1];
(4)射频识别模块:首先通过MFRC522读卡器读取用户的RFID卡信息,然后读取的信息用来识别RFID卡是否为已注册卡,最终传递到液晶显示模块,实现RFID卡识别功能[17];
(5)AT24C02存储模块:读卡器读取到RFID卡信息之后,信息会存储在AT24C02中,这时单片机再接收到新的数据,就可以和AT24C02中的信息作比较,看信息是否相同,从而决定开关门[12]。
(6)继电器驱动模块:接收到的新的信息与AT24C02中存储的信息进行比较之后,结合蜂鸣器和指示灯[4],控制电磁锁的吸合,进而控制门的状态。
本系统结构框图如图1.1所示。
图1.1 系统结构框图
电源供电后,单片机通过对RFID卡信息和按键输入信息进行处理,经转换后传输给步进电机驱动电路、液晶显示电路、报警电路,完成系统的运行。
二、总电路图设计
本设计采用STC89C52单片机作为主控制器,包括LCD12864液晶显示电路、射频识别电路、报警电路、按键电路、继电器驱动电路以及电源电路[4]
三、项目软件设计
3.2 系统主程序设计
基于单片机的RFID门禁系统以单片机为主控制器,MFRC522非接触式读卡芯片用来完成本设计的读写RFID卡功能[9],当刷卡时,对卡内信息进行读写,当密码错误超出3次就把键盘锁死报警。门禁系统设计的程序可以实现以下的功能:
(1)可以注册和注销卡;
(2)已注册卡可以开门,没有注册卡则无法开门;
(3)可以设置密码,当使用者遇到忘记携带RFID卡的情况时,可通过键盘手动输入密码,减少了不必要的麻烦;
(4)通过输入原始密码,进入设置页面,就可以对原有的密码进行修改;
(5)如果系统检测到有用户连续3次输入了不正确的密码,则蜂鸣器会发出警报,而且键盘只有通过复位才能恢复正常使用;
(6)信息被12864液晶显示屏接收后,在显示屏上会显示密码的正确与否,RFID卡是不是已注册卡以及设置页面密码的修改、RFID卡的注册与注销。
系统主程序流程图如图3.3所示。
图3.3 系统程序总体流程图
根据本设计预期实现功能,对实物进行调试
(1)LCD12864液晶显示屏显示刷卡是否成功与密码是否正确等状态;
(2)系统集成两种解锁方式:RFID卡解锁、密码解锁,在忘记带RFID卡时可通过密码进行解锁;
(3)刷卡之后,通过MFRC522读卡器可以读取到卡内的信息,信息匹配成功继电器吸合门锁打开,十秒左右会自动关闭门禁;如果匹配失败声光报警提醒;
(4)可以通过管理界面进行RFID卡的注册和注销,同时也可以进入管理界面,把原密码修改为新密码。
(5)4×4矩阵键盘定义,分别为数字键、进入管理键、切换上一项键、切换下一项键、退格键、确定键、返回上一级菜单键。
本设计的所有功能均能实现,实物如图4.3所示。
图4.3 设计实物图
程序
#include #include //包含头文件 //#include //#include #define uchar unsigned char #define uint unsigned int //定义变量类型 #define nop() _nop_() //空操作指令 宏定义 uchar xdata shu[16]; //IC内容暂存数组变量 uchar xdata RevBuffer[4]; //IC卡的唯一序列号 uchar xdata IDH[4]; //当先检测的IC卡序列号 uchar code DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; #include "rc522.c" //调用控制检测文件 #include "SerialLcd12864.c" //调用控制检测文件 #include "24C02.h" //调用控制检测文件 sbit Door=P3^0; sbit Beep=P2^0; //定义IO口 uchar code Pass[6]={1,3,1,4,2,0}; //定义万能密码数组 uint OperationTime; //定义变量 uchar ShowMode,HintMode,SetOption; //定义变量 ShowMode显示的模式,其实就是显示的状态 uchar ms,PassNum,OpenTime,BeepNum,ShowTime,Show3Time; //定义变量 uchar xdata SysPass[6],InputPass[6],NewPass[6],AgainPass[6]; //定义数组,系统密码数组、输入密码数组,新密码数组。再一次输入密码数组 uchar ResultShow,ErrorNum; //定义变量 ErrorNum错误次数 bit s1,ok,bj; //定义位变量 void delay(uint T) //短延时函数 { while(T--); } void TimerConfig(void) { SCON= 0x50; //串口方式1 //REN=1; 允许接收 PCON=0x00; //SMOD=0 TMOD= 0x21; //定时器1定时方式2 TH1= 0xFD; //11.0592MHz 模块默认波特率为9600bps TL1= 0xFD; TR1= 1; //启动定时器 TH0=0x3c; TL0=0xb0; EA=1; ET0=1; TR0=1; } /*****************Fingerprint Code****************/ void show() // 12864液晶显示程序 { uchar i; //定义局部变量 //ShowMode=6; switch(ShowMode) // switch case语句,当 ShowMode=0,就会执行ShowMode=1;,==1,就会执行case 1;的语句 { case 0: ShowMode=1; break; case 1: LCD12864_pos(1,2); //液晶控制写地址命令 LCD12864_pos括号里有两个,第一个数据填写的是显示的第几行,第二个数据是显示这一行的第几个位置 LCD12864_writebyte("欢迎使用"); //显示字符串 LCD12864_pos(2,1); //第二行第一个位置显示 LCD12864_writebyte("多功能电子锁"); //显示字符串 break; case 2: LCD12864_pos(0,1); //第零行,第一个位置开始准备显示 LCD12864_writebyte("密码输入开锁"); //显示字符串 LCD12864_pos(1,1); //第一行第一个位置 LCD12864_writebyte(" "); //显示空 for(i=0;i LCD12864_write(1,0x2a); //对于这个函数LCD12864_write,里面也是填写两个数据,第一个是0/1,只能填写0或者1,0代表命令,1代表数据,然后填写的数据是根据前面的数据命令来控制的,比如这个,0x2A就是数据 } //显示部分基本就是这样,就不做过多的赘述 if(s1==0&&PassNum LCD12864_writebyte(" "); } break; case 3: // HintMode=1; switch(HintMode) //门状态switch case语句 HintMode=0,就是门代开 { case 0: LCD12864_pos(1,2); LCD12864_writebyte("门已打开"); break; case 30: LCD12864_pos(1,2); LCD12864_writebyte("门已打开"); // HintMode=1,就是门关闭 LCD12864_pos(2,1); LCD12864_writebyte("ID:"); //下下面显示门禁ID号 for(i=0;i if(IDH[i]/16 if(IDH[i]/16 //SetOption设置变量 case 0: LCD12864_pos(0,0); LCD12864_writebyte("★"); // →☆ LCD12864_pos(1,0); LCD12864_writebyte(" "); LCD12864_pos(2,0); LCD12864_writebyte(" "); break; case 1: LCD12864_pos(1,0); LCD12864_writebyte("★"); // →☆ LCD12864_pos(0,0); LCD12864_writebyte(" "); LCD12864_pos(2,0); LCD12864_writebyte(" "); break; } LCD12864_pos(0,1); //4行显示选择内容 LCD12864_writebyte("①密码设置"); LCD12864_pos(1,1); LCD12864_writebyte("②IC卡登记"); break; case 5: LCD12864_pos(0,2); LCD12864_writebyte("密码设置"); //设置密码部分 LCD12864_pos(1,0); LCD12864_writebyte("原密码:"); if(SetOption==0) { for(i=0;i LCD12864_write(1,0x2a); //LCD12864_write(1,0x30+InputPass[i]); } if(PassNum==0) { if(s1==0) LCD12864_write(1,0x5f); //显示数据下的横杠 else LCD12864_writebyte(" "); } for(i=0;i LCD12864_writebyte(" "); } } LCD12864_pos(2,0); LCD12864_writebyte("新密码:"); //显示新密码 if(SetOption==1) { for(i=0;i LCD12864_write(1,0x2a); //星号 } if(PassNum==0) { if(s1==0) LCD12864_write(1,0x5f); //横杠 else LCD12864_writebyte(" "); } for(i=0;i LCD12864_writebyte(" "); } } LCD12864_pos(3,0); LCD12864_writebyte("再一次:"); //再次确定密码 if(SetOption==2) { for(i=0;i LCD12864_write(1,0x2a); } if(PassNum==0) { if(s1==0) LCD12864_write(1,0x5f); else LCD12864_writebyte(" "); } for(i=0;i LCD12864_writebyte(" "); } } break; case 6: if(SetOption==0) { LCD12864_pos(0,2); LCD12864_writebyte("注册IC卡"); //设置状态里的,修改IC部分,注册、注销、 }else { LCD12864_pos(0,2); LCD12864_writebyte("注销IC卡"); } if(ResultShow==1) { LCD12864_pos(2,2); LCD12864_writebyte("注册完成"); LCD12864_pos(3,1); LCD12864_writebyte("ID:"); for(i=0;i if(IDH[i]/16 LCD12864_pos(2,2); LCD12864_writebyte("注销完成"); //显示注册完成 LCD12864_pos(3,1); LCD12864_writebyte("ID:"); for(i=0;i if(IDH[i]/16 LCD12864_pos(2,2); LCD12864_writebyte("IC卡错误"); //IC卡刷卡错误 LCD12864_pos(3,1); LCD12864_writebyte("ID:"); for(i=0;i if(IDH[i]/16 LCD12864_pos(2,2); LCD12864_writebyte(" "); LCD12864_pos(3,1); LCD12864_writebyte(" "); } break; case 8: LCD12864_pos(1,1); LCD12864_writebyte("输入错误超限"); //输入密码错误三次之后的显示界面 LCD12864_pos(2,1); LCD12864_writebyte("