#include
#include
#include " LCD12864.h " //里面定义了12864液晶的端口接法 以及 12864程序声名
//sbit relay =P1^4; //继电器引脚
sbit buzzer=P2^7; //蜂鸣器引脚
//sbit red= P3^5;//录入模式指示灯 在板子靠近单片机处
sbit green= P3^5;//识别模式指示灯 在板子远离单片机处
sbit k3=P3^2; //清除所有指纹(10个指纹清除)
sbit k1=P3^3; //模式识别
sbit k2=P3^4; //录入一次指纹
#define FALSE 0
#define TURE 1
#define MAX_NUMBER 30
#define _Nop() _nop_()
unsigned char SaveNumber=0,searchnum=0;
unsigned int SearchNumber=0,clk0=0;
bit modeflag= 0 , clearallflag=0, changeflag=0;
//默认为识别模式
//如果为1为录入指纹模式,每录入一次SaveNumber++
unsigned char strnum[4]={0};
unsigned char FifoNumber=0;
unsigned char FIFO[MAX_NUMBER+1]={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};
void delay1ms(unsigned int count) //1MS 延时子程序
{
unsigned char i=0;
unsigned int k=0;
for(k=0;k=6)
{
checksum=FIFO[count]+checksum; //计算校验和
}
if(count==8)
{
package = FIFO[7]*256 + 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;
}
}
}
}
}/do的内容----------------结束
while ((clk0<=MaxTime)&&(count<=MAX_NUMBER) && ( changeflag == 0 )); //由定时器以及最大接收数据来控制,保证不会在此一直循环
FifoNumber=count; //保存接收到的数据个数
}
return (result);
}
bit VefPSW(void)//验证设备握手口令,成功返回1
{
unsigned char 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); //清空指纹库
}
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 if(BUFID==2)
{
if(Command(GENT2,60) && (FifoNumber==11) && (FIFO[9]==0x00))
{
return 1;
}
}
else
{
;
}
}
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; //由于只有162个指纹,如果返回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);
}
return (0) ; //不成功返回0
}
unsigned char enroll(void) //采集两次指纹,生成1个 指纹模板
{
unsigned char temp=0,count=0;
delay1ms(30);
while(1)
{
temp=ImgProcess(1); //生成特征1
if ( temp == 1 )//生成特征文件成功
{
break;
}
else
{
if ( temp == 0 )//采集指纹没有成功
{
count++;
if (count>=40)//如果采集了40次,还不成功,直接采集失败,直接退出enroll函数----返回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//特征文件合并生成模板,结果存于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 delayms(int ms)
{
unsigned char j;
while(ms--)
{
for(j =0;j<120;j++);
}
}
void numshow(unsigned char num)
{
strnum[0]= num/100+48; //+48是为了转换在ASCII码 百
strnum[1]= (num%100)/10+48;//+48是为了转换在ASCII码 十
strnum[2]= num%10+48; //+48是为了转换在ASCII码 个
dprintf(3,0,"指纹号:");
dprintf(3,4,strnum);
}
void modecheck(void)
{
if(modeflag==0)
{
green=0;
// red=1;
dprintf(1,0," 识别模式 ");
}
else
{
// red=0;
green=1;
dprintf(1,0," 录入模式 ");
}
numshow(0);
}
void main(void)
{
unsigned int addra=0,i=0;
delayms(10);//等待单片机复位
PSB=0; //液晶为串口显示方式
LcmInit();
LcmClearTXT();
LcmClearBMP();
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;//中断0低电平中断
IT1=1;//中断1低电平中断
EX0=1;//开中断0
EX1=1;//开中断1
EA=1;
dprintf(0,0," 指纹识别系统 ");
for(i=0;i<6;i++)//开始握手6次,如果没有一次成功,表示模块通信不正常。只要成功就跳出此循环
{
if(VefPSW())//与模块握手通过,绿灯亮起。进入识别模式
{
dprintf(1,0," 握手成功 ");
// red=0;
buzzer=0;
delay1ms(100);
buzzer=1;
delay1ms(3000); //显示3秒握手状态
modecheck(); //显示当前是什么状态
break;
}
else
{
dprintf(1,0," 握手失败 ");
break;
}
}
while(1)
{
if( modeflag == 1 )//为录入指纹模式
{
if(k2==0)//录入一个指纹
{
delay1ms(10);
if(k2==0)//如果仍为低电平,表示按键有效
{
while(k2==0);//等待松手
if( SaveNumber<162 )//与模块握手通过
{
if(enroll()==1)//采集两次,生成1个指纹模板成功
{
if(savefingure(SaveNumber+1)==1)//保存也成功
{
SaveNumber++;//加一次
dprintf(2,0," 录入成功 ");
delay1ms(800);
dprintf(2,0," ");
numshow(SaveNumber);
}
}
else
{
dprintf(2,0," 录入失败 ");
delay1ms(800);
dprintf(2,0," ");
}
}
}
}
}
if( modeflag==0 )//为识别模式
{
searchnum=search();
if(searchnum>=1 && searchnum <= 162 )
{
numshow(searchnum);//显示搜索到的指纹
buzzer=0;delay1ms(100);buzzer=1;//蜂鸣器响三声
// relay=0;
// delay1ms(3000); relay=1;//继电器打开3秒
}
if(searchnum==255)//识别指纹失败
{
//蜂鸣器响三声
numshow(0);
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(clearallflag==1)
{
clearallflag=0;
Clear_All();
// red=0; //红色灯亮
green=1; //蜂鸣器长响一次,表示清除所有指纹结束
modeflag=1;//进入录入指纹模式
buzzer=0;
delay1ms(800);
buzzer=1;
SaveNumber=0;
numshow(0);
modecheck();
}
if( changeflag == 1 )
{
modecheck();
changeflag=0;
}
}while(1)结束
}
void Timer0(void) interrupt 1//定时器0中断函数
{
TL0=0x97;
TH0=0xBD;
clk0++; //延时17ms
}
void int0(void) interrupt 0//中断0,清除所有指纹
{
if(k3==0) //清除所有指纹
{
delay1ms(10);
if(k3==0)//如果仍为低电平,表示按键有效
{
while(k3==0);//等待松手
clearallflag=1;
}
}
}
void int1(void) interrupt 2//中断1,模式转换
{
if(k1==0)//模式转换 其中用modeflag 来标志,默认从第1个指纹开始录入
{
delay1ms(10);
if(k1==0)//如果仍为低电平,表示按键有效
{
while(k1==0);//等待松手
modeflag=~modeflag;//0表示录入指纹 1表示识别指纹
changeflag=1;//模式发生了切换
}
}
}