基于STM32的智能门禁系统

这篇具有很好参考价值的文章主要介绍了基于STM32的智能门禁系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

stm32F407主控芯片

RFID模块

矩阵按键模块

AS608指纹模块

SG90舵机模块

OLED显示屏模块文章来源地址https://www.toymoban.com/news/detail-540053.html


一、系统设计框架图

基于stm32的门禁系统设计,嵌入式硬件,stm32,Powered by 金山文档

二、模块设计

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); 
	}
	
	
	
}

 

到了这里,关于基于STM32的智能门禁系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【毕业设计】基于RFID的门禁系统 - 单片机 物联网 嵌入式 stm32

    Hi,大家好,这里是丹成学长,今天向大家介绍一个 如何使用RFID技术构建一个单片机门禁系统 基于RFID的门禁系统 大家可用于 课程设计 或 毕业设计 单片机-嵌入式毕设选题大全及项目分享: https://blog.csdn.net/m0_71572576/article/details/125409052 本篇博客,学长先向大家介绍射频识别

    2024年02月03日
    浏览(53)
  • 毕业设计 stm32人脸识别门禁系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月09日
    浏览(78)
  • FreeRTOS小项目实战------基于FreeRTOS和stm32的门禁系统

    目录 收获 系统总体框架 程序框架 具体程序实现 工程文件网盘链接 收获 学习 freertos的移植与裁剪 ,对任务间通信的认识更加深刻,加深了实时操作系统的理解,学习了as608指纹模块,rc522刷卡模块等模块的简单使用。 系统总体框架 该系统采用STM32F407ZGT6为主控芯片,在Fre

    2024年02月02日
    浏览(47)
  • 基于STM32的多功能门禁系统(AS608指纹识别、密码解锁、刷卡解锁)

    目录 一、项目功能 二、视频 三、原理图 4、材料选择 5、部分程序 1、AS608指纹解锁;可以录入、删除、验证指纹; 2、密码解锁;可以密码验证、修改密码和保存密码; 3、刷卡解锁; 4、OLED液晶显示; 基于STM32的多功能门禁系统(AS608指纹识别、密码解锁、刷卡解锁) AS608指纹

    2024年02月12日
    浏览(55)
  • stm32毕设 stm32 RFID员工打卡门禁系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(63)
  • STM32外设集 -- 人脸识别门禁系统(K210--HEX协议版本)

    人脸,指纹识别已经走进人们的生活,无疑这方便了人们的生活,也提高了安全和可靠性,所以作为未来的学习方向,我也来接触接触人脸识别(有不足之处请见谅😁) 因为这款芯片有充足的开源资料足够支撑我们学习,并将文档也很友好 相关资料连接 使用说明 (Github):

    2023年04月08日
    浏览(46)
  • 详细!基于ESP32的智能门禁系统(华为云iot+微信小程序)

    git地址:智能门禁(云IOT+微信小程序) 开关门效果 创建产品 创建产品 , 协议类型选择MQTT,数据格式选择JSON ,其他参数自定 设备注册 找到所属产品,认证类型选择密钥,单击确定后注册成功 注册成功后出现如下页面,点击保存并关闭,会自动下载好\\\"device_id\\\"和\\\"secret\\\",保

    2023年04月26日
    浏览(45)
  • 【单片机毕业设计】【mcuclub-dz-032】基于单片机的智能门禁控制系统设计

    项目名:基于单片机的门禁的设计 单片机:STM32F103C8T6 mcuclub-dz-032 功能简介: 1、通过扫码枪进行扫描二维码,当二维码识别成功,10s内需触发红外避障管,并通过红外测温模块进行测温,如果温度正常,则自动开锁,如果温度异常,则声光报警3次,锁不打开 2、通过RFID进行

    2024年01月18日
    浏览(73)
  • 物联网毕业设计 RFID智能门禁系统

    Hi,大家好,学长今天向大家介绍一个 如何使用RFID技术构建一个单片机门禁系统 基于RFID的门禁系统 大家可用于 课程设计 或 毕业设计 本篇博客,学长先向大家介绍射频识别技术的概念、 分类及工作原。然后介绍 本次使用的射频芯片 MFRC522。 RFID 系统设计可分为硬件部分和

    2024年02月07日
    浏览(44)
  • 毕业设计 RFID 单片机智能门禁系统

    Hi,大家好,学长今天向大家介绍一个 如何使用RFID技术构建一个单片机门禁系统 基于RFID的门禁系统 大家可用于 课程设计 或 毕业设计 本篇博客,学长先向大家介绍射频识别技术的概念、 分类及工作原。然后介绍 本次使用的射频芯片 MFRC522。 RFID 系统设计可分为硬件部分和

    2024年02月04日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包