• 【毕业设计项目】基于单片机的指纹识别系统实现 - 物联网 stm32 c51



    1 简介

    Hi,大家好,这里是丹成学长,今天向大家介绍一个学长做的单片机项目

    基于单片机的指纹识别系统实现

    大家可用于 课程设计 或 毕业设计


    单片机-嵌入式毕设选题大全及项目分享:

    https://blog.csdn.net/m0_71572576/article/details/125409052


    2 指纹识别简介

    指纹识别是世界上最先进的身份识别技术之一,目前在银行金融系统,公安案例分析、户籍管理系统、门禁、考勤都得到了成功的应用。指纹识别技术利用人类指纹的惟一性和不变性这种生理特征,将指纹作为人的一种“活的身份证”,具有独特的防伪性、方便性、可靠性、安全性等众多优点。

    在这里插入图片描述

    众所周知,IC卡、磁卡须防伪造,密码须防破译和盗用,应用指纹识别系统可告别用识别卡、口令、密码、私人印章等鉴别人的身份的传统方法,改变了以往认卡不认人的疏漏状况,其应用领域必将越来越广泛。

    所以,学长今天向大家介绍如何使用单片机实现指纹识别系统。

    3 指纹识别传感器原理

    3.1 光学指纹传感器原理

    借助光学技术采集指纹是历史最久远、使用最广泛的技术,主要是利用光的折摄和反射原理,将手指放在光学镜片上,手指在内置光源照射下,光从底部射向三棱镜,并经棱镜射出,射出的光线在手指表面指纹凹凸不平的线纹上折射的角度及反射回去的光线明暗就会不一样。

    用棱镜将其投射在电荷耦合器件上CMOS或者CCD上,进而形成脊线(指纹图像中具有一定宽度和走向的纹线)呈黑色、谷线(纹线之间的凹陷部分)呈白色的数字化的、可被指纹设备算法处理的多灰度指纹图像。

    在这里插入图片描述

    原理图
    在这里插入图片描述

    3.2 半导体指纹传感器

    这类传感器,无论是电容式或是电感式,其原理类似,在一块集成有成千上万半导体器件的“平板”上,手指贴在其上与其构成了电容(电感)的另一面,由于手指平面凸凹不平,凸点处和凹点处接触平板的实际距离大小就不一样,形成的电容/电感数值也就不一样,设备根据这个原理将采集到的不同的数值汇总,也就完成了指纹的采集。

    在这里插入图片描述

    3.3 电容式指纹识别传感器

    在这里插入图片描述
    原理是将电容感整合于一块芯片中,当指纹按压芯片表面时,内部电容感测器会根据指纹波峰与波谷而产生的电荷差,从而形成指纹影像。如下简图,可以把上面的凹凸认为是指纹的谷和脊,那么同传感器就会形成不同的电容差,这样传感器就可以根据这些不同的电容差画出指纹的纹理。

    4 系统设计

    这里学长使用光学指纹传感器来构建指纹识别系统。

    当指纹传感器收到指纹信息, 将通过串口给单片机发送命令, 单片机同意并接收相应的信息, 指纹传感器采集的指纹转换成 RGB 格式, 并且数据传输到单片机, 单片机通过存储在 EEPROM 中的固化程序执行大量的模式识别和图像处理相关计算, 当用户的指纹被确认,单片机将命令执行机构动作, 开关开。

    4.1 指纹识别核心技术流程

    在这里插入图片描述

    4.2 硬件结构

    在这里插入图片描述
    学长设计的,基于stm32 单片机的 指纹识别系统、由68128RAM和EEPROM芯片等构成,具有指纹录入、图像处理、指纹对比、搜索和模版储存等功能的智能型模块。它通过与之相配套的指纹传感器,可构成一个独立的指纹识别系统,或作为一个完整的外部设备。

    4.3 采集到的指纹

    在这里插入图片描述

    4.4 指纹识别算法流程

    在这里插入图片描述

    5 实现效果

    在这里插入图片描述

    6 部分实现代码

    部分源码,篇幅有限,工程较大,不放完整源码

    #include <reg52. h>
    #include <intrins. h>
    #include"lcd1602. h"
    sbit relay =P1^4; //继电器引脚
    sbit buzzer=P1^5; //蜂鸣器引脚
    sbit red= P2^7; //录入模式指示灯 在板子靠近单片机处
    sbit green= P2^0; //识别模式指示灯 在板子远离单片机处
    sbit k2=P3^4; //录入一次指纹
    sbit k1=P3^3; //模式识别转换
    sbit k3=P3^2; //清除所有指纹(10 个指纹清除)
    #define Max_User 10
    #define error 2
    unsigned char SaveNumber=0, searchnum=0;
    unsigned int  SearchNumber=0; 
    unsigned int clk0=0;
    unsigned char str[3] ={0, ' \0' , ' \0' };
    unsigned char code Identify[16]="Lock: Idenfity";
    unsigned char code Input[16] ="Lock: Input ";
    bit modeflag=0, clearallflag=0, changeflag=0;//默认为识别模式
    常用指令定义/
    //Verify Password : 验证设备握手口令
    unsigned  char  code  VPWD[16] ={16, 0X01  , 0Xff, 0xff, 0xff, 0xff,
    0x01, 0, 7, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b} ; //回送 12 个
    //设置设备握手口令
    unsigned  char  code  STWD[16] ={16, 0X01  , 0Xff, 0xff, 0xff, 0xff,
    0x01, 0, 7, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a} ; //回送 12 个
    //GetImage : 探测手指并从传感器上读入图像
    unsigned char code GIMG[14] ={12, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01,
    0, 3, 1, 0x00, 0x05}; //回送 12 个
    //Gen Templet1 : 根据原始图像生成指纹特征 1
    unsigned  char  code
    GENT1[14] ={13, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01, 0, 4, 2, 1, 0x00, 0x08} ; //
    回送 12//Gen Templet2 : 根据原始图像生成指纹特征 2
    unsigned  char  code
    GENT2[14] ={13, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01, 0, 4, 2, 2, 0x00, 0x09} ; //回12//Search Finger : 以 CharBufferA 或 CharBufferB 中的特征文件搜索整
    个或部分指纹库
    unsigned char code SEAT[18] ={17, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01,
    0, 8, 4, 1, 0, 0, 0, 0x65, 0x00, 0x73} ; //回送 16 个
    //Merge Templet ; 将 CharBufferA 与 CharBufferB 中的特征文件合并生成
    模板, 结果存于 ModelBuffer。
    unsigned char code MERG[14] ={12, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01,
    0, 3, 5 , 0x00, 0x09} ;//回送 12 个
    //Store Templet : 将 ModelBuffer 中的文件储存到 flash 指纹库中
    unsigned char code STOR[16] ={15, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01,
    0, 6, 6, 2, 0x00, 0x00, 0x00, 0x0f} ; //回送 12 个
    //Read Note
    unsigned char code RDNT[14] ={13, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01,
    0, 4, 0x19, 0, 0x00, 0x1e} ;
    //Clear Note
    unsigned char code DENT[46] ={45, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01,
    0, 36, 0x18, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x3d
    } ;
    //DEL one templet
    unsigned char code DELE_one[16] ={16, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01,
    0, 7, 0x0c, 0x00, 0x00, 0, 1, 0x00, 0x15} ;
    //DEL templet ; 清空指纹库
    unsigned char code DELE_all[12] ={12, 0X01 , 0Xff, 0xff, 0xff, 0xff, 0x01, 0, 3,
    0x0d, 0x00, 0x11} ;
    常用指令定义-------结束//
    /宏定义///
    #define FALSE 0
    #define TURE 1
    //状态定义表
    #define on  1
    #define off  0
    #define MAX_NUMBER 63
    #define _Nop() _nop_()
    宏定义------------结束///
    unsigned char   FifoNumber=0;
    xdata unsigned char FIFO[MAX_NUMBER+1]={0} ;
    void Clear_All(void) //清空指纹库
    {   
    delay1ms(200) ;
     Command(DELE_all, 50) ; //清空指纹库 
    }
    unsigned char ImgProcess(unsigned char BUFID) //发获取图像并生成特征
    文件, 存入 BUFID 中//输入参数为缓冲区号
    {
    if(Command(GIMG, 89) && (FifoNumber==11) && (FIFO[9]==0x00) )
    {
      if(BUFID==1)
    {  
     if(Command(GENT1, 60) && (FifoNumber==11) && (FIFO[9] ==0x00))
    {
    return 1;
       }
    else
    {
       return 0;
    }
      }
      else if(BUFID==2)
      {
      if(Command(GENT2, 60) && (FifoNumber==11) && (FIFO[9] ==0x00) )
    {   
        return 1;
       }
    else
    {
      return 0;
    }  
      }
    }
    else
    {
    return 0;
    }
     return 0;
    }
    bit Searchfinger(void) //搜索指纹(发送搜索命令、 以及根据返回值确定是否
    存在)
    {
    if( Command(SEAT, 60) && (FifoNumber==15) && (FIFO[9] ==0x00) ) //搜
    索到指纹
    {
      SearchNumber=FIFO[10] *0x100+FIFO[11] ;//搜索到的页码
    //MatchScore=FIFO[12] *0x100+FIFO[13] 可以在此计算得分, 从而进
    行安全级别设定, 本程序忽略
     return 1;
     }
    else
    {
    return 0;
    }
    }
    unsigned char search(void) //搜索用户
    {
    unsigned char SearchBuf=0, i=0;
    while (i<20)
    {
    if (ImgProcess(1) ==1) //首先读入一次指纹
     {
    SearchBuf=Searchfinger() ;//进行指纹比对, 如果搜索到, 返
    回搜索到的指纹序号
      if(SearchBuf==1)
     {
      return SearchNumber;
    }
      else
     {
       return 255; //表示搜索到的指纹不正确
       }
     }
     i++;
    }
    return 0;
    }
    bit savefingure(unsigned char ID) //保存指纹
    {
     unsigned char i=0;
     //现在开始进行存储指纹模板的操作
    for (i=0; i<16;i++) //保存指纹信息
     {
       FIFO[i]=STOR[i] ;
      }
    FIFO[12]=ID; //把指纹模板存放的 PAGE_ID 也就是 FLASH 的位置
    FIFO[14]=FIFO[14]+ID; //校验和
    if (Command(FIFO, 70) ==1) //不成功返回 0 //此处进行存放指纹模板
    的命
     {return(1) ; }
    else
     {return(0) ; } //不成功返回 0
    }
    unsigned char enroll(void) //采集两次指纹, 生成 1 个 指纹模板
    {
    unsigned char temp=0, count=0;
    while(1)
    {
    temp=ImgProcess(1) ; //生成特征 1
     if (temp==1) //生成特征文件成功
    { 
    break;
     }
    else
    {
    if (temp==0) //采集指纹没有成功
    {
     count++;
    if (count>=40) //如果采集了 40 次, 还不成功, 直接采集失败,
    直接退出 enroll 函数----返回 0
    return(0) ;
    }
    }
    }
     //采集第一个特征成功
    .... 程序截断...
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191

    单片机-嵌入式毕设选题大全及项目分享:

    https://blog.csdn.net/m0_71572576/article/details/125409052


    6 最后

  • 相关阅读:
    undefined 与 undeclared 的区别?
    SQL游戏行业实战案例5:玩家在线分布(自定义排序,条件求和)
    作业fgets计算行数和大小
    【案例设计】配置与批量化处理外部 Texture 导入格式转换
    微信多开,张大龙-《软件方法》自测题解析018
    00后测试员摸爬滚打近一年,为是否要转行或去学软件测试的学弟们总结出了以下走心建议
    四川易点慧电子商务抖音小店:安全正规,购物新选择
    【五、接口自动化测试】5分钟掌握python + requests接口测试
    数据结构顺序表之单链表
    leetcode:6240. 树上最大得分和路径【两次dfs模拟 + 读题题 + 不要用list做py函数的参数!!】
  • 原文地址:https://blog.csdn.net/m0_71572576/article/details/125486287