標(biāo)題:
我家里的指紋模塊51單片機(jī)程序 已經(jīng)安全運(yùn)行三年了
[打印本頁(yè)]
作者:
503127655
時(shí)間:
2017-10-17 16:27
標(biāo)題:
我家里的指紋模塊51單片機(jī)程序 已經(jīng)安全運(yùn)行三年了
#include <reg52.h>
#include <intrins.h>
#define TRUE 1
unsigned char SaveNumber=0,searchnum=0;
unsigned int SearchNumber=0;
unsigned int clk0=0;
sbit relay =P1^4; //繼電器引腳
sbit buzzer=P1^5; //蜂鳴器引腳
sbit red= P2^7;//錄入模式指示燈 在板子靠近單片機(jī)處
sbit green= P2^0;//識(shí)別模式指示燈 在板子遠(yuǎn)離單片機(jī)處
sbit k1=P3^3; //模式識(shí)別
sbit k2=P3^4; //錄入一次指紋
sbit k3=P3^2; //清除所有指紋(10個(gè)指紋清除)
//變量定義:
unsigned char code tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//表:共陽(yáng)數(shù)碼管 0-9
//數(shù)碼管引腳定義:
sbit SMG_g = P1^3; //定義數(shù)碼管陽(yáng)級(jí)控制腳(個(gè)位)
//由于程序中定時(shí)器被用 我們用一位數(shù)碼管顯示 且為靜太顯示 所以推薦大家用1602或者12864液晶
bit changeflag=0,modeflag=0,clearallflag=0; //默認(rèn)為識(shí)別模式,如果為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個(gè)
//設(shè)置設(shè)備握手口令
unsigned char code STWD[16]={16,0X01 ,0Xff,0xff,0xff,0xff, 0x01,0,7,0x12,0x00,0x00,0x00,0x00,0x00,0x1a}; //回送12個(gè)
//GetImage :探測(cè)手指并從傳感器上讀入圖像
unsigned char code GIMG[14]={12, 0X01 ,0Xff,0xff,0xff,0xff, 0x01, 0,3,1,0x00,0x05}; //回送12個(gè)
//Gen Templet1 :根據(jù)原始圖像生成指紋特征1
unsigned char code GENT1[14]={13,0X01 ,0Xff,0xff,0xff,0xff,0x01,0,4,2,1,0x00,0x08}; //回送12個(gè)
//Gen Templet2 :根據(jù)原始圖像生成指紋特征2
unsigned char code GENT2[14]={13,0X01 ,0Xff,0xff,0xff,0xff,0x01,0,4,2,2,0x00,0x09}; //回送12個(gè)
//Search Finger :以CharBufferA或CharBufferB中的特征文件搜索整個(gè)或部分指紋庫(kù)
unsigned char code SEAT[18]={17, 0X01 ,0Xff,0xff,0xff,0xff, 0x01, 0,8, 4,1,0,0, 0,0x65, 0x00,0x73}; //回送16個(gè)
//Merge Templet ;將CharBufferA與CharBufferB中的特征文件合并生成模板,結(jié)果存于ModelBuffer。
unsigned char code MERG[14]={12, 0X01 ,0Xff,0xff,0xff,0xff, 0x01, 0,3,5 , 0x00,0x09};//回送12個(gè)
//Store Templet :將ModelBuffer中的文件儲(chǔ)存到flash指紋庫(kù)中
unsigned char code STOR[16]={15, 0X01 ,0Xff,0xff,0xff,0xff, 0x01, 0,6,6,2, 0x00,0x00, 0x00,0x0f}; //回送12個(gè)
//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 ;清空指紋庫(kù)
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;
unsigned char FIFO[MAX_NUMBER+1]={0};
/*********1毫秒延時(shí)程序**********/
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ā)送信息,通過(guò)查詢方式發(fā)送一個(gè)字符
{
TI = 0; //讓TI=0
SBUF = dat; //讀入數(shù)據(jù)
while(!TI); //等待發(fā)送完畢
TI = 0; //清零
}
bit Command(unsigned char *p,unsigned char MaxTime) //命令解析,給模塊發(fā)送一個(gè)命令
{
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ù)包包頭識(shí)別碼
TxdByte(0x01);//數(shù)據(jù)包包頭識(shí)別碼
i=*p; //數(shù)組的第“0”個(gè)元素、里面存放了本數(shù)組的長(zhǎng)度,把這個(gè)長(zhǎng)度給變量i,方便進(jìn)行操作
p++;
p++;
for (count=i-1; count!=1;count--) //Sent command String
{
temp=*p++; //取第個(gè)“1”個(gè)元素的內(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)容,寫(xiě)入0X00
FIFO[count-1]=0x00;
if (result)
{
result=FALSE;
start =FALSE;
stop =FALSE;
count=0;
clk0=0; //清零CL0計(jì)數(shù)
do /////////////////////////////do的內(nèi)容////////////////////////////////
{
restart0:
if (RI==1)//如果接收到數(shù)據(jù)
{
tmpdat=SBUF;//先把接收到的數(shù)據(jù)放到tmpdat中
RI=0;
if ((tmpdat==0xef)&&(start==FALSE))//這個(gè)數(shù)據(jù)為第一個(gè)傳回來(lái)的數(shù)據(jù),也就是“指令應(yīng)答”的第一個(gè)字節(jié)
{
count=0;
FIFO[0]=tmpdat;//讀入第一個(gè)應(yīng)答字節(jié)(0XEF),存在第“0”個(gè)元素中
flag=1;
goto
restart0;//可以用中斷方式進(jìn)行
}
if(flag==1)//第一個(gè)字節(jié)已經(jīng)回來(lái),所以flag==1成立
{
if(tmpdat!=0x01) //接收數(shù)據(jù)錯(cuò)誤,將重新從緩沖區(qū)接收數(shù)據(jù)
{
flag=0;//接收應(yīng)答失敗
result=FALSE;
start =FALSE;
stop=FALSE;
count=0;
goto
restart0;
}
//如果成功接收到0xef01,可以開(kāi)始接收數(shù)據(jù)
flag=2;//flag=2;表示應(yīng)答成功,可以開(kāi)始接收數(shù)據(jù)了
count++;//現(xiàn)在count=1;
FIFO[count]=tmpdat;//讀入第二個(gè)應(yīng)答字節(jié)(0X01),存在第“1”個(gè)元素中
start=TURE; //應(yīng)答成功可以開(kāi)始接收數(shù)據(jù)
goto
restart0;
}
if((flag==2)&&(start==TURE))//flag=2;表示應(yīng)答成功,可以開(kāi)始接收數(shù)據(jù)了
{
count++; //數(shù)據(jù)元素下標(biāo)++
FIFO[count]=tmpdat;//存入數(shù)據(jù)
if(count>=6)
{
checksum=FIFO[count]+checksum; //計(jì)算校驗(yàn)和
}
if(count==8)
{
package=FIFO[7]*0X100+FIFO[8]; //計(jì)算包長(zhǎng)度
stop= TURE;
}
if(stop)
{
if(count==package+8)
{
checksum=checksum-FIFO[count-1] - FIFO[count];
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) && (changeflag==0)); //由定時(shí)器以及最大接收數(shù)據(jù)來(lái)控制,保證不會(huì)在此一直循環(huán)
FifoNumber=count; //保存接收到的數(shù)據(jù)個(gè)數(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) //清空指紋庫(kù)
{
delay1ms(200);
Command(DELE_all,50); //清空指紋庫(kù)
}
unsigned char ImgProcess(unsigned char BUFID) //發(fā)獲取圖像并生成特征文件,存入BUFID中//輸入?yún)?shù)為緩沖區(qū)號(hào)
{
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];//搜索到的頁(yè)碼
//MatchScore=FIFO[12]*0x100+FIFO[13] 可以在此計(jì)算得分,從而進(jìn)行安全級(jí)別設(shè)定,本程序忽略
return 1;
}
else
{
return 0;
}
}
unsigned char search(void)//搜索指紋
{
unsigned char SearchBuf=0,i=0;
while (i<20)
{
if (ImgProcess(1)==1)//首先讀入一次指紋
{
SearchBuf=Searchfinger();//進(jìn)行指紋比對(duì),如果搜索到,返回搜索到的指紋序號(hào)
if(SearchBuf==1)
{
return SearchNumber;
}
else
{
return 255;//表示搜索到的指紋不正確
}
}
i++;
}
return 0;
}
bit savefingure(unsigned char ID)//保存指紋
{
unsigned char i=0;
//現(xiàn)在開(kāi)始進(jìn)行存儲(chǔ)指紋模板的操作
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)//此處進(jìn)行存放指紋模板的命令
{
return(1);
}
else
{
return(0);//不成功返回0
}
}
unsigned char enroll(void) //采集兩次指紋,生成1個(gè) 指紋模板
{
unsigned char temp=0,count=0;
while(1)
{
temp=ImgProcess(1); //生成特征1
if (temp==1)//生成特征文件成功
{
//采集第一個(gè)特征成功
count=0;
buzzer=1;
delay1ms(100);
buzzer=0;
break;
}
else
{
if (temp==0)//采集指紋沒(méi)有成功
{
count++;
if (count>=40)//如果采集了40次,還不成功,直接采集失敗,直接退出enroll函數(shù)----返回0
return(0);
}
}
}
delay1ms(2000);//延時(shí)2S開(kāi)始采集下一個(gè)特征
//開(kāi)始采集第二個(gè)特征
while(1)
{
temp=ImgProcess(2); //生成特征2
if (temp==1)//生成特征文件2成功
{
if ( (Command(MERG,40)&& (FifoNumber==11) && (FIFO[9]==0x00))==1 ) //合并成功返回1
{
buzzer=1;
delay1ms(100);
buzzer=0;
delay1ms(100);
buzzer=1;
delay1ms(100); //響兩聲,表示生成一個(gè)模板成功
buzzer=0;
return(1);
}
else
{
return(0);
}
}
else
{
if (temp==1)//采集指紋沒(méi)有成功
{
count++;
if (count>=25)
return(0);
}
}
}
}
void main(void)//主函數(shù)
{
unsigned char i=0;
buzzer=0;
ET0=1; //定時(shí)器0開(kāi)中斷
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波特率設(shè)置:9600
TR1=1;
TR0=1;// 開(kāi)定時(shí)器0
IT0=0;//中斷0低電平中斷
IT1=1;//中斷1低電平中斷
EX0=1;//開(kāi)中斷0
EX1=1;//開(kāi)中斷1
EA=1;
SMG_g = 0;
P0 = tab[0];//顯示0
for(i=0;i<6;i++)//開(kāi)始握手6次,如果沒(méi)有一次成功,表示模塊通信不正常。只要成功就跳出此循環(huán)
{
if(VefPSW()==1)//與模塊握手通過(guò),綠燈亮起。進(jìn)入識(shí)別模式
{
green=0;
buzzer=1;
delay1ms(300);
buzzer=0;
green=1;
red=0;
break; //成功就退出這個(gè)循環(huán)
}
}
while(1)
{
if(k2==0)//錄入一個(gè)指紋
{
delay1ms(10);
if(k2==0)//如果仍為低電平,表示按鍵有效
{
while(k2==0);//等待松手
if(VefPSW()==1&&modeflag==1&&SaveNumber<10)//與模塊握手通過(guò)
{
if(enroll()==1)//采集兩次,生成1個(gè)指紋模板成功
{
if(savefingure(SaveNumber+1)==1)//保存也成功
{
SaveNumber++;//加一次
P0=tab[SaveNumber];
delay1ms(200);
P0=0xFF;//來(lái)一次顯示,閃爍一次
delay1ms(200);
P0=tab[SaveNumber];
}
}
}
else
{
buzzer=1;
for(i=0;i<8;i++)
{
delay1ms(100);
red=~red;
}
red=0;
buzzer=0;
}
}
}
// ET0=0;
// ET1=0;
// PCON=0X02;
if(modeflag==0)//為識(shí)別模式
{
green=0;
red=1;
searchnum=search();
if(searchnum>=1&&searchnum<=162)//只能存入162個(gè)指紋
{
P0=tab[searchnum];//顯示搜索到的指紋模塊
//蜂鳴器響一聲
//繼電器打開(kāi)約 5s
relay=1;
buzzer=1;
delay1ms(100);
buzzer=0;
delay1ms(5000);
relay=0;
//ET0=0;
// ET1=0;
// PCON=0X02;
}
if(searchnum==255)//不正確的指紋 蜂鳴器響三聲
{
P0=tab[0];//顯示0
buzzer=1;delay1ms(100); buzzer=0;delay1ms(100);
buzzer=1;delay1ms(100); buzzer=0;delay1ms(100);
buzzer=1;delay1ms(100); buzzer=0;delay1ms(100);
//ET0=0;
//ET1=0;
// PCON=0X02;
}
}
if(modeflag==1)//錄入模式
{
green=1;
red=0;
}
if(clearallflag==1)
{
clearallflag=0;
Clear_All();
red=0; //紅色燈亮
green=1;
//蜂鳴器長(zhǎng)響一次,表示清除所有指紋結(jié)束
modeflag=1;//進(jìn)入錄入指紋模式
P0=tab[0];//表示沒(méi)有指紋錄入
buzzer=1;
delay1ms(800);
buzzer=0;
SaveNumber=0;
}
if(changeflag==1)
{
changeflag=0;
if(modeflag==0) //識(shí)別模式
{
green=0;
red=1;
P0=tab[0];//顯示當(dāng)前有幾個(gè) 指紋
}
else //錄入模式
{
red=0;
green=1;
P0=tab[0];//顯示0
}
}////////////////////////////while(1)結(jié)束////////////////////////////////
}
}
//////////////
void Timer0(void) interrupt 1//定時(shí)器0中斷函數(shù)
{
TL0=0x97;
TH0=0xBD;
clk0++; //延時(shí)17ms
}
void int0(void) interrupt 0//中斷0,清除所有指紋
{
if(k3==0) //清除所有指紋
{
delay1ms(10);
if(k3==0)//如果仍為低電平,表示按鍵有效
{
while(k3==0);//等待松手
clearallflag=1;
changeflag=1;
}
}
}
void int1(void) interrupt 2//中斷1,模式轉(zhuǎn)換
{
if(k1==0)//模式轉(zhuǎn)換 其中用modeflag 來(lái)標(biāo)志,默認(rèn)從第1個(gè)指紋開(kāi)始錄入
{
delay1ms(10);
if(k1==0)//如果仍為低電平,表示按鍵有效
{
while(k1==0);//等待松手
modeflag=~modeflag;//0表示錄入指紋 1表示識(shí)別指紋
changeflag=1;
// PCON=0; ///////////
// ET0=1;
// ET1=1;
}
}
}
復(fù)制代碼
作者:
admin
時(shí)間:
2017-10-17 17:38
樓主能提供下原理圖嗎?
作者:
yf11239605520
時(shí)間:
2017-10-26 10:37
有點(diǎn)看不懂
作者:
a2569808500
時(shí)間:
2017-12-11 16:32
樓主能教教我嗎,qq遠(yuǎn)程有償
作者:
6726234500
時(shí)間:
2018-9-6 17:59
有圖嗎
作者:
gnez
時(shí)間:
2019-3-14 08:38
層次分明,思維縝密,學(xué)到很多!多謝分享。!
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1