52单片机控制指纹模块

#include <reg52.h>
#include <intrins.h>

#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<count;k++) 
	{
	    for(i=0;i<160;i++)
		{
		   ;
		} 
	}   	   
}





void TxdByte(unsigned char dat)//串口发送信息,通过查询方式发送一个字符
{
    TI = 0;		 //让TI=0
    SBUF = dat;	 //读入数据
    while(!TI);	 //等待发送完毕
    TI = 0;		 //清零
}



bit Command(unsigned char *p,unsigned char MaxTime) //命令解析,给模块发送一个命令
{
  	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);//数据包包头识别码
   	TxdByte(0x01);//数据包包头识别码
  	i=*p;         //数组的第“0”个元素、里面存放了本数组的长度,把这个长度给变量i,方便进行操作
  	p++; 
	p++;
  	for (count=i-1; count!=1;count--)  //Sent command String
  	{
 		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;	//清零CL0计数
		
       	do /do的内容
		{	
		   restart0:				
	         	if (RI==1)//如果接收到数据
		      	{ 				
			  		tmpdat=SBUF;//先把接收到的数据放到tmpdat中
	            	RI=0;
	            	if ((tmpdat==0xef)&&(start==FALSE))//这个数据为第一个传回来的数据,也就是“指令应答”的第一个字节
	            	{ 
						count=0;
				    	FIFO[0]=tmpdat;//读入第一个应答字节(0XEF),存在第“0”个元素中    
						flag=1;	
						goto 
							restart0;//可以用中断方式进行			
	             	}

					if(flag==1)//第一个字节已经回来,所以flag==1成立
					{  
						if(tmpdat!=0x01)  //接收数据错误,将重新从缓冲区接收数据
						{  	
							flag=0;//接收应答失败
							result=FALSE;
	      					start =FALSE;
	   						stop=FALSE;
	       					count=0;
							goto 
								restart0;					
						}
						//如果成功接收到0xef01,可以开始接收数据
						flag=2;//flag=2;表示应答成功,可以开始接收数据了
						count++;//现在count=1;
						FIFO[count]=tmpdat;//读入第二个应答字节(0X01),存在第“1”个元素中    
						start=TURE;	//应答成功可以开始接收数据
						    goto 
								restart0;	
					}
					                  
	             	if((flag==2)&&(start==TURE))//flag=2;表示应答成功,可以开始接收数据了
	             	{	   	  					 
				   		count++; //数据元素下标++
			            FIFO[count]=tmpdat;//存入数据
						if(count>=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;//模式发生了切换
		}	
	}	
}


  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值