本帖最后由 45555mkkl 于 2016-4-3 16:38 編輯
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar SaveNumber=0,searchnum=0;
- uint SearchNumber=0;
- uint clk0=0;
- //sbit relay=P1^4;
- sbit buzzer=P2^0;
- sbit red=P1^0;
- sbit green=P1^1;
- sbit k1=P3^3; //zhuanhuan
- sbit k2=P3^4;
- sbit k3=P3^2;//qing
- bit changeflag=0,modeflag=0,clearalflag=0;
- //驗證手握指令
- uchar code VPWD[16]={16,0x01,0xff,0xff,0xff,0xff,0x01,0,7,0x13,0x00,0x00,0x00,0x00,0x00,0x1b};
- // 設置設備握口令
- uchar code STWD[16]={16,0X01,0Xff,0xff,0xff,0xff,0x01,0,7,0x12,0x00,0x00,0x00,0x00,0x00,0x1a};
- //從傳感器讀入圖片
- uchar code GIMG[14]={12,0X01,0Xff,0xff,0xff,0xff,0x01,0,3,1,0x00,0x05};
- //根據原始圖像生成指紋特征1/2
- uchar code GENT1[14]={13,0X01,0Xff,0xff,0xff,0xff,0x01,0,4,2,1,0x00,0x08};
- uchar code GENT2[14]={13,0X01,0Xff,0xff,0xff,0xff,0x01,0,4,2,2,0x00,0x09};
- //由特征文件搜索指紋庫
- uchar code SEAT[18]={17,0x01,0xff,0xff,0xff,0xff,0x01,0,8,4,1,0,0,0,0x65,0x00,0x73};
- //特征文件合成模板
- uchar code MERG[14]={12,0x01,0xff,0xff,0xff,0xff,0x01,0,3,5,0x00,0x09};
- //文保保存
- uchar code STOR[16]={15,0x01,0xff,0xff,0xff,0xff,0x01,0,6,6,2,0x00,0x00,0x00,0x0f};
- //讀取記事本
- uchar code RDNT[14]={13,0x01,0xff,0xff,0xff,0xff,0x01,0,4,0x19,0,0x00,0x1e};
- //清除記事本
- uchar 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};
- //刪除一個指紋
- uchar code DELE_one[16]={16,0X01,0Xff,0xff,0xff,0xff, 0x01, 0,7,0x0c,0x00,0x00, 0,1, 0x00,0x15};
- //清空所有指紋
- uchar 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_()
- uchar FifoNumber=0;
- uchar FIFO[MAX_NUMBER+1]={0};
- ////////12864
- #define com 0
- #define dat 1
- sbit cs =P3^7;
- sbit sid=P3^6;
- sbit sck=P3^5;
- sbit beef=P2^0;
- uchar com_data,untemp,temp;
- uchar bdata datbyte;
- sbit datbyte0=datbyte^0;
- sbit datbyte7=datbyte^7;
- void delay1ms(uint x)
- {
- uint i,j;
- for(i=0;i<x;i++)
- for(j=0;j<120;j++);
- }
- void w_12864byte(uchar byte)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- sck=0;
- byte<<=1;
- sid=CY;
- sck=1;
- }
- }
- uchar r_12864byte(void)
- {
- uchar i,temp1,temp2;
- temp1 = 0;
- temp2 = 0;
- for(i=0;i<8;i++)
- {
- temp1=temp1<<1;
- sck = 0;
- sck = 1;
- sck = 0;
- if(sid) temp1++;
- }
- for(i=0;i<8;i++)
- {
- temp2=temp2<<1;
- sck = 0;
- sck = 1;
- sck = 0;
- if(sid) temp2++;
- }
- return ((0xf0&temp1)+(0x0f&temp2));
- }
- void c_12864busy( void )
- {
- do
- w_12864byte(0xfc);
- while(0x80&r_12864byte());
- }
- void w_12864(bit dat_com,uchar byt)
- {
- uchar temp;
- if(dat_com==0)
- temp=0xf8;
- else
- temp=0xfa;
- cs=1;
- c_12864busy();
- w_12864byte(temp);
- w_12864byte(byt&0xf0);
- w_12864byte(byt<<4);
- cs=0;
- }
- void init_12864(void)
- {
- w_12864(com,0x30);
- w_12864(com,0x0c);
- w_12864(com,0x01);
- w_12864(com,0x06);
- }
- /////////////////////////////////////////////
- void TxdByte(uchar dat1)
- {
- TI=0;
- SBUF=dat1; //讀入數據
- while(!TI); //等待發送完畢
- TI=0;
- }
- bit Command(uchar *p,uchar MaxTime) //發送一個命令
- {
- uchar count=0,tmpdat=0, temp=0,i=0,package=0,flag=0,checksum=0;
- bit result=0,start=0,stop=0;
- TxdByte(0xef); //數據包包頭識別碼
- TxdByte(0x01);
- i=*p; ///
- p++;p++;
- for(count=i-1;count!=1;count--)
- {
- temp=*p++; //取第1個元素的內容,然后發送
- TxdByte(temp); //將數據發送
- }
- result=TURE; //發送完成,結果為真(1)
- FifoNumber=0;
- for(count=MAX_NUMBER+1;count!=0;count--) //清空FIFO數組里面的內容寫入0x00
- FIFO[count-1]=0x00;
- if(result)
- {
- result=FALSE;
- start=FALSE;
- stop=FALSE;
- count=0;
- clk0=0; //清零計數
- do
- {
-
- r:if(RI==1) //如果接受到數據
- {
- tmpdat=SBUF;//先把接收到的數據放到tmdat中
- RI=0;
- if((tmpdat==0xef)&&(start==FALSE)) // 第一個傳回來的數據,指令應答的第一個字節
- {
- count=0;
- FIFO[0]=tmpdat; //讀入第一個應答字節
- flag =1;
- goto r;
- }
- if(flag==1)//第一個字節已經回來
- {
- if(tmpdat!=0x01) //接收數據錯誤,將重新從緩沖區接收數據
- {
- flag=0; //接收應答失敗
- result=FALSE;
- start=FALSE;
- stop=FALSE;
- count=0;
- goto r;
- }
- //如果成功接收到0xef01,可以開始接收數據
- flag=2; //應答成功,可以接收數據了
- count++;
- FIFO[count]=tmpdat;
- start=TURE;
- goto r;
- }
- if((flag==2)&&(start==TURE))
- {
- count++; //數據元素下表++
- FIFO[count]=tmpdat;//存入數據
- if(count>=6)
- {
- checksum=FIFO[count]+checksum; //計算校驗和
- }
- if(count==8)
- {
- package=FIFO[7]*0x100+FIFO[8]; //計算包長
- stop=TURE;
- }
- if(stop)
- {
- if(count==package+8)
- {
- checksum=checksum-FIFO[count-1]-FIFO[count];
- if(checksum!=(FIFO[count]&0xff))
- result=FALSE; //校驗失敗,置結果標志為0
- else
- result=TURE;
- flag=0;
- break;
- }
- }
- }
- }
- }
- while((clk0<=MaxTime)&&(count<=MAX_NUMBER)&&(changeflag==0));//由定時器以及最大接收數據來控制,保證不會在此一直循環
- FifoNumber=count; //保存接收到的數據個樹
- }
- return result;
- }
- bit VefPSW(void) //驗證設備握手口令,成功返回1
- {
- uchar count=0;
- while(1)
- {
- if(Command(VPWD,20)&&(FifoNumber==11)&&(FIFO[9]=0x00))
- return 1;
- count++;
- if(count>=2) //如果不成功,再次驗證,如果兩次不成功,返回失敗
- return 0;
- }
- }
- void Clear_All(void) //清空指紋庫
- {
- delay1ms(200);
- Command(DELE_all,50);//清空指紋庫
- }
- uchar ImgProcess(uchar 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() //搜搜指紋(發送搜索命令,以及根據返回值確定是否存在)
- {
- 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;
- }
- }
- uchar search() //搜索指紋
- {
- uchar 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(uchar ID) //保存指紋
- {
- uchar i=0; //開始進行儲存指紋模塊的操作
- for(i=0;i<16;i++)//保存指紋信息
- {
- FIFO[i]=STOR[i];
- }
- FIFO[12]=ID; //校驗和
- FIFO[14]=FIFO[14]+ID;
- if(Command(FIFO,70)==1)//進行存放指紋模板的命令
- {
- return 1;
- }
- else
- return 0; //不成功
- }
- uchar enroll() //采集兩次指紋,生成一個指紋模板
- {
- uchar temp=0,count=0;
- while(1)
- {
- temp=ImgProcess(1);//生成特征1
- if(temp==1) //生成特征文件成功
- { //采集第一個特征成功
- count=0;
- buzzer=0;
- delay1ms(100);
- buzzer=1;
- break;
- }
- else
- {
- if(temp==0) //采集指紋沒有成功
- {
- count++;
- if(count>=40)//采集了40次,還不成功,直接采集失敗,直接退出enroll函數,返回0
- return 0;
- }
- }
- }
- delay1ms(2000);//延時2秒開始采集下一個特征
- //開始采集第二個特征
- while(1)
- {
- temp=ImgProcess(2); //生成特征2
- if(temp==1) //生成特征文件2成功
- {
- if((Command(MERG,40)&&(FifoNumber==11)&&(FIFO[9]==0x00))==1)//合并成功返回1
- {
- buzzer=0;
- delay1ms(100);
- buzzer=1;
- delay1ms(100);
- buzzer=0;
- delay1ms(100); //響兩聲表示一個模板成功
- buzzer=1;
- return 1;
- }
- else
- return 0;
- }
- else
- {
- if(temp==1)//采集指紋沒有成功
- {
- count++;
- if(count>=25)
- return 0;
- }
- }
- }
- }
- void main(void)
- {
- uchar i=0;
- init_12864();
- ET0=1; //定時器0開中斷
- TL0=0x97; //17ms的初值
- TH0=0xbd;
- SCON=0x50; //UART方式1:8位UART:REN=1:允許接收
- PCON=0x00; //SMOD=0,波特率不加倍
- TMOD=0x21; //T1方式2,用于UART波特率
- TH1=0xfd;
- TL1=0xfd; //UART波特率設置9600
- TR1=1; //開定時器
- TR0=1; //中斷0低電平中斷
- IT0=0; //中斷1低電平中斷
- IT1=1; //開中斷0
- EX0=1; //開中斷1
- EX1=1;
- EA=1;
- w_12864(com,0x90);
- w_12864(dat,0x34);
- //SMG_g=0;
- //P0=tab[0];
- for(i=0;i<6;i++)//開始握手6次,如果沒有一次成功,表示模快通信不正常,只要成功跳出循環
- {
- if(VefPSW()==1) //與模塊握手通過,綠燈亮起。進入識別模式
- {
- w_12864(com,0x90);
- w_12864(dat,0x37);
- green=0;
- buzzer=0;
- delay1ms(300);
- buzzer=1;
- green=1;
- red=0;
- break;//成功就退出這個循環
- }
- }
- while(1)
- {
- if(k2==0)//錄入一個指紋
- {
- delay1ms(10);
- if(k2==0)//如果仍為低電平,表示按鍵有效
- {
- while(k2==0); //等待松手
- if(VefPSW()==1&&modeflag==1&&SaveNumber<10)//與模塊握手通過
- {
- /* w_12864(com,0x80);
- w_12864(dat,'y');
- w_12864(dat,'e');
- w_12864(dat,'s');*/
- if(enroll()==1)//采集兩次,生成一個指紋模塊成功
- {
- if(savefingure(SaveNumber+1)==1)//保存也成功
- {
- SaveNumber++; //加一次
- //P0=tab[SaveNumber];
- delay1ms(200);
- //P0=0xff;
- delay1ms(200);
- //P0=tab[SaveNumber];
- //w_12864(com,0x90);
- //w_12864(dat,0x31);
- }
- }
- }
- else
- {
- buzzer=0;
- for(i=0;i<8;i++)
- {
- delay1ms(100);
- red=~red;
- }
- red=0;
- buzzer=1;
- //w_12864(com,0x88);
- //w_12864(dat,0x32);
- }
- }
- }
- if(modeflag==0)//為識別模式
- {
- green=0;
- red=1;
- searchnum=search();
- if(searchnum>=1&&searchnum<=162)//只能存入162個指紋
- {
- //P0=tab[searchnum];//顯示搜索到的指紋模塊
- //w_12864(com,0x87);
- //w_12864(dat,0x33);
- //relay=0;
- buzzer=0;
- delay1ms(100);
- buzzer=1;
- delay1ms(3000);
- //relay=1;
- }
- if(searchnum==255) //不正確的指紋,蜂鳴器響三聲
- {
- //P0=tab[0];//顯示
- //w_12864(com,0x86);
- //w_12864(dat,0x35);
- buzzer=0;delay1ms(100);buzzer=1;delay1ms(100);
- buzzer=0;delay1ms(100);buzzer=1;delay1ms(100);
- buzzer=0;delay1ms(100);buzzer=1;delay1ms(100);
- }
- }
- if(modeflag==1)//錄入模式
- {
- green=1;
- red=0;
- }
- if(clearalflag==1)
- {
- clearalflag=0;
- Clear_All();
- red=0;
- green=1;
- modeflag=1;//進入錄入指紋模式
- // P0=tab[0];//表示沒有指紋錄入
- //w_12864(com,0x98);
- // w_12864(dat,0x38);
- buzzer=0;
- delay1ms(800);
- buzzer=1;
- SaveNumber=0;
- }
- if(changeflag==1)
- {
- changeflag=0;
- if(modeflag==0)//識別模式
- {
- green=0;
- red=1;
- // P0=tab[0];//顯示當前幾個指紋
- //w_12864(com,0x92);
- //w_12864(dat,0x37);
- }
- else //錄入模式
- {
- red=0;
- green=1;
- // P0=tab[0]; //顯示0
- //w_12864(com,0x94);
- //w_12864(dat,0x38);
- }
- }
- }
- }
- void Timer0() interrupt 1 //定時器0中斷函數
- {
- TL0=0x97;
- TH0=0xbd;
- clk0++; //延時17ms
- }
- void int0()interrupt 0 //中斷0,清除所有指紋
- {
- if(k3==0) //清除所有指紋
- {
- delay1ms(10);
- if(k3==0)//如果仍為低電平,表示按有效
- {
- while(k3==0); //等待松手
- clearalflag=1;
- changeflag=1;
- }
- }
- }
- void int1() interrupt 2 //中斷1,模式轉換
- {
- if(k1==0) //模式轉換 其中用modeflag來標志。默認從1個指紋開始錄入
- {
- delay1ms(10);
- if(k1==0)
- {
- while(k1==0);
- modeflag=~modeflag;//0表示錄入 1表示識別指紋
- changeflag=1;
- }
- }
- }
復制代碼 |