STM32
直播中

张娟

7年用户 2059经验值
私信 关注
[问答]

怎样去使用基于stm32F103的门禁系统呢?

怎样去使用基于STM32F103的门禁系统呢?

怎样去设计一种基于stm32F103的门禁系统呢?

回帖(1)

赵天湖

2021-10-19 14:24:22
1.引言
学了这么久的知识了,现在大二了。想着总不能老是吸取别人的经验嘛!于是就突发奇想地想写一次博客,跟大家分享一下我的学习经验。第一次写博客,如果有什么问题,还请大家见谅见谅,欢迎大家指出问题来。
这是我在大一下学期跟着师兄做的物联网智能家居项目里面的模块,当时师兄让我负责门禁这一方面。没办法当时的我就是菜鸟一个,对于人脸识别等高技术根本就不懂。于是就在网上搜索了一天,确定了方案后,断断续续地花了一个星期,最终完成任务。那么废话少说了,开始进入正题了。
2.概述
在该项目的门禁系统中我主要采用了以stm32F103系列单片机作为MCU,以ATK-AS608指纹识别模块作为指纹识别模块,和4X4矩阵按键为密码按键模块。该门禁系统可以通过指纹识别确认成功或者通过按键输入正确密码则开锁后,MCU发送指令控制继电器驱动模块进行开锁。当指纹识别失败或者输入密码错误时则会通过蜂鸣器报警。
在以上实现的基础上,对指纹模块和按键模块加以优化功能。当家里没有人的时候,门禁系统需要同时通过指纹和按键密码才能开锁。当家里有人是可以任选一种方式。假若刷指纹失败超过六次,则需要通过两次刷指纹和一次按键密码才能开锁。
下面是正确操作步骤

3.元器件部分清单


4.硬件部分说明

继电器模块的接口说明:
1、DC+:接电源正极(电压按继电器要求,有5V.9V.12V和24V选择) 2、DC-:接电源负极 3、IN:可以高或低电平控制继电器吸合 继电器输出端: 1、NO: 继电器常开接口,继电器吸合前悬空,吸合后与COM短接 2、COM:继电器公用接口 3、NC: 继电器常闭接口,继电器吸合前与COM短接,吸合后悬空。下面时示意图:




矩阵按键
在本系统中,我采用了4X4的矩阵按键来作为实现密码按键功能,

))。
目前一般使用的方法有两种,分别是:
方法一:先通过高四位全部输出低电平,然后逐行扫描,如果低四位不为1(非门)则,该行的按键被按下
方法二(常用):先给高四位全部输出低电平,低四位输出高电平,接受数据,当低四位不全为高电平时,判断所在列,然后,低四位输出低电平,高四位输出高电平,判断行,行列都判断了;
对于哪种方法比较好,那就个人而异了。下面的代码是采用了第二种方法
5.部分代码
key.c//按键返回值
int key(void) //返回int类型按键值
{
//已经定义PB8~11为上拉输入,PB12~15为下拉输入
int KeyVal=0;
GPIO_Write(GPIOB,(GPIOB-》ODR & 0xf0ff | 0x0f00));
if((GPIOB-》IDR & 0xf000)==0x0000)
return -1;
else
{
delay_ms(5);
if((GPIOB-》IDR & 0xf000)==0x0000)
return -1;
}
GPIO_Write(GPIOB,(GPIOB-》ODR & 0xf0ff | 0x0100));
switch(GPIOB-》IDR & 0xf000)
{
case 0x1000: KeyVal=1;Key_Scan[1]=1;break;//1
case 0x2000: KeyVal=2;Key_Scan[2]=2; break;//2
case 0x4000: KeyVal=3;Key_Scan[3]=3; break;//3
case 0x8000: KeyVal=11;break;//A
}
GPIO_Write(GPIOB,(GPIOB-》ODR & 0xf0ff | 0x0200));
switch(GPIOB-》IDR & 0xf000)
{
case 0x1000: KeyVal=4;Key_Scan[4]=4; break;
case 0x2000: KeyVal=5;Key_Scan[5]=5; break;
case 0x4000: KeyVal=6;Key_Scan[6]=6; break;
case 0x8000: KeyVal=12;Key_Scan[1]=0; break;
}
GPIO_Write(GPIOB,(GPIOB-》ODR & 0xf0ff | 0x0400));
switch(GPIOB-》IDR & 0xf000)
{
case 0x1000: KeyVal=7;Key_Scan[7]=7; break;
case 0x2000: KeyVal=8;Key_Scan[1]=1; break;
case 0x4000: KeyVal=9;Key_Scan[1]=1; break;
case 0x8000: KeyVal=13;Key_Scan[1]=0; break;
}
GPIO_Write(GPIOB,(GPIOB-》ODR & 0xf0ff | 0x0800));
switch(GPIOB-》IDR & 0xf000)
{
case 0x1000: KeyVal=15;Key_Scan[1]=0; break;
case 0x2000: KeyVal=0;Key_Scan[0]=0; break;
case 0x4000: KeyVal=16; Key_Scan[1]=0;break;
case 0x8000: KeyVal=14;Key_Scan[1]=0; break;
}
return KeyVal;
}
刷指纹
void press_FR(void)
{
SearchResult seach;
u8 ensure;
char *str;
ensure=PS_GetImage();
//SUO_Init();
LED_Init();
if(ensure==0x00)//获取图像成功
{
ensure=PS_GenChar(CharBuffer1);
if(ensure==0x00) //生成特征成功
{
ensure=PS_HighSpeedSearch(CharBuffer1,0,300,&seach);
if(ensure==0x00)//搜索成功
{
LED0=1;
LED1=0;BEEP=1;delay_ms(2500);BEEP=0;SUO=0;//开锁
LCD_Fill(0,100,lcddev.width,160,WHITE);
Show_Str_Mid(0,100,“Search fingerprint success”,16,240);//
str=mymalloc(50);
sprintf(str,“Match ID:%d Match score:%d”,seach.pageID,seach.mathscore);//
Show_Str_Mid(0,140,(u8*)str,16,240);
myfree(str);
}
else
{ShowErrMessage(ensure);BEEP=1; LED0=0;SUO=1;delay_ms(3000);BEEP=0;}
}
else
{ShowErrMessage(ensure);}
delay_ms(1000);
LCD_Fill(0,100,lcddev.width,160,WHITE);
}
}
密码判断执行操作函数
//由于项目结题中,省略了部分代码,详细步骤过程如下
void do_Verify Password{
int KEY,key0[10]={0};
KEY=key();//key()返回按键值 ,无按下返回-1.
if(KEY!=-1)
{
key0[i]=KEY;
i+=1;
if(i==6)
for(i=0;i《6;i++)
{ //Key[10]为全局变量,原密码值,可调用 change_Password()改变原密码
if(key0[i]==Key1[i]){K+=1;continue;}
else {//密码输入错误,请重新输入密码,自行写代码}
}
}
if(K==6){//密码输入正确后,判断是否开锁or取消}
if(/*判断条件*/)//执行操作,返回主程序 ;
}
}
}
6.结论
如有问题,欢迎大家提出来,第一次写,难免写得很差,hhhh~。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分