基于STM32F103+AS608指纹模块+RFID-RC522射频模块+OLED显示模块+4x4矩阵键盘+HC-05蓝牙模块发验证码----智能门禁系统

Posted Lewin~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于STM32F103+AS608指纹模块+RFID-RC522射频模块+OLED显示模块+4x4矩阵键盘+HC-05蓝牙模块发验证码----智能门禁系统相关的知识,希望对你有一定的参考价值。

0.前言

本人大二软工菜鸟一枚,大神不喜勿喷

1.功能演示

点这里功能演示

2.硬件选型

序号名称备注
1STM32F103C8T6开发板用于主控
2AS608指纹模块指纹解锁
3RFID-RC522射频模块刷卡解锁
40.96寸四针OLED显示模块(IIC)用于界面显示
54x4矩阵按键(优信电子的)按键解锁
6HC-05蓝牙模块发验证码
7继电器模拟开锁
8蜂鸣器开锁响声
9面包板拓展电源接口

3.实现功能

  1. OLED锁屏界面
    1.1 按键退出主界面
  2. 指纹解锁
  3. 刷卡解锁
  4. 按键解锁
    4.1 掩码输入密码(用 * 代替)
    4.2 按键查看输入的密码
    4.3 按键删除密码
    4.4 按键返回锁屏幕界面
    4.5 按键光标左右移
    4.6 按键删除光标前的密码(未实现)
  5. 输错三次密码锁死
    5.1 通过蓝牙模块发送验证码
  6. 解锁界面
    6.1 支持修改密码
    6.2 支持增删指纹
    6.3 个人信息
  7. 继电器、蜂鸣器模拟开锁

4.项目所涉及的技术

GPIO、中断、RTC、UART、IIC、SPI

5.部分源码

main.c

#include "stm32f10x.h"
#include "oled.h"
#include "public.h"
#include <string.h>
u8  eu8_Flag = 0;								/*全局变量串口一发生中断标志位*/
u8  eu8_what = 0;        			  /*全局变量串口一接收到的一位数据*/
extern const unsigned char BMP[];
extern u32 res;
extern u8 res_flag;
#define usart2_baund  57600			/*串口2波特率,根据指纹模块波特率更改*/
SysPara AS608Para;							/*指纹模块AS608参数*/
u16 ValidN;											/*模块内有效指纹个数*/
uint8_t Card_Type1[2];  
uint8_t Card_ID[4]; 
uint8_t Card_KEY[6] = 0xff,0xff,0xff,0xff,0xff,0xff;    //0x11,0x11,0x11,0x11,0x11,0x11;   //密码
uint8_t Card_Data[16];
uint8_t status;
uint8_t flag;
uint8_t Run_flag=1;
uint8_t Lock_flag=0;
u16 led0pwmval=0;    
u8 dir=1;
void OLED_IIC_Init(void);
void RC522_Init(void);
void AS608_Init(void);
void Finger_unlock(void);
void Swipe_unlock(void);
void Password_unlock(void);
void uart_unlock(void);
void record_fingerprints(void);
void delate_fingerprints(void);
/
u8 ensure;
char buf[4]='\\0';
char password[4]='2','4','7','8';
u8 Error;
u8 Offset;
u8 lock;
u8 fingerprint_num = 1;

int  main()

		u16 key;
		int i,j,k,m;
		int lseek = -1;
		int left_overflow = 0;
		u8 spill_status;
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	  delay_init();             //延时初始化--RTC
		USART_INIT();							//串口初始化--串口1
	  LED_Init();								//蜂鸣器继电器初始化--gpio
		uart3_init();							//蓝牙初始化--串口3
		OLED_IIC_Init();					//IIC驱动OLED初始化--软件IIC
	  RC522_Init();							//RC522初始化--硬件spi
		AS608_Init();							//AS608初始化--串口2
//主界面
	XMB:
		OLED_Clear(); 
		OLED_WriteCN(16,1,0,6);    //显示->智能门禁系统
	  OLED_WriteCN(56,4,1,1);		 //显示锁
		OLED_ShowStr(0,7,"Back",6);
		lock=0;			
		while(1)
		
			LOCK0://lock=0
			if(lock==1)
			
					OLED_Clear();
					key = 16;
			
			while(1)
			
				key = Key_Scan();
				if(key == BACK)	//主界面按下back键退出
				
						OLED_Clear();
						delay_ms(100);
				
				if(MI_OK==PcdRequest(0x52, Card_Type1))  //寻卡函数,如果成功返回MI_OK  打印多次卡号
				
						OLED_Clear();
						OLED_WriteCN(6,2,5,5);	
						delay_ms(500);
						OLED_ShowChar(86,2,'.',8);
						delay_ms(500);
						OLED_ShowChar(94,2,'.',8);
						delay_ms(500);
						OLED_ShowChar(102,2,'.',8);
						delay_ms(500);
						OLED_ShowChar(110,2,'.',8);
						while(1)
						
								uint16_t cardType = (Card_Type1[0]<<8)|Card_Type1[1];//读不同卡的类型
								printf("卡类型:(0x%04X)\\r\\n",cardType);  //"Card Type(0x%04X):"
								switch(cardType)
								
										case 0x4400:
												printf("Mifare UltraLight\\r\\n");
												break;
										case 0x0400:
												printf("Mifare One(S50)\\r\\n");
												break;
										case 0x0200:
												printf("Mifare One(S70)\\r\\n");
												break;
										case 0x0800:
												printf("Mifare Pro(X)\\r\\n");
												break;
										case 0x4403:
												printf("Mifare DESFire\\r\\n");
												break;
										default:
												printf("Unknown Card\\r\\n");
												break;
								
								status = PcdAnticoll(Card_ID);//防冲撞 如果成功返回MI_OK
								if(status != MI_OK)
								
										printf("Anticoll Error\\r\\n");
								else
								
										printf("Serial Number:%d %d %d %d\\r\\n",Card_ID[0],Card_ID[1],Card_ID[2],Card_ID[3]);
										flag=data_kz(Card_ID);
										printf("flag=%d \\r\\n",flag);
										if(flag==7||flag==8)
										
												goto LOCK1;
										
										else
										
			
								status = PcdSelect(Card_ID);  //选卡 如果成功返回MI_OK
								if(status != MI_OK)
										printf("Select Card Error\\r\\n");
								
								else
										printf("Select Card OK\\r\\n");
			
								status = PcdHalt();  //卡片进入休眠状态
								if(status != MI_OK)
										printf("PcdHalt Error\\r\\n");			
								
								else
								
										printf("PcdHalt OK\\r\\n");	
								
						
						delay_ms(100);
				
				if(PS_Sta)	 //检测PS_Sta状态,如果有手指按下
					
						OLED_Clear();
						OLED_WriteCN(6,2,4,5);	
						delay_ms(500);
						OLED_ShowChar(86,2,'.',8);
						delay_ms(500);
						OLED_ShowChar(94,2,'.',8);
						delay_ms(500);
						OLED_ShowChar(102,2,'.',8);
						delay_ms(500);
						OLED_ShowChar(110,2,'.',8);
						while(1)
						
								SearchResult seach;
								u8 ensure;
								ensure=PS_GetImage();
								if(ensure==0x00)//获取图像成功 
									

											ensure=PS_GenChar(CharBuffer1);
											if(ensure==0x00) //生成特征成功
													
														ensure=PS_HighSpeedSearch(CharBuffer1,0,AS608Para.PS_max,&seach);
														if(ensure==0x00)//搜索成功
																
																	goto LOCK1;
														
														else 
																	ShowErrMessage(ensure);					
											
											else
														ShowErrMessage(ensure);

								
	
						
						delay_ms(100);
				
				if(Error==3)	//连续三次输错密码,就会死锁,手机通过蓝牙发送验证码
				
					Error = 0;
					OLED_Clear(); 
					OLED_WriteCN(16,1,0,6);    //显示->智能门禁系统
					OLED_WriteCN(56,4,1,1);		 //显示锁
					OLED_ShowStr(0,7,"Back",6);	
					while(1)
					while(res_flag == '0');
					while(res_flag == '1')
					
						printf("res == %x\\r\\n",res);		
							if(res==0x12)
							
								res =0;
								res_flag = '0';
								goto LOCK1;
							
							else
								res =0;
								res_flag = '0';
							
						
			
				
				if(key<10)	//检测按下数字键0~9
				
						Password_unlock();
						for(i=0,j=51,spill_status=0;	key!=ACK;\\
								i=i<3?i+1:i,j=j<108?i*19+51:j)
						
								if(key<10&&spill_status==0)
								
									buf[i]=key+'0';
									OLED_ShowChar(j,0,'*',8);
									OLED_ShowChar(j,2,' ',6);
									if(i<3)OLED_ShowChar(j+19,2,'_',6);
									else spill_status = 1;//输入满后阻止输入
								else 
										switch(key)
										
												case CLEAR:
																			if(spill_status==0&&i>=0)
																			
																					buf[i-1]='\\0';
																					if(i>0)
																					
																							OLED_ShowChar(j-19,0,' ',8);
																							OLED_ShowChar(j-19,2,'_',6);
																							OLED_ShowChar(j,2,' ',6);
																					
																					i=i-2;
																					j=j-19*2;
																					if(i==-2)i=-1;
																			else if(spill_status==1)
																							buf[i]='\\0';
																							i-=1;
																							OLED_ShowChar(j,0,' ',8);
																							OLED_ShowChar(j,2,'_',6);
																							j=j-19*1;
																							spill_status=0;
																			
																			break;
																	
														
//																		for(;lseek<4;lseek++)
//																		
//																			if(lseek<3)
//																				buf[lseek]=buf[lseek+1];
//																			else
//																				buf[lseek]='\\0';
//																		
																	
								case 16:	i--;
													j=j-19;
													break;														
								case UP:	if(i==0)
													
														i--;
														j=j-19;
													
													if(lseek==-1)
														for(k=0;k<4;k++)
														
															if(buf[k]=='\\0'&&k!=0)
															
																OLED_ShowChar(51+k*19,2,' ',6);
    														OLED_ShowChar(51+(k-1)*19,2,'_',6);//3->2,2->1,1->0
																lseek = k-1;//k可选值1、2、3
																break;
															 
															if(buf[0]=='\\0')
															
    														OLED_ShowChar(51,2,'_',6);//0->0
																lseek = 3;
																break;
															
															if(buf[3]!='\\0')
															
																OLED_ShowChar(108,2,'_',6);//无->3
																lseek =3;
															
														//移动第一步
													else														

																OLED_ShowChar(51+lseek*19,2,' ',6);
																if(lseek==0)lseek+=4;
																OLED_ShowChar(51+(lseek-1)*19,2,'_',6);
																lseek--;

													
																						
													break;
								case DOWN:if(i==0)
													
														i--;
														j=j-19;
													
													if(lseek==-1)
														for(k=0;k<4;k++)
														
															if(buf[k]=='\\0'&&k!=3)
															
																OLED_ShowChar(51+k*19,2,' ',6);
    														OLED_ShowChar(51+(k+1)*19,2,'_',6);//0->1 1->2,2->3
																lseek = k+1;//k可选值0、1、2
																break;
															 
															if(buf[3]=='\\0')
															
    														OLED_ShowChar(108,2,'_',6);<

以上是关于基于STM32F103+AS608指纹模块+RFID-RC522射频模块+OLED显示模块+4x4矩阵键盘+HC-05蓝牙模块发验证码----智能门禁系统的主要内容,如果未能解决你的问题,请参考以下文章

基于STM32F103+AS608指纹模块+4X4矩阵按键+SIM900A发短信——智能门禁卡系统

基于STM32F103+AS608指纹模块+4X4矩阵按键+SIM900A发短信——智能门禁卡系统

基于STM32F103+AS608指纹模块+RFID-RC522射频模块+OLED显示模块+4x4矩阵键盘+HC-05蓝牙模块发验证码----智能门禁系统

AS608指纹+STM32串口通信录入或删除指纹

基于STM32F103的智能门禁系统

基于STM32F103的智能门禁系统