一、基本介绍
项目名:
基于单片机的智能门禁系统设计
基于单片机的小区门禁系统系统设计
基于单片机的刷卡门禁系统系统设计
项目编号:mcuclub-jj-001
单片机类型:STC89C52
具体功能:
1、密码输入:首先输入住户门牌号,然后进入输入密码界面,密码正确后,门锁打开,错误后蜂鸣器报警1s,若密码输入错误3次,则蜂鸣器持续报警10s。
可添加门牌号和密码,添加步骤:门牌号—>管理员密码—>新密码—>再次新密码。
可修改密码,修改步骤:门牌号—>管理员密码—>旧密码—>新密码—>再次新密码。
另外,密码是可以掉电保存在AT24C02中。
2、刷卡:通过RFID进行刷卡进入,刷有效卡,门锁打开,无效卡,蜂鸣器报警1s,若无效卡刷3次,则蜂鸣器持续报警10s。可添加卡或删除卡
3、通过4*4矩阵键盘可输入密码,进入不同模式
4、通过显示屏显示数据
扩展功能:通过zigbee,可一键呼叫,外机可进行一键开门
二、资料总览
实物资料
仿真资料
三、51单片机部分资料展示
1、实物图展示
单片机型号:STC89C52
供电接口:TYPE-C
板子类型:PCB集成板,厚度1.2,两层板(上下层覆铜接地)
器件类型:元器件基本上为插针式,个别降压芯片会使用贴片式。
2、仿真图展示
仿真软件版本:proteus8.9
电路连线方式:网络标号连线方式
注意:部分实物元器件仿真中没有,仿真中会用其他工作原理相似的元件代替,这样可能导致实物程序和仿真程序不一样
3、原理图展示
软件版本:AD2013
电路连线方式:网络标号连线方式
注意:原理图只是画出了模块的引脚图,而并不是模块的内部结构图
4、PCB图展示
由原理图导出,中间有一个项目编号,隐藏在单片机底座下,插入单片机后不会看到。
两层板,上下覆铜接地。
四、32单片机部分资料展示
1、实物图展示
单片机型号:STM32F103C8T6
供电接口:TYPE-C
板子类型:PCB集成板,厚度1.2,两层板(上下层覆铜接地)
器件类型:元器件基本上为插针式,个别降压芯片会使用贴片式。
2、原理图展示
软件版本:AD2013
电路连线方式:网络标号连线方式
注意:原理图只是画出了模块的引脚图,而并不是模块的内部结构原理图
3、PCB图展示
由原理图导出,中间有一个项目编号,隐藏在单片机底座下,插入单片机后不会看到。
两层板,上下覆铜接地。
五、系统框图
绘制软件:VISIO
本设计以单片机为核心控制器,加上其他模块一起组成此次设计的整个系统,此次设计可以分为主机和从机,从机和主机都可以分为三部分输入、输出和中控,主机的输入由三个部分组成,第一部分是矩阵键盘模块,用户可以通过该模块输入对应的数子;第二部分是供电模块,通过该模块给从机进行供电;第三部分是RFID模块,通过RFID进行刷卡进入;输出由五部分组成,第一部分是显示模块,通过显示屏显示数据和设置的阈值;第二部分是存储模块,通过该模块对数据和密码进行保存;第三部分是继电器控制模块,控制门锁打开和关闭;第四部分是蜂鸣器电路模块,通过该模块进行蜂鸣器报警;第五部分是zigbee模块,通过zigbee模块发射模块,将用户输入的数子传输到从机,从机的输入由四部分组成,第一部分是4P拨码开关模块,通过4*4矩阵键盘可输入密码,进入不同模式;第二部分是按键模块,通过该模块设置数据和设置的阈值;第三部分是zigbee接收模块,用户可以通过该模块接收输入端发射的指令;第四部分是供电模块,通过该模块给系统进行供电;输出由声光报警模块组成,通过该模块检测是否是无效卡,无效卡则蜂鸣器报警。具体系统框图如图3.1所示。
六、部分程序展示
软件版本:keil5
注意:逻辑程序和驱动程序分开,分布于main.c和其他.c文件
*******按键函数
*****/
void Key_function(void)
{
key_num = Chiclet_Keyboard_Scan(); //按键扫描
if(key_num != 0xff) //有按键按下
{
if(key_num == 3) //按键A:添加用户号
{
Oled_Clear_All();
Oled_ShowCHinese(1,2,"添加住户");
if(user_number < 30)
{
Oled_ShowCHinese(2,0,"请输入住户号");
Oled_ShowCHinese(3,0,"户号:");
flag_reset_password = 1;
flag_set_user = 1;
}
else
{
Oled_ShowCHinese(2,0,"户号已满");
Oled_ShowCHinese(3,0,"无法添加");
Delay_ms(1000);
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_reset_password = 0;
flag_set_user = 0;
}
flag_open_step = 0;
memset(input_buf,'\r',6);
input_num = 0;
flag_rfid = 0;
flag_rfiden = 0;
addr_operation = 0;
}
else if(key_num == 7) //按键B:修改用户密码
{
Oled_Clear_All();
Oled_ShowCHinese(1,2,"修改密码");
Oled_ShowCHinese(2,0,"请输入住户号");
Oled_ShowCHinese(3,0,"户号:");
flag_open_step = 0;
memset(input_buf,'\r',6);
input_num = 0;
flag_reset_password = 1;
flag_set_user = 2;
flag_rfid = 0;
flag_rfiden = 0;
addr_operation = 0;
}
else if(key_num == 11) //按键C:添加卡
{
Oled_Clear_All();
Oled_ShowCHinese(1,2,"添加卡");
Oled_ShowCHinese(2,0,"请输入管理员密码");
Oled_ShowCHinese(3,0,"密码:");
flag_open_step = 0;
memset(input_buf,'\r',6);
input_num = 0;
flag_reset_password = 0;
flag_set_user = 0;
flag_rfid = 1;
flag_rfiden = 0;
addr_operation = 0;
}
else if(key_num == 15) //按键D:删除卡
{
Oled_Clear_All();
Oled_ShowCHinese(1,2,"删除卡");
Oled_ShowCHinese(2,0,"请输入管理员密码");
Oled_ShowCHinese(3,0,"密码:");
flag_open_step = 0;
memset(input_buf,'\r',6);
input_num = 0;
flag_reset_password = 0;
flag_set_user = 0;
flag_rfid = 2;
flag_rfiden = 0;
addr_operation = 0;
}
else if(key_num == 12) //按键 * :删除一位输入数据
{
if(input_num != 0)
{
input_num--;
if(flag_reset_password == 0 && flag_rfid == 0)
Oled_ShowString(2,6+input_num," ");
else
Oled_ShowString(3,6+input_num," ");
}
}
else if(key_num == 14) //按键 # :确认
{
Ensure_function();
}
else if((key_num<12 && key_num%4<3) || key_num==13) //按下的是数字键,保存输入数字
{
if(key_num != 13)
key_num = (key_num/4*3 + (key_num%4+1));
else
key_num = 0;
if(flag_reset_password == 0 && flag_rfid == 0) //开门模式
{ //户号最多两位
if((flag_open_step == 0 && input_num < 2) || (flag_open_step == 2 && input_num < 6))
{
Oled_ShowString(2,6+input_num,"*");
input_buf[input_num] = key_num;
input_num++;
}
else if(flag_open_step == 1) //选择输入密码或呼叫
{
if(key_num == 1)
{
Oled_ShowString(2,0," ");
Oled_ShowCHinese(2,0,"密码:");
flag_open_step++;
}
else if(key_num == 2)
{
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_open_step = 0;
UsartPrintf(USART1,"\xFC\x05\x01\x02 %02d",(int)(user_data.user_num[0]*10+user_data.user_num[1]));
input_num = 0;
memset(input_buf,'\r',6);
}
}
}
else
{
if((flag_reset_password == 1 && input_num < 2) || (flag_reset_password != 1 && input_num < 6))
{
Oled_ShowString(3,6+input_num,"*");
input_buf[input_num] = key_num;
input_num++;
}
}
}
}
}
/****
*******确认函数
*****/
void Ensure_function(void)
{
u8 i = 0;
if(flag_rfid == 0) //输入密码模式
{
if(flag_reset_password == 0) //输入户号密码开门模式
{
if(flag_open_step == 0) //用户号步骤,查找户号及密码
{
memset(user_data.user_num,'\n',2);
memset(user_data.user_password,'\n',6);
for(i = 0; i < user_number; i++)
{
AT24CXX_Read(i*8,user_data.user_num,2);
if(user_data.user_num[0] == input_buf[0] && user_data.user_num[1] == input_buf[1])
{
AT24CXX_Read((i*8)+2,user_data.user_password,6);
break;
}
}
user_data.user_num[0] = input_buf[0];
user_data.user_num[1] = input_buf[1];
flag_open_step++;
Oled_ShowString(2,0," ");
Oled_ShowString(2,0,"1:");
Oled_ShowCHinese(2,1,"密码");
Oled_ShowString(2,8,"2:");
Oled_ShowCHinese(2,5,"呼叫");
}
else if(flag_open_step == 2) //密码步骤,判断密码是否正确,如果密码正确开门
{
if(memcmp(user_data.user_password,input_buf,6) == 0)
{
Oled_ShowCHinese(3,0,"密码正确");
RELAY_D = 1;
Delay_ms(1500);Delay_ms(1500);
RELAY_D = 0;
Oled_ShowCHinese(2,0,"户号:");
Oled_ShowString(2,6," ");
Oled_ShowString(3,0," ");
flag_error_num = 0;
}
else //密码不正确,蜂鸣器警报
{
flag_error_num++;
BEEP = 1;
Oled_ShowCHinese(3,0,"密码错误");
Oled_ShowCHinese(4,0,"请重新输入");
if(flag_error_num >= 3) //如果密码错误三次,蜂鸣器响十秒,否则一秒
{
flag_error_num = 0;
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
}
else
Delay_ms(1000);
BEEP = 0;
Oled_ShowString(2,6," ");
Oled_ShowString(3,0," ");
Oled_ShowString(4,0," ");
Oled_ShowCHinese(2,0,"户号:");
}
flag_open_step = 0;
}
}
else if(flag_reset_password == 1) //用户设置模式1
{
for(i = 0; i < user_number; i++)
{
AT24CXX_Read(i*8,user_data.user_num,2);
if(user_data.user_num[0] == input_buf[0] && user_data.user_num[1] == input_buf[1])
{
addr_operation = i;
AT24CXX_Read((i*8)+2,user_data.user_password,6);
break;
}
}
if(flag_set_user == 1) //添加用户,如果用户已存在,不能添加,否则可以添加
{
if(i == user_number)
{
flag_reset_password++;
Oled_ShowCHinese(2,0,"请输入管理员密码");
Oled_ShowCHinese(3,0,"密码:");
Oled_ShowString(3,6," ");
user_data.user_num[0] = input_buf[0];
user_data.user_num[1] = input_buf[1];
}
else
{
Oled_ShowString(3,0," ");
Oled_ShowCHinese(3,0,"户号已存在");
Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_reset_password = 0;
flag_set_user = 0;
}
}
else if(flag_set_user == 2) //修改用户密码,如果用户存在,可以修改,否则不能修改
{
if(i == user_number)
{
Oled_ShowString(3,0," ");
Oled_ShowCHinese(3,0,"户号不存在");
Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_reset_password = 0;
flag_set_user = 0;
}
else
{
flag_reset_password++;
Oled_ShowCHinese(2,0,"请输入管理员密码");
Oled_ShowCHinese(3,0,"密码:");
Oled_ShowString(3,6," ");
}
}
}
else if(flag_reset_password == 2) //用户设置模式2
{
if(memcmp(admipassword,input_buf,6) == 0) //管理员密码正确
{
Oled_ShowCHinese(4,0,"密码正确");
Delay_ms(1000);
Oled_ShowString(2,0," ");
Oled_ShowString(3,6," ");
Oled_ShowString(4,0," ");
if(flag_set_user == 1) //如果是添加用户,输入新密码,如果是修改,输入旧密码
Oled_ShowCHinese(2,0,"请输入新密码");
else if(flag_set_user == 2)
Oled_ShowCHinese(2,0,"请输入旧密码");
flag_reset_password++;
}
else //密码错误,蜂鸣器警报
{
flag_error_num++;
BEEP = 1;
Oled_ShowString(3,0," ");
Oled_ShowCHinese(3,0,"密码错误");
if(flag_error_num >= 3) //如果密码错误三次,蜂鸣器响十秒,否则一秒
{
flag_error_num = 0;
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
BEEP = 0;
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_reset_password = 0;
flag_set_user = 0;
addr_operation = 0;
}
else
{
Oled_ShowCHinese(4,0,"请重新输入");
Delay_ms(1000);
BEEP = 0;
Oled_ShowString(3,0," ");
Oled_ShowString(4,0," ");
Oled_ShowCHinese(3,0,"密码:");
}
}
}
else if(flag_reset_password == 3) //用户设置模式3
{
if(flag_set_user == 1) //如果添加用户,再次输入新密码
{
Oled_ShowString(2,0," ");
Oled_ShowString(3,6," ");
Oled_ShowCHinese(2,0,"请再次输入新密码");
Delay_ms(1000);
for(i = 0; i < 6; i++)
{
user_data.user_password[i] = input_buf[i];
}
flag_reset_password++;
}
else if(flag_set_user == 2) //如果是修改用户
{
if(memcmp(user_data.user_password,input_buf,6) == 0) //如果密码正确,输入新密码
{
Oled_ShowCHinese(4,0,"密码正确");
Delay_ms(1000);
Oled_ShowString(2,0," ");
Oled_ShowString(3,6," ");
Oled_ShowString(4,0," ");
Oled_ShowCHinese(2,0,"请输入新密码");
flag_reset_password++;
flag_error_num = 0;
}
else //否则密码错误,蜂鸣器警报
{
flag_error_num++;
Oled_ShowString(3,0," ");
Oled_ShowCHinese(3,0,"密码错误");
if(flag_error_num >= 3) //如果密码错误三次,蜂鸣器响十秒,否则一秒
{
flag_error_num = 0;
BEEP = 1;
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
BEEP = 0;
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_reset_password = 0;
flag_set_user = 0;
addr_operation = 0;
}
else
{
Oled_ShowCHinese(4,0,"请重新输入");
Delay_ms(1000);
Oled_ShowString(3,0," ");
Oled_ShowString(4,0," ");
Oled_ShowCHinese(3,0,"密码:");
}
}
}
}
else if(flag_reset_password == 4) //用户设置模式4
{
if(flag_set_user == 1) //如果添加用户,两次新密码相同;如果修改用户密码,再次输入新密码
{
flag_reset_password = 0;
flag_set_user = 0;
if(memcmp(user_data.user_password,input_buf,6) == 0)
{
AT24CXX_Write(user_number*8,user_data.user_num,2);
AT24CXX_Write((user_number*8)+2,user_data.user_password,6);
user_number++;
AT24CXX_WriteOneByte(ADDR_UCount,user_number);
Oled_ShowCHinese(4,0,"添加成功");
Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
}
else
{
Oled_ShowCHinese(3,0," ");
Oled_ShowCHinese(3,0,"密码不一致");
Oled_ShowCHinese(4,0,"添加失败");
Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
}
}
else if(flag_set_user == 2)
{
Oled_ShowString(2,0," ");
Oled_ShowString(3,6," ");
Oled_ShowCHinese(2,0,"请再次输入新密码");
Delay_ms(1000);
for(i = 0; i < 6; i++)
{
user_data.user_password[i] = input_buf[i];
}
flag_reset_password++;
}
}
else if(flag_reset_password == 5) //用户设置模式5,修改用户密码,两次新密码相同,修改成功
{
flag_reset_password = 0;
flag_set_user = 0;
if(memcmp(user_data.user_password,input_buf,6) == 0)
{
AT24CXX_Write(addr_operation*8,user_data.user_num,2);
AT24CXX_Write((addr_operation*8)+2,user_data.user_password,6);
Oled_ShowCHinese(4,0,"修改成功");
Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
}
else
{
Oled_ShowString(3,0," ");
Oled_ShowCHinese(3,0,"密码不一致");
Oled_ShowCHinese(4,0,"修改失败");
Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
}
}
}
else //RFID操作模式
{
if(memcmp(admipassword,input_buf,6) == 0) //管理员密码与输入密码相同,提示放卡,否则提示密码错误
{
Oled_ShowCHinese(4,0,"密码正确");
Delay_ms(1000);
Oled_ShowString(2,0," ");
Oled_ShowString(3,0," ");
Oled_ShowString(4,0," ");
Oled_ShowCHinese(2,0,"请放入卡");
flag_rfiden = 1;
flag_error_num = 0;
}
else //如果密码错误三次,蜂鸣器响十秒,否则一秒
{
flag_error_num++;
BEEP = 1;
Oled_ShowString(3,0," ");
Oled_ShowCHinese(3,0,"密码错误");
if(flag_error_num >= 3)
{
flag_error_num = 0;
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
BEEP = 0;
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_reset_password = 0;
flag_set_user = 0;
addr_operation = 0;
}
else
{
Oled_ShowCHinese(4,0,"请重新输入");
Delay_ms(1000);
BEEP = 0;
Oled_ShowString(3,0," ");
Oled_ShowString(4,0," ");
Oled_ShowCHinese(3,0,"密码:");
}
}
}
input_num = 0;
memset(input_buf,'\r',6);
}
/****
*******搜索RFID函数
*****/
void Search_Rfid_function(void)
{
if(RC522_Request(0x52,RF_TP) == MI_OK) //实时检测卡
{
if(RC522_Anticoll(RF_ID) == MI_OK) //防冲撞
{
switch(flag_rfid)
{
case 0: //RFID卡开锁模式
if(flag_reset_password == 0)
{
flag_open_step = 0;
if((RF_ID[0]==rfid_id[0]) && (RF_ID[1]==rfid_id[1]) && (RF_ID[2]==rfid_id[2]) && (RF_ID[3]==rfid_id[3])) //对比卡号正确,开锁
{
Oled_ShowString(2,0," ");
Oled_ShowCHinese(2,0,"卡正确");
RELAY_D = 1;
Delay_ms(1500);Delay_ms(1500);
RELAY_D = 0;
Oled_ShowString(2,0," ");
Oled_ShowCHinese(2,0,"户号:");
}
else //否则不开锁
{
flag_error_num++;
Oled_ShowString(2,0," ");
Oled_ShowCHinese(2,0,"卡无效");
BEEP = 1;
if(flag_error_num >= 3)
{
flag_error_num = 0;
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
}
else
{
Oled_ShowCHinese(3,0,"请重新放入卡");
Delay_ms(1000);
}
BEEP = 0;
Oled_ShowString(2,0," ");
Oled_ShowString(3,0," ");
Oled_ShowCHinese(2,0,"户号:");
}
}
break;
case 1: //添加RFID卡模式
if(flag_rfiden == 1)
{
flag_rfiden = 0;
AT24CXX_Write(ADDR_UIDcard,RF_ID,4);
rfid_id[0] = RF_ID[0];
rfid_id[1] = RF_ID[1];
rfid_id[2] = RF_ID[2];
rfid_id[3] = RF_ID[3];
Oled_ShowCHinese(3,0,"添加成功");
Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_rfid = 0;
}
break;
case 2: //删除RFID卡模式
if(flag_rfiden == 1)
{
flag_rfiden = 0;
if((RF_ID[0]==rfid_id[0]) && (RF_ID[1]==rfid_id[1]) && (RF_ID[2]==rfid_id[2]) && (RF_ID[3]==rfid_id[3])) //对比卡号,卡号正确删除成功
{
AT24CXX_Write(ADDR_UIDcard,"\xff\xff\xff\xff",4);
memset(rfid_id,'\r',4);
Oled_ShowCHinese(3,0,"删除成功");
Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_rfid = 0;
}
else //卡号不正确,删除失败
{
Oled_ShowCHinese(3,0,"卡无效");
BEEP = 1;
if(flag_error_num >= 3)
{
flag_error_num = 0;
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);
Oled_Clear_All();
Oled_ShowCHinese(1,2,"智能门禁");
Oled_ShowCHinese(2,0,"户号:");
flag_rfid = 0;
}
else
{
Oled_ShowCHinese(4,0,"请重新放入卡");
Delay_ms(1000);
}
BEEP = 0;
}
}
break;
default:
break;
}
input_num = 0;
memset(input_buf,'\r',6);
}
}
}
/****
*******外机指令处理函数
*****/
void Peripherals_function(void)
{
if(USART1_WaitRecive() == 0) //接收到外机数据
{
if(usart1_buf[0] == 0xcc) //如果是开门指令,开门
{
if(flag_reset_password == 0 && flag_rfid == 0)
{
RELAY_D = 1;
Delay_ms(1500);Delay_ms(1500);
RELAY_D = 0;
}
}
USART1_Clear();
}
}