基于STM32的智能门禁系统

stm32F407主控芯片

RFID模块

矩阵按键模块

AS608指纹模块

SG90舵机模块

OLED显示屏模块


一、系统设计框架图

二、模块设计

RFID

寻卡


//功能描述寻卡读取卡类型号
//输入参数reqMode--寻卡方式
//                    TagType--返回卡片类型
//                    0x4400 = Mifare_UltraLight
//                    0x0400 = Mifare_One(S50)
//                    0x0200 = Mifare_One(S70)
//                    0x0800 = Mifare_Pro(X)
//                    0x4403 = Mifare_DESFire
//返 回 值成功返回MI_OK    
u8 MFRC522_Request(u8 reqMode, u8 *TagType)
{  
    u8  status;    
    u16 backBits;   //接收到的数据位数
    //   
    Write_MFRC522(BitFramingReg, 0x07);  //TxLastBists = BitFramingReg[2..0]   
    TagType[0] = reqMode;  
    status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits); 
    // 
    if ((status != MI_OK) || (backBits != 0x10))  
    {       
        status = MI_ERR;
    }
    //  
    return status; 
}

读取卡序列号


//功能描述防冲突检测读取选中卡片的卡序列号
//输入参数serNum--返回4字节卡序列号,第5字节为校验字节
//返 回 值成功返回MI_OK
u8 MFRC522_Anticoll(u8 *serNum) 
{     
    u8  status;     
    u8  i;     
    u8  serNumCheck=0;     
    u16 unLen;
    //           
    ClearBitMask(Status2Reg, 0x08);              //TempSensclear     
    ClearBitMask(CollReg,0x80);                   //ValuesAfterColl  
    Write_MFRC522(BitFramingReg, 0x00);      //TxLastBists = BitFramingReg[2..0]
    serNum[0] = PICC_ANTICOLL1;     
    serNum[1] = 0x20;     
    status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
    //      
    if (status == MI_OK)
    {   
        //校验卡序列号   
        for(i=0;i<4;i++)   
            serNumCheck^=serNum[i];
        //
        if(serNumCheck!=serNum[i])        
            status=MI_ERR;
    }
    SetBitMask(CollReg,0x80);  //ValuesAfterColl=1
    //      
    return status;
}

匹配卡号


u8 check_ID(u8 *a, u8 *b)
{
    int i;
    for(i=0;i<4;i++)
    {
            if( a[i] == b[i])
                continue;
            else 
                return 1;    
    }
    return 0;
}

保存卡


//保存卡号
void save_id(u8 *card_numberbuf)
{
    char Wbuf[32];
    int i;
    printf("count:%d\n",count);
    w25q128_sector_erase(0x001000+0x001000*count);//擦除第count+1个扇区
    
    delay_ms(500);
    w25q128_read_data(0x001000+0x001000*count,Wbuf,20);//读取
    for(i=0;i<10;i++)
            printf("[%#x]  ",Wbuf[i]);
    printf("\r\n");
    //sprintf(Wbuf,"%x%x%x%x\0",);
    w25q128_write_data(0x001000+0x001000*count,(char *)card_numberbuf,4);
    
    w25q128_read_data(0x001000+0x001000*count,Wbuf,20);
    for(i=0;i<10;i++)
            printf("[%#x]  ",Wbuf[i]);
    printf("\r\n");
    
    memset(Wbuf,0,sizeof(Wbuf));
    count++;
}

删除卡


//删除卡号
void del_id(u8 *card_numberbuf)
{
    int i,j;
    u8 flag;
    char NextID[32];
    
    for(i=0;i<count;i++)
    {
        
        w25q128_read_data(0x001000+0x001000*i,NextID,4);
        printf("card_id[%d]",i);
        printf("now_card_id:");      
        flag = check_ID((u8 *)NextID,card_numberbuf);
        printf("比较第%d张卡\n",i+1);
        if(flag == 0)  //遍历成功找到
        {
            printf("卡号存在!");
            printf("为第%d张卡\n",i+1);
            break;
        }

    }
    for(j = i;j<count;j++)
    {
        w25q128_sector_erase(0x001000+0x001000*j);
        w25q128_read_data(0x001000+0x001000*(j+1),NextID,4);
        w25q128_write_data(0x001000+0x001000*j,NextID,4);
        memset(NextID,0,sizeof(NextID));
    }
    count--;
    
}

矩阵按键

按行按列读取,获取按键值


char get_keyboard()
{
    int x,y;
    //设置PA0~PA3为输出,PB0~PB3为输入
    GPIO_SET_MODE(GPIO_Mode_OUT,1);
    //读取电平
    x = get_num(GPIO_Mode_OUT);
    
    //设置PB0~PB3为输出模式,清零
    GPIO_SET_MODE(GPIO_Mode_OUT,0);
    
    //设置PB0~PB3为输出模式,PA0~PA3为输入模式
    GPIO_SET_MODE(GPIO_Mode_IN,1);
    //读取电平
    y = get_num(GPIO_Mode_IN);
    
    //清零
    GPIO_SET_MODE(GPIO_Mode_IN,0);
    
    //printf("x=%d\n",x);
    //printf("x=%d\n",x);
    
    return arr[x][y];    
}

指纹

检测是否有手指按下图像


//录入图像 PS_GetImage
//功能:探测手指,探测到后录入指纹图像存于ImageBuffer。 
//模块返回确认字
u8 PS_GetImage(void)
{
  u16 temp;
  u8  ensure;
    u8  *data;
    SendHead();
    SendAddr();
    SendFlag(0x01);//命令包标识
    SendLength(0x03);
    Sendcmd(0x01);
  temp =  0x01+0x03+0x01;
    SendCheck(temp);
    data=JudgeStr(2000);
    if(data)
        ensure=data[9];
    else
        ensure=0xff;
    return ensure;
}

刷指纹


void press_FR(void)
{
    SearchResult seach;
    u8 ensure;
    ensure=PS_GetImage();
    delay_ms(3000);
    if(ensure==0x00)//获取图像成功 
    {    
        printf("获取图像成功!");
        PFout(10) = 0;
        ensure=PS_GenChar(CharBuffer1);
        if(ensure==0x00) //生成特征成功
        {
            printf("生成特征成功!");    
            PFout(10) = 1;
            ensure=PS_HighSpeedSearch(CharBuffer1,0,AS608Para.PS_max,&seach);
            if(ensure==0x00)//搜索成功
            {
                printf("搜索成功!");
                printf("刷指纹成功,此人ID:%d  匹配得分:%d\r\n",seach.pageID,seach.mathscore);
                opendoor();
                
            }
            else 
            {
                printf("指纹不存在,匹配失败!");       
                ShowErrMessage(ensure);
                
            }
                                    
        }
        else
        {
            printf("指纹识别失败\r\n");
            ShowErrMessage(ensure);
        }
            
     //PFout(10) = 1;
     delay_ms(2000);
     
    }
    AS608_flag = 0;
}

录入指纹


void Add_FR(void)
{
    u8 i,ensure ,processnum=0;
    u16 ID;
    while(AS608_flag == 1)
    {
        switch (processnum)
        {
            case 0:
                i++;
                printf("请按下指纹...\r\n");
            
                OLED_Clear();
                OLED_ShowCHinese(0,2,48);//请
                OLED_ShowCHinese(18,2,49);//按
                OLED_ShowCHinese(36,2,50);//下
                OLED_ShowCHinese(54,2,40);//指
                OLED_ShowCHinese(72,2,41);//纹
                
                
                delay_xms(2000);
                ensure=PS_GetImage();
                if(ensure==0x00) 
                {
                    PFout(9) = 0;
                    ensure=PS_GenChar(CharBuffer1);//生成特征
                    PFout(9) = 1;
                    if(ensure==0x00)
                    {
                        printf("指纹正常\r\n");
                        i=0;
                        processnum=1;//跳到第二步                        
                    }else ShowErrMessage(ensure);                
                }else ShowErrMessage(ensure);                        
                break;
            
            case 1:
                i++;
                printf("请再按一次指纹...\r\n");
                
                OLED_Clear();
                OLED_ShowCHinese(0,2,48);//请
                OLED_ShowCHinese(18,2,51);//再
                OLED_ShowCHinese(36,2,49);//按
                OLED_ShowCHinese(54,2,50);//下
                OLED_ShowCHinese(72,2,40);//指
                OLED_ShowCHinese(90,2,41);//纹
                ensure=PS_GetImage();
                if(ensure==0x00) 
                {
                    PFout(9) = 0;
                    ensure=PS_GenChar(CharBuffer2);//生成特征
                    PFout(9) = 1;
                    if(ensure==0x00)
                    {
                        printf("指纹正常\r\n");
                        i=0;
                        processnum=2;//跳到第三步
                    }else ShowErrMessage(ensure);    
                }else ShowErrMessage(ensure);        
                break;

            case 2:
                printf("对比两次指纹...\r\n");
                ensure=PS_Match();
                if(ensure==0x00) 
                {
                    printf("对比成功,两次指纹一样\r\n");
                    processnum=3;//跳到第四步
                }
                else 
                {
                    printf("对比失败,请重新录入指纹\r\n");
                    ShowErrMessage(ensure);
                    i=0;
                    processnum=0;//跳回第一步        
                }
                delay_ms(1200);
                break;

            case 3:
                printf("生成指纹模板...\r\n");
                ensure=PS_RegModel();
                if(ensure==0x00) 
                {
                    printf("生成指纹模板成功\r\n");
                    processnum=4;//跳到第五步
                }else {processnum=0;ShowErrMessage(ensure);}
                delay_ms(1200);
                break;
                
            case 4:
                ID = ID_input();//输入存储用的ID号

                ensure=PS_StoreChar(CharBuffer2,ID);//储存模板
                if(ensure==0x00) 
                {    
                    printf("录入指纹成功\r\n");
                    //录入失败
                    OLED_ShowCHinese(0,2,40);//指
                    OLED_ShowCHinese(18,2,41);//纹
                    OLED_ShowCHinese(36,2,53);//录
                    OLED_ShowCHinese(54,2,54);//入
                    OLED_ShowCHinese(72,2,26);//成
                    OLED_ShowCHinese(90,2,27);//功
                    AS608_flag = 0;
                    PS_ValidTempleteNum(&ValidN);//读库指纹个数
                    printf("剩余指纹容量为%d\r\n",AS608Para.PS_max-ValidN);
                    return ;
                }else {processnum=0;ShowErrMessage(ensure);}                    
                break;                
        }
                
        delay_xms(2000);
        if(i==5)//超过5次没有按手指则退出
        {
            printf("--------超过5次没有按手指则退出--------\r\n");
            //录入失败
            OLED_ShowCHinese(0,2,40);//指
            OLED_ShowCHinese(18,2,41);//纹
            OLED_ShowCHinese(36,2,53);//录
            OLED_ShowCHinese(54,2,54);//入
            OLED_ShowCHinese(72,2,28);//失
            OLED_ShowCHinese(90,2,29);//败
            AS608_flag = 0;
            break;    
        }
        
    }
    
                    
}

删除指纹


void Del_FR(void)
{
    u8  ensure;
    u16 num;
    
    printf("删除指纹,请输入指纹ID\r\n");
    
    OLED_Clear();
    OLED_ShowCHinese(0,2,55);//输
    OLED_ShowCHinese(18,2,56);//入
    OLED_ShowCHinese(36,2,40);//指
    OLED_ShowCHinese(54,2,41);//纹
    OLED_ShowCHinese(72,2,57);//编
    OLED_ShowCHinese(90,2,58);//号
    
    
    delay_ms(50);
    
    num = ID_input();//输入删除用的ID号
    
    if(num==0xFFFF)
        goto MENU ; //返回主页面
    else if(num==0xFF00)
        ensure=PS_Empty();//清空指纹库
    else 
        ensure=PS_DeletChar(num,1);//删除单个指纹
    if(ensure==0)
    {
        printf("删除指纹成功\r\n");
        
        OLED_Clear();
        OLED_ShowCHinese(0,2,40);//指
        OLED_ShowCHinese(18,2,41);//纹
        OLED_ShowCHinese(36,2,32);//删
        OLED_ShowCHinese(54,2,33);//除
        OLED_ShowCHinese(72,2,26);//成
        OLED_ShowCHinese(90,2,27);//功 
    }
    else
        ShowErrMessage(ensure);    
    delay_ms(750);
    PS_ValidTempleteNum(&ValidN);//读库指纹个数
    printf("剩余指纹个数:%d\r\n",AS608Para.PS_max-ValidN);
    AS608_flag = 0;
  
    
MENU:    
    printf("返回主程序\r\n");
}

三、主函数设计

int main()
{
	char buf[8];
	count = 0;
	char keyboard_buf[5] = {0};
	u8 ensure;

	//中断优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//滴答定时器采用8分频
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
	
	//初始化LED灯  
	led_init();
	//初始化按键
	key_nvic_init();
	//初始化USART1
	usart1_init(9600);
	//USART1_init(9600);
	//初始化USART2--蓝牙模块
	//usart2_init(9600);
	tim4_init();	//定时器  舵机
	
	tim6_init();//
	
	MFRC522_Initializtion();			//初始化MFRC522
	
	AT24C02_init();//flash缓存
	
	SPI1_init();
	
	//初始化OLED  
	OLED_Init();
//	
//	char ch = count +'0';
//	w25q128_sector_erase(0x000000);
//	w25q128_write_data(0x000000,&ch,1);
	w25q128_read_data(0x000000,buf,1);
	printf("buf:%s\n",buf);
	count = buf[0] -'0';
	printf("count:%d\n",count);
	
	show_page();

	//system config
	//USART1_init(115200);	//初始化串口,并设置波特率为115200
	usart2_init(57600);		//初始化串口2,用于与指纹模块通讯
	
	
	//hardware config
	//PS_StaGPIO_Init();	//初始化FR读状态引脚---PA6高电平表示有指纹按下

	
	printf("与AS608模块握手....\r\n");
	while(PS_HandShake(&AS608Addr))//与AS608模块握手
	{
		delay_ms(400);
		printf("未检测到模块\r\n");
		delay_ms(800);
		printf("尝试连接模块...\r\n"); 
	}
	
	printf("通讯成功!!!\r\n"); 
	printf("波特率:%d   地址:%x\r\n",57600,0XFFFFFFFF); 
	
	ensure=PS_ValidTempleteNum(&ValidN);//读库指纹个数
	if(ensure!=0x00)
	{
		ShowErrMessage(ensure);
		while(1);
	}
	
	ensure=PS_ReadSysPara(&AS608Para);  //读参数 
	if(ensure==0x00)
	{
		printf("库容量:%d     对比等级: %d\r\n",AS608Para.PS_max-ValidN,AS608Para.PS_level);
	}
	else
	{
		ShowErrMessage(ensure);		
		while(1);
	}
	
	
	while(1)
	{
		MFRC522Test();//测试代码
		
		//密码操作
		if(keyboard_flag == 1) //按下key4 标志位改变 开始获取按键值
		{
			int i = 0;
			while(1)
			{
				delay_xms(1000);//太快 导致按键连续检测  最后不成功  这里加上延时就行了
				char a=get_keyboard();
				printf("a:%c",a);
				if(a != NULL)
				{
					keyboard_buf[i] = a;
					
					i++;
					printf("i:%d",i);
					if(i == 6)
						break;//获取五位密码之后结束按键获取
				}
			}
			if(strncmp(password,keyboard_buf,5) == 0)
			{
				//密码正确  开门 显示提示信息
				OLED_Clear();
				OLED_ShowCHinese(0,4,34);//密
				OLED_ShowCHinese(18,4,35);//码
				OLED_ShowCHinese(36,4,36);//正
				OLED_ShowCHinese(54,4,37);//确
				printf("密码正确!");
				delay_xms(2000);
				opendoor();
				show_page();
				
			}
			else
			{
				OLED_Clear();
				OLED_ShowCHinese(0,4,34);//密
				OLED_ShowCHinese(18,4,35);//码
				OLED_ShowCHinese(36,4,38);//错
				OLED_ShowCHinese(54,4,39);//误
				printf("密码错误!");
				delay_xms(2000);
				show_page();
			}
		}
		keyboard_flag = 0;//密码解锁结束  标志位置为0
		
		uint32_t sec=0;
		//指纹检测 //按下key3
		while(AS608_flag == 1)
		{
			u8 press_flag = NULL;
			delay_ms(500);delay_ms(500);
			printf("sec:%d\r\n",sec++);
			
			press_flag = PS_GetImage();
			delay_ms(2000);
			printf("press_flag:%d\n",press_flag);
			
			if(press_flag == 0)	 //检测PS_Sta状态,如果有手指按下
			{
				press_FR();//刷指纹
				//AS608_flag = 0;
			}				 

			if(usart1_flag == 1)//串口1接收到消息
			{
				printf("usart1_buf recv:%s\r\n",usart1_buf_rx);
			
				if( usart1_buf_rx[0] == '1' )
				{
					printf("准备删除指纹\r\n");
					Del_FR();
					//AS608_flag = 0;
				}
				else if( usart1_buf_rx[0] == '2' )
				{
					printf("准备录入指纹\r\n");
					Add_FR();
					//AS608_flag = 0;
					
				}
				
				memset((void*)usart1_buf_rx,0,32);//清空缓冲区
				usart1_flag=0;//标志位置0
				usart1_cnt=0;//数组下标置0
			}
			show_page();
			
		}
			
		
		delay_xms(1000); 
	}
	
	
	
}

 

  • 8
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0 WARNING

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值