|
本指紋識別設(shè)計包含資料、程序、PCB等
制作出來的實(shí)物圖如下:
IMG_4524.JPG (395.23 KB, 下載次數(shù): 16)
下載附件
2020-2-16 11:18 上傳
實(shí)物照片.JPG (21.38 KB, 下載次數(shù): 19)
下載附件
2020-2-16 11:18 上傳
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
原理圖.png (34.23 KB, 下載次數(shù): 19)
下載附件
2020-2-16 11:24 上傳
PCB圖.png (33.1 KB, 下載次數(shù): 18)
下載附件
2020-2-16 11:24 上傳
單片機(jī)源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #include"lcd1602.h"
- sbit buzzer=P2^0; //蜂鳴器 低電平打開蜂鳴器
- sbit red= P1^0; //紅色燈 表示錄入模式
- sbit green= P1^1; //綠色燈 表示識別模式
- sbit k2=P3^4; //錄入一次指紋
- sbit k1=P3^3; //模式識別轉(zhuǎn)換
- 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;
- // modeflag=0 為識別模式 modeflag=1為錄入指紋模式
- //每成功錄入一次指紋 SaveNumber++
- //////////////////////////////////////常用指令定義/////////////////////////////
- //Verify Password :驗(yàn)證設(shè)備握手口令
- unsigned char code VPWD[16]={16,0X01 ,0Xff,0xff,0xff,0xff, 0x01,0,7,0x13,0x00,0x00,0x00,0x00,0x00,0x1b}; //回送12個
- //設(shè)置設(shè)備握手口令
- 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 :根據(jù)原始圖像生成指紋特征1
- unsigned char code GENT1[14]={13,0X01 ,0Xff,0xff,0xff,0xff,0x01,0,4,2,1,0x00,0x08}; //回送12個
- //Gen Templet2 :根據(jù)原始圖像生成指紋特征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中的特征文件合并生成模板,結(jié)果存于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};
- //////////////////////////////////////常用指令定義-------結(jié)束///////////////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////宏定義////////////////////////////////////////////////////////////////////////
- #define FALSE 0
- #define TURE 1
- //狀態(tài)定義表
- #define on 1
- #define off 0
- #define MAX_NUMBER 63
- #define _Nop() _nop_()
- //////////////////////////////////////宏定義------------結(jié)束////////////////////////////////////////////////////////
- unsigned char FifoNumber=0;
- xdata unsigned char FIFO[MAX_NUMBER+1]={0};
- /*********1毫秒延時程序**********/
- void delay1ms(unsigned int t)
- {
- unsigned int i,j;
- for(i=0;i<t;i++)
- for(j=0;j<120;j++)
- ;
- }
- void TxdByte(unsigned char dat)//串口發(fā)送信息,通過查詢方式發(fā)送一個字符
- {
- TI = 0; //讓TI=0
- SBUF = dat; //讀入數(shù)據(jù)
- while(!TI); //等待發(fā)送完畢
- TI = 0; //清零
- }
- bit Command(unsigned char *p,unsigned char MaxTime) //命令解析,給模塊發(fā)送一個命令
- {
- unsigned char count=0,tmpdat=0,temp=0,i=0,package=0,flag=0,checksum=0;
-
- bit result=0, start=0,stop=0;
- TxdByte(0xef);//數(shù)據(jù)包包頭識別碼
- TxdByte(0x01);//數(shù)據(jù)包包頭識別碼
- i=*p; //數(shù)組的第“0”個元素、里面存放了本數(shù)組的長度,把這個長度給變量i,方便進(jìn)行操作
- p++;
- p++;
- for (count=i-1; count!=1;count--) //Sent command String
- {
- temp=*p++;//取第個“1”個元素的內(nèi)容,然后發(fā)送
- TxdByte(temp);//將數(shù)據(jù)發(fā)送出去
- }
- result=TURE;//發(fā)送完成,結(jié)果為真 (真為1)
- FifoNumber=0;
- for (count=MAX_NUMBER+1; count!=0; count--)//清空所有FIFO[]數(shù)組里面的內(nèi)容,寫入0X00
- FIFO[count-1]=0x00;
-
- if (result)
- {
- result=FALSE;
- start =FALSE;
- stop =FALSE;
- count=0;
- clk0=0; //清零CL0計數(shù)
-
- do /////////////////////////////do的內(nèi)容////////////////////////////////
- {
- restart0:
- if (RI==1)//如果接收到數(shù)據(jù)
- {
- tmpdat=SBUF;//先把接收到的數(shù)據(jù)放到tmpdat中
- RI=0;
- if ((tmpdat==0xef)&&(start==FALSE))//這個數(shù)據(jù)為第一個傳回來的數(shù)據(jù),也就是“指令應(yīng)答”的第一個字節(jié)
- {
- count=0;
- FIFO[0]=tmpdat;//讀入第一個應(yīng)答字節(jié)(0XEF),存在第“0”個元素中
- flag=1;
- goto
- restart0;//可以用中斷方式進(jìn)行
-
- }
- if(flag==1)//第一個字節(jié)已經(jīng)回來,所以flag==1成立
- {
- if(tmpdat!=0x01) //接收數(shù)據(jù)錯誤,將重新從緩沖區(qū)接收數(shù)據(jù)
- {
- flag=0;//接收應(yīng)答失敗
- result=FALSE;
- start =FALSE;
- stop=FALSE;
- count=0;
- goto
- restart0;
-
- }
- //如果成功接收到0xef01,可以開始接收數(shù)據(jù)
- flag=2;//flag=2;表示應(yīng)答成功,可以開始接收數(shù)據(jù)了
- count++;//現(xiàn)在count=1;
- FIFO[count]=tmpdat;//讀入第二個應(yīng)答字節(jié)(0X01),存在第“1”個元素中
- start=TURE; //應(yīng)答成功可以開始接收數(shù)據(jù)
- goto
- restart0;
- }
- if((flag==2)&&(start==TURE))//flag=2;表示應(yīng)答成功,可以開始接收數(shù)據(jù)了
- {
- count++; //數(shù)據(jù)元素下標(biāo)++
- FIFO[count]=tmpdat;//存入數(shù)據(jù)
- if(count>=6)
- {
- checksum=FIFO[count]+checksum; //計算校驗(yàn)和
- }
- if(count==8)
- {
- package=FIFO[7]*0X100+FIFO[8]; //計算包長度
- stop= TURE;
- }
- if(stop)
- {
- if(count==package+8)
- {
- checksum=checksum-FIFO[count-1];
- if(checksum!=FIFO[count]&0xff)
- result=FALSE; //校驗(yàn)失敗,置結(jié)果標(biāo)志為0
- else
- result=TURE;
- flag=0;
- break;
- }
- }
- }
- }
- }/////////////////////////////do的內(nèi)容----------------結(jié)束////////////////////////////////
-
- while ((clk0<=MaxTime)&&(count<=MAX_NUMBER)); //由定時器以及最大接收數(shù)據(jù)來控制,保證不會在此一直循環(huán)
-
- FifoNumber=count; //保存接收到的數(shù)據(jù)個數(shù)
- }
- return (result);
- }
- bit VefPSW(void)//驗(yàn)證設(shè)備握手口令,成功返回1
- {
- unsigned char count=0;
- while (1)
- {
- if(Command(VPWD,20) && (FifoNumber==11) && (FIFO[9]==0x00))
- return(1);
- count++;
- if (count>=2)//如果不成功,再驗(yàn)證一次,如果兩次不成功,返回失敗
- {
- return(0);
- }
- }
- }
- void Clear_All(void) //清空所有指紋信息,清空前首先驗(yàn)證和指紋模塊通訊是否正常
- {
- if(VefPSW()!=1)//驗(yàn)證失敗
- {
-
- }
- else //驗(yàn)證成功
- {
- Command(DELE_all,50); //清空指紋庫
- Command(DENT,20); //清空用戶記事本
- }
- }
- unsigned char ImgProcess(unsigned char BUFID) //發(fā)獲取圖像并生成特征文件,存入BUFID中//輸入?yún)?shù)為緩沖區(qū)號
- {
- 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)//搜索指紋(發(fā)送搜索命令、以及根據(jù)返回值確定是否存在)
- {
- if(Command(SEAT,60) && (FifoNumber==15) && (FIFO[9]==0x00) )
- {
- SearchNumber=FIFO[10]*0x100+FIFO[11];//搜索到的頁碼
- //MatchScore=FIFO[12]*0x100+FIFO[13] 可以在此計算得分,從而進(jìn)行安全級別設(shè)定,本程序忽略
- return 1;
- }
- else
- {
- return 0;
- }
- }
- unsigned char search(void)//搜索用戶
- {
- unsigned char SearchBuf=0,i=0;
- while (i<20)
- {
- if(modeflag==0)//在識別模式下
- {
- if (ImgProcess(1)==1)//首先讀入一次指紋
- {
- SearchBuf=Searchfinger();//進(jìn)行指紋比對,如果搜索到,返回搜索到的指紋序號
- if(SearchBuf==1) //成功搜索到指紋號
- {
- return SearchNumber;
- }
- else //如果沒有搜索到指紋號
- {
- return 255; //由于只能錄入162個指紋,這時候如果返回255表示識別錯誤,或者這個指紋沒有登記
- }
- }
- }
- else
- {
- break;
- return 0;
- }
- i++;
- }
- return 255;//這里其實(shí)是超時了,由于只能錄入162個指紋,這時候如果返回255表示識別錯誤,或者這個指紋沒有登記
- }
- bit savefingure(unsigned char ID)//保存指紋
- {
- unsigned char i=0;
- //現(xiàn)在開始進(jìn)行存儲指紋模板的操作
- for (i=0;i<16;i++) //保存指紋信息
- {
- FIFO[i]=STOR[i];
- }
- FIFO[12]=ID; //把指紋模板存放的PAGE_ID也就是FLASH的位置
- FIFO[14]=FIFO[14]+ID; //校驗(yàn)和
- if (Command(FIFO,70)==1)//不成功返回0 //此處進(jìn)行存放指紋模板的命令
- {return(1);} //成功返回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函數(shù)----返回0
- return(0);
- }
- }
- }
- //采集第一個特征成功
- count=0;
- buzzer=0;delay1ms(100); buzzer=1; //蜂鳴器提醒第一個特征采集成功
- delay1ms(2000);//延時2S開始采集下一個特征
- //開始采集第二個特征
- while(1)
- {
- temp=ImgProcess(2); //生成特征2
- if (temp==1)//生成特征文件2成功
- {
- if ( (Command(MERG,40)&& (FifoNumber==11) && (FIFO[9]==0x00))==0 ) //合并不成功返回0,成功返回1
- {
- return 0; //合并不成功
- }
- else//特征文件合并生成模板,結(jié)果存于ModelBuffer
- {
- buzzer=0;
- delay1ms(100);
- buzzer=1;
- delay1ms(100);
- buzzer=0;
- delay1ms(100); //響兩聲,表示生成一個模板成功
- buzzer=1;
- return 1; //合并成功
- }
- }
- else
- {
- count++;
- if (count>=25) return(0);
- }
- }
- }
- void shownum(unsigned char dat) //顯示指紋編號
- {
- unsigned char numdat=0;
- numdat=dat;
- GotoXY(0,1);//x,y
- Print("Finger:");
- GotoXY(0,8);//x,y
- str[0]=0x30+numdat/10;
- str[1]=0x30+numdat%10;
- Print(str);
- }
- void changeState(void)//顯示狀態(tài)轉(zhuǎn)換
- {
- if(changeflag==1) //模式識別鍵按下
- {
- GotoXY(0,0);//x,y
- if(modeflag==0)
- {
- Print(Identify);//顯示 識別模式 Indentity
- }
- else
- {
- Print(Input); //顯示 輸入模式 Input
- }
- changeflag=0;
- }
-
- }
- void main(void)//主函數(shù)
- {
- unsigned char i=0;
- ET0=1; //定時器0開中斷
- TL0=0x97; //17ms的初值
- TH0=0xBD;
- delay1ms(5);
- LcdRw=0; //只對液晶進(jìn)行寫操作,不進(jìn)行讀操作
- delay1ms(5);
- LCD_Initial();//液晶初始化
- delay1ms(5);
- GotoXY(0,0);//x,y
- Print(Identify);
- //串口初始化
- SCON=0x50; //UART方式1:8位UART; REN=1:允許接收
- PCON=0x00; //SMOD=0:波特率不加倍
- TMOD=0x21; //T1方式2,用于UART波特率
- TH1=0xFD;
- TL1=0xFD; //UART波特率設(shè)置:9600
- TR1=1;
- TR0=1;// 開定時器0
-
- IT0=0;//中斷0低電平中斷
- IT1=1;//中斷1低電平中斷
- EX0=1;//開中斷0
- EX1=1;//開中斷1
- EA=1;
-
- for(i=0;i<6;i++)//開始握手6次,如果沒有一次成功,表示模塊通信不正常。只要成功就跳出此循環(huán)
- {
- if(VefPSW())//與模塊握手通過,綠燈亮起。進(jìn)入識別模式
- {
- green=0; //讀一次
- buzzer=0;
- shownum(0);
- delay1ms(300);
- buzzer=1;
- break;
- }
- else //通信握手失敗
- {
- red=1; //紅燈亮
- green=1;
- break;
- }
- }
- while(1)
- {
-
- if(k2==0)//錄入一個指紋
- {
- delay1ms(10);
- if(k2==0)//如果仍為低電平,表示按鍵有效
- {
- while(k2==0);//等待松手
- if(VefPSW()==1&&modeflag==1&&SaveNumber<10)//與模塊握手通過
- {
- if(enroll()==1)//采集兩次,生成1個指紋模板成功
- {
- if(savefingure(SaveNumber+1)==1)//保存也成功
- {
- SaveNumber++;//加一次
- shownum(SaveNumber);
- }
-
- }
- }
- else
- {
- buzzer=0;
- for(i=0;i<8;i++)
- {
- delay1ms(100);
- red=~red;
- }
- red=0;
- buzzer=1;
- }
- }
-
- } //k2==0
- if(modeflag==0)//為識別模式
- {
- searchnum=search();
- if(searchnum>=1&&searchnum<=162)//最多只能存儲162個指紋
- {
- //顯示搜索到的指紋號
- shownum(searchnum);
-
- //蜂鳴器響一聲
- buzzer=0;
- delay1ms(100);
- buzzer=1;
- }
- if(searchnum==255)//表示放上了沒有登記的指紋或者識別錯誤
- {
- ;//用戶可以自己處理,比如顯示 指紋是非法的 或者蜂鳴器響三聲,表示錯誤等
- }
- }
- if(clearallflag==1)
- {
- clearallflag=0;
- Clear_All();
- red=0; //紅色燈亮
- green=1;
- //蜂鳴器長響一次,表示清除所有指紋結(jié)束
- modeflag=1;//進(jìn)入錄入指紋模式
- GotoXY(0,0);//x,y
- Print(Input);
- shownum(0);
- buzzer=0;
- delay1ms(800);
- buzzer=1;
- SaveNumber=0;
- }
- }////////////////////////////while(1)結(jié)束////////////////////////////////
-
- }
- void int0(void) interrupt 0//中斷0,清除所有指紋
- {
- if(k3==0) //清除所有指紋
- {
- delay1ms(10);
- if(k3==0)//如果仍為低電平,表示按鍵有效
- {
- while(k3==0);//等待松手
- clearallflag=1;
- }
- }
- }
- void Timer0(void) interrupt 1//定時器0中斷函數(shù)
- {
- TL0=0x97;
- TH0=0xBD;
- clk0++; //延時17ms
- }
- void int1(void) interrupt 2//外部中斷1,模式轉(zhuǎn)換鍵按下
- {
- if(k1==0)//模式轉(zhuǎn)換 其中用modeflag 來標(biāo)志,默認(rèn)從第1個指紋開始錄入
- {
- delay1ms(10);
- if(k1==0)//如果仍為低電平,表示按鍵有效
- {
- while(k1==0);//等待松手
- changeflag=1;//表示模式有變化,即K1鍵按下
- modeflag=~modeflag;//0表示錄入指紋 1表示識別指紋
- changeState();//看一下是不是要顯示狀態(tài)轉(zhuǎn)換
- if(modeflag==0)//根據(jù)模式改變當(dāng)前模式指示燈的顏色
- {
- green=0; red=1; //錄入指紋綠燈亮
- }
- else
- {
- red=0; green=1; //指紋識別紅燈燈亮
- }
- }
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
指紋識別.zip
(2.27 MB, 下載次數(shù): 72)
2020-2-16 11:17 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|