当前位置:   article > 正文

基于STM32的智能门禁系统

基于stm32的智能门禁系统

stm32F407主控芯片

RFID模块

矩阵按键模块

AS608指纹模块

SG90舵机模块

OLED显示屏模块


一、系统设计框架图

二、模块设计

RFID

寻卡

  1. //功能描述寻卡读取卡类型号
  2. //输入参数reqMode--寻卡方式
  3. // TagType--返回卡片类型
  4. // 0x4400 = Mifare_UltraLight
  5. // 0x0400 = Mifare_One(S50)
  6. // 0x0200 = Mifare_One(S70)
  7. // 0x0800 = Mifare_Pro(X)
  8. // 0x4403 = Mifare_DESFire
  9. //返 回 值成功返回MI_OK
  10. u8 MFRC522_Request(u8 reqMode, u8 *TagType)
  11. {
  12. u8 status;
  13. u16 backBits; //接收到的数据位数
  14. //
  15. Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0]
  16. TagType[0] = reqMode;
  17. status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
  18. //
  19. if ((status != MI_OK) || (backBits != 0x10))
  20. {
  21. status = MI_ERR;
  22. }
  23. //
  24. return status;
  25. }

读取卡序列号

  1. //功能描述防冲突检测读取选中卡片的卡序列号
  2. //输入参数serNum--返回4字节卡序列号,第5字节为校验字节
  3. //返 回 值成功返回MI_OK
  4. u8 MFRC522_Anticoll(u8 *serNum)
  5. {
  6. u8 status;
  7. u8 i;
  8. u8 serNumCheck=0;
  9. u16 unLen;
  10. //
  11. ClearBitMask(Status2Reg, 0x08); //TempSensclear
  12. ClearBitMask(CollReg,0x80); //ValuesAfterColl
  13. Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
  14. serNum[0] = PICC_ANTICOLL1;
  15. serNum[1] = 0x20;
  16. status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
  17. //
  18. if (status == MI_OK)
  19. {
  20. //校验卡序列号
  21. for(i=0;i<4;i++)
  22. serNumCheck^=serNum[i];
  23. //
  24. if(serNumCheck!=serNum[i])
  25. status=MI_ERR;
  26. }
  27. SetBitMask(CollReg,0x80); //ValuesAfterColl=1
  28. //
  29. return status;
  30. }

匹配卡号

  1. u8 check_ID(u8 *a, u8 *b)
  2. {
  3. int i;
  4. for(i=0;i<4;i++)
  5. {
  6. if( a[i] == b[i])
  7. continue;
  8. else
  9. return 1;
  10. }
  11. return 0;
  12. }

保存卡

  1. //保存卡号
  2. void save_id(u8 *card_numberbuf)
  3. {
  4. char Wbuf[32];
  5. int i;
  6. printf("count:%d\n",count);
  7. w25q128_sector_erase(0x001000+0x001000*count);//擦除第count+1个扇区
  8. delay_ms(500);
  9. w25q128_read_data(0x001000+0x001000*count,Wbuf,20);//读取
  10. for(i=0;i<10;i++)
  11. printf("[%#x] ",Wbuf[i]);
  12. printf("\r\n");
  13. //sprintf(Wbuf,"%x%x%x%x\0",);
  14. w25q128_write_data(0x001000+0x001000*count,(char *)card_numberbuf,4);
  15. w25q128_read_data(0x001000+0x001000*count,Wbuf,20);
  16. for(i=0;i<10;i++)
  17. printf("[%#x] ",Wbuf[i]);
  18. printf("\r\n");
  19. memset(Wbuf,0,sizeof(Wbuf));
  20. count++;
  21. }

删除卡

  1. //删除卡号
  2. void del_id(u8 *card_numberbuf)
  3. {
  4. int i,j;
  5. u8 flag;
  6. char NextID[32];
  7. for(i=0;i<count;i++)
  8. {
  9. w25q128_read_data(0x001000+0x001000*i,NextID,4);
  10. printf("card_id[%d]",i);
  11. printf("now_card_id:");
  12. flag = check_ID((u8 *)NextID,card_numberbuf);
  13. printf("比较第%d张卡\n",i+1);
  14. if(flag == 0) //遍历成功找到
  15. {
  16. printf("卡号存在!");
  17. printf("为第%d张卡\n",i+1);
  18. break;
  19. }
  20. }
  21. for(j = i;j<count;j++)
  22. {
  23. w25q128_sector_erase(0x001000+0x001000*j);
  24. w25q128_read_data(0x001000+0x001000*(j+1),NextID,4);
  25. w25q128_write_data(0x001000+0x001000*j,NextID,4);
  26. memset(NextID,0,sizeof(NextID));
  27. }
  28. count--;
  29. }

矩阵按键

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

  1. char get_keyboard()
  2. {
  3. int x,y;
  4. //设置PA0~PA3为输出,PB0~PB3为输入
  5. GPIO_SET_MODE(GPIO_Mode_OUT,1);
  6. //读取电平
  7. x = get_num(GPIO_Mode_OUT);
  8. //设置PB0~PB3为输出模式,清零
  9. GPIO_SET_MODE(GPIO_Mode_OUT,0);
  10. //设置PB0~PB3为输出模式,PA0~PA3为输入模式
  11. GPIO_SET_MODE(GPIO_Mode_IN,1);
  12. //读取电平
  13. y = get_num(GPIO_Mode_IN);
  14. //清零
  15. GPIO_SET_MODE(GPIO_Mode_IN,0);
  16. //printf("x=%d\n",x);
  17. //printf("x=%d\n",x);
  18. return arr[x][y];
  19. }

指纹

检测是否有手指按下图像

  1. //录入图像 PS_GetImage
  2. //功能:探测手指,探测到后录入指纹图像存于ImageBuffer。
  3. //模块返回确认字
  4. u8 PS_GetImage(void)
  5. {
  6. u16 temp;
  7. u8 ensure;
  8. u8 *data;
  9. SendHead();
  10. SendAddr();
  11. SendFlag(0x01);//命令包标识
  12. SendLength(0x03);
  13. Sendcmd(0x01);
  14. temp = 0x01+0x03+0x01;
  15. SendCheck(temp);
  16. data=JudgeStr(2000);
  17. if(data)
  18. ensure=data[9];
  19. else
  20. ensure=0xff;
  21. return ensure;
  22. }

刷指纹

  1. void press_FR(void)
  2. {
  3. SearchResult seach;
  4. u8 ensure;
  5. ensure=PS_GetImage();
  6. delay_ms(3000);
  7. if(ensure==0x00)//获取图像成功
  8. {
  9. printf("获取图像成功!");
  10. PFout(10) = 0;
  11. ensure=PS_GenChar(CharBuffer1);
  12. if(ensure==0x00) //生成特征成功
  13. {
  14. printf("生成特征成功!");
  15. PFout(10) = 1;
  16. ensure=PS_HighSpeedSearch(CharBuffer1,0,AS608Para.PS_max,&seach);
  17. if(ensure==0x00)//搜索成功
  18. {
  19. printf("搜索成功!");
  20. printf("刷指纹成功,此人ID:%d 匹配得分:%d\r\n",seach.pageID,seach.mathscore);
  21. opendoor();
  22. }
  23. else
  24. {
  25. printf("指纹不存在,匹配失败!");
  26. ShowErrMessage(ensure);
  27. }
  28. }
  29. else
  30. {
  31. printf("指纹识别失败\r\n");
  32. ShowErrMessage(ensure);
  33. }
  34. //PFout(10) = 1;
  35. delay_ms(2000);
  36. }
  37. AS608_flag = 0;
  38. }

录入指纹

  1. void Add_FR(void)
  2. {
  3. u8 i,ensure ,processnum=0;
  4. u16 ID;
  5. while(AS608_flag == 1)
  6. {
  7. switch (processnum)
  8. {
  9. case 0:
  10. i++;
  11. printf("请按下指纹...\r\n");
  12. OLED_Clear();
  13. OLED_ShowCHinese(0,2,48);//请
  14. OLED_ShowCHinese(18,2,49);//按
  15. OLED_ShowCHinese(36,2,50);//下
  16. OLED_ShowCHinese(54,2,40);//指
  17. OLED_ShowCHinese(72,2,41);//纹
  18. delay_xms(2000);
  19. ensure=PS_GetImage();
  20. if(ensure==0x00)
  21. {
  22. PFout(9) = 0;
  23. ensure=PS_GenChar(CharBuffer1);//生成特征
  24. PFout(9) = 1;
  25. if(ensure==0x00)
  26. {
  27. printf("指纹正常\r\n");
  28. i=0;
  29. processnum=1;//跳到第二步
  30. }else ShowErrMessage(ensure);
  31. }else ShowErrMessage(ensure);
  32. break;
  33. case 1:
  34. i++;
  35. printf("请再按一次指纹...\r\n");
  36. OLED_Clear();
  37. OLED_ShowCHinese(0,2,48);//请
  38. OLED_ShowCHinese(18,2,51);//再
  39. OLED_ShowCHinese(36,2,49);//按
  40. OLED_ShowCHinese(54,2,50);//下
  41. OLED_ShowCHinese(72,2,40);//指
  42. OLED_ShowCHinese(90,2,41);//纹
  43. ensure=PS_GetImage();
  44. if(ensure==0x00)
  45. {
  46. PFout(9) = 0;
  47. ensure=PS_GenChar(CharBuffer2);//生成特征
  48. PFout(9) = 1;
  49. if(ensure==0x00)
  50. {
  51. printf("指纹正常\r\n");
  52. i=0;
  53. processnum=2;//跳到第三步
  54. }else ShowErrMessage(ensure);
  55. }else ShowErrMessage(ensure);
  56. break;
  57. case 2:
  58. printf("对比两次指纹...\r\n");
  59. ensure=PS_Match();
  60. if(ensure==0x00)
  61. {
  62. printf("对比成功,两次指纹一样\r\n");
  63. processnum=3;//跳到第四步
  64. }
  65. else
  66. {
  67. printf("对比失败,请重新录入指纹\r\n");
  68. ShowErrMessage(ensure);
  69. i=0;
  70. processnum=0;//跳回第一步
  71. }
  72. delay_ms(1200);
  73. break;
  74. case 3:
  75. printf("生成指纹模板...\r\n");
  76. ensure=PS_RegModel();
  77. if(ensure==0x00)
  78. {
  79. printf("生成指纹模板成功\r\n");
  80. processnum=4;//跳到第五步
  81. }else {processnum=0;ShowErrMessage(ensure);}
  82. delay_ms(1200);
  83. break;
  84. case 4:
  85. ID = ID_input();//输入存储用的ID号
  86. ensure=PS_StoreChar(CharBuffer2,ID);//储存模板
  87. if(ensure==0x00)
  88. {
  89. printf("录入指纹成功\r\n");
  90. //录入失败
  91. OLED_ShowCHinese(0,2,40);//指
  92. OLED_ShowCHinese(18,2,41);//纹
  93. OLED_ShowCHinese(36,2,53);//录
  94. OLED_ShowCHinese(54,2,54);//入
  95. OLED_ShowCHinese(72,2,26);//成
  96. OLED_ShowCHinese(90,2,27);//功
  97. AS608_flag = 0;
  98. PS_ValidTempleteNum(&ValidN);//读库指纹个数
  99. printf("剩余指纹容量为%d\r\n",AS608Para.PS_max-ValidN);
  100. return ;
  101. }else {processnum=0;ShowErrMessage(ensure);}
  102. break;
  103. }
  104. delay_xms(2000);
  105. if(i==5)//超过5次没有按手指则退出
  106. {
  107. printf("--------超过5次没有按手指则退出--------\r\n");
  108. //录入失败
  109. OLED_ShowCHinese(0,2,40);//指
  110. OLED_ShowCHinese(18,2,41);//纹
  111. OLED_ShowCHinese(36,2,53);//录
  112. OLED_ShowCHinese(54,2,54);//入
  113. OLED_ShowCHinese(72,2,28);//失
  114. OLED_ShowCHinese(90,2,29);//败
  115. AS608_flag = 0;
  116. break;
  117. }
  118. }
  119. }

删除指纹

  1. void Del_FR(void)
  2. {
  3. u8 ensure;
  4. u16 num;
  5. printf("删除指纹,请输入指纹ID\r\n");
  6. OLED_Clear();
  7. OLED_ShowCHinese(0,2,55);//输
  8. OLED_ShowCHinese(18,2,56);//入
  9. OLED_ShowCHinese(36,2,40);//指
  10. OLED_ShowCHinese(54,2,41);//纹
  11. OLED_ShowCHinese(72,2,57);//编
  12. OLED_ShowCHinese(90,2,58);//号
  13. delay_ms(50);
  14. num = ID_input();//输入删除用的ID号
  15. if(num==0xFFFF)
  16. goto MENU ; //返回主页面
  17. else if(num==0xFF00)
  18. ensure=PS_Empty();//清空指纹库
  19. else
  20. ensure=PS_DeletChar(num,1);//删除单个指纹
  21. if(ensure==0)
  22. {
  23. printf("删除指纹成功\r\n");
  24. OLED_Clear();
  25. OLED_ShowCHinese(0,2,40);//指
  26. OLED_ShowCHinese(18,2,41);//纹
  27. OLED_ShowCHinese(36,2,32);//删
  28. OLED_ShowCHinese(54,2,33);//除
  29. OLED_ShowCHinese(72,2,26);//成
  30. OLED_ShowCHinese(90,2,27);//功
  31. }
  32. else
  33. ShowErrMessage(ensure);
  34. delay_ms(750);
  35. PS_ValidTempleteNum(&ValidN);//读库指纹个数
  36. printf("剩余指纹个数:%d\r\n",AS608Para.PS_max-ValidN);
  37. AS608_flag = 0;
  38. MENU:
  39. printf("返回主程序\r\n");
  40. }

三、主函数设计

  1. int main()
  2. {
  3. char buf[8];
  4. count = 0;
  5. char keyboard_buf[5] = {0};
  6. u8 ensure;
  7. //中断优先级分组
  8. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  9. //滴答定时器采用8分频
  10. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  11. //初始化LED灯
  12. led_init();
  13. //初始化按键
  14. key_nvic_init();
  15. //初始化USART1
  16. usart1_init(9600);
  17. //USART1_init(9600);
  18. //初始化USART2--蓝牙模块
  19. //usart2_init(9600);
  20. tim4_init(); //定时器 舵机
  21. tim6_init();//
  22. MFRC522_Initializtion(); //初始化MFRC522
  23. AT24C02_init();//flash缓存
  24. SPI1_init();
  25. //初始化OLED
  26. OLED_Init();
  27. //
  28. // char ch = count +'0';
  29. // w25q128_sector_erase(0x000000);
  30. // w25q128_write_data(0x000000,&ch,1);
  31. w25q128_read_data(0x000000,buf,1);
  32. printf("buf:%s\n",buf);
  33. count = buf[0] -'0';
  34. printf("count:%d\n",count);
  35. show_page();
  36. //system config
  37. //USART1_init(115200); //初始化串口,并设置波特率为115200
  38. usart2_init(57600); //初始化串口2,用于与指纹模块通讯
  39. //hardware config
  40. //PS_StaGPIO_Init(); //初始化FR读状态引脚---PA6高电平表示有指纹按下
  41. printf("与AS608模块握手....\r\n");
  42. while(PS_HandShake(&AS608Addr))//AS608模块握手
  43. {
  44. delay_ms(400);
  45. printf("未检测到模块\r\n");
  46. delay_ms(800);
  47. printf("尝试连接模块...\r\n");
  48. }
  49. printf("通讯成功!!!\r\n");
  50. printf("波特率:%d 地址:%x\r\n",57600,0XFFFFFFFF);
  51. ensure=PS_ValidTempleteNum(&ValidN);//读库指纹个数
  52. if(ensure!=0x00)
  53. {
  54. ShowErrMessage(ensure);
  55. while(1);
  56. }
  57. ensure=PS_ReadSysPara(&AS608Para); //读参数
  58. if(ensure==0x00)
  59. {
  60. printf("库容量:%d 对比等级: %d\r\n",AS608Para.PS_max-ValidN,AS608Para.PS_level);
  61. }
  62. else
  63. {
  64. ShowErrMessage(ensure);
  65. while(1);
  66. }
  67. while(1)
  68. {
  69. MFRC522Test();//测试代码
  70. //密码操作
  71. if(keyboard_flag == 1) //按下key4 标志位改变 开始获取按键值
  72. {
  73. int i = 0;
  74. while(1)
  75. {
  76. delay_xms(1000);//太快 导致按键连续检测 最后不成功 这里加上延时就行了
  77. char a=get_keyboard();
  78. printf("a:%c",a);
  79. if(a != NULL)
  80. {
  81. keyboard_buf[i] = a;
  82. i++;
  83. printf("i:%d",i);
  84. if(i == 6)
  85. break;//获取五位密码之后结束按键获取
  86. }
  87. }
  88. if(strncmp(password,keyboard_buf,5) == 0)
  89. {
  90. //密码正确 开门 显示提示信息
  91. OLED_Clear();
  92. OLED_ShowCHinese(0,4,34);//
  93. OLED_ShowCHinese(18,4,35);//
  94. OLED_ShowCHinese(36,4,36);//
  95. OLED_ShowCHinese(54,4,37);//
  96. printf("密码正确!");
  97. delay_xms(2000);
  98. opendoor();
  99. show_page();
  100. }
  101. else
  102. {
  103. OLED_Clear();
  104. OLED_ShowCHinese(0,4,34);//
  105. OLED_ShowCHinese(18,4,35);//
  106. OLED_ShowCHinese(36,4,38);//
  107. OLED_ShowCHinese(54,4,39);//
  108. printf("密码错误!");
  109. delay_xms(2000);
  110. show_page();
  111. }
  112. }
  113. keyboard_flag = 0;//密码解锁结束 标志位置为0
  114. uint32_t sec=0;
  115. //指纹检测 //按下key3
  116. while(AS608_flag == 1)
  117. {
  118. u8 press_flag = NULL;
  119. delay_ms(500);delay_ms(500);
  120. printf("sec:%d\r\n",sec++);
  121. press_flag = PS_GetImage();
  122. delay_ms(2000);
  123. printf("press_flag:%d\n",press_flag);
  124. if(press_flag == 0) //检测PS_Sta状态,如果有手指按下
  125. {
  126. press_FR();//刷指纹
  127. //AS608_flag = 0;
  128. }
  129. if(usart1_flag == 1)//串口1接收到消息
  130. {
  131. printf("usart1_buf recv:%s\r\n",usart1_buf_rx);
  132. if( usart1_buf_rx[0] == '1' )
  133. {
  134. printf("准备删除指纹\r\n");
  135. Del_FR();
  136. //AS608_flag = 0;
  137. }
  138. else if( usart1_buf_rx[0] == '2' )
  139. {
  140. printf("准备录入指纹\r\n");
  141. Add_FR();
  142. //AS608_flag = 0;
  143. }
  144. memset((void*)usart1_buf_rx,0,32);//清空缓冲区
  145. usart1_flag=0;//标志位置0
  146. usart1_cnt=0;//数组下标置0
  147. }
  148. show_page();
  149. }
  150. delay_xms(1000);
  151. }
  152. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/494950
推荐阅读
相关标签
  

闽ICP备14008679号