基於AS608與STC89C52的指紋密碼鎖

原理圖與PCB圖

首先先附上原理圖,如下圖所示。爲了方便製版,於是畫了原理圖進行PCB打板。
在這裏插入圖片描述
PCB的三維圖如下圖所示。看起來還是很不錯的。由於指紋模塊AS608的供電電壓是3.3v,大家可以買AMS1117模塊進行降壓。我沒有試過AS608接5V。大家可以試一下,如果可以用那還省事一點。
在這裏插入圖片描述


AS608模塊的介紹

錄入圖像

首先肯定是要錄入指紋的,錄入指紋的指令與詳解如下所示,我就不一 一贅述了。我直接講解我寫這個代碼的思路叭。首先可以肯定的是串口初始化,串口初始化完成之後,我們可以將包頭、芯片地址之類的生成一個不可改變的數組,通過調用數組去發送,會讓代碼看起來更容易理解一點。
在這裏插入圖片描述

生成特徵

在這裏插入圖片描述

對比兩個指紋

我的程序裏並沒有用到,所以導致錄入指紋的時候會出現同一個手指錄了兩個不同指紋。我想應該是沒有比對的原因。
在這裏插入圖片描述

搜索指紋

搜索指紋,由於AS608有內部flash,所以可以存好多枚指紋,於是大家在掃描指紋開鎖的時候,可以採用搜索指紋的方式,看看是否內部存有指紋進行開鎖。
在這裏插入圖片描述

合成模板

將錄入的指紋合成特徵模板
在這裏插入圖片描述
大概關鍵的指令就這些。

24C02的代碼

另外在附錄一下24C02的代碼,大家可以借鑑學習一下。

/*************************************************
D羅電子設計qq:1679960378 qq:672939453
***************************************************/
#include <reg52.h>
#include <intrins.h>
#include "24C02.h"
//#include"mytype.h"

#include <24c02.h>

void nop()
{
   
   
	_nop_();
	_nop_();
}

/24C02讀寫驅動程序
void delay1(unsigned int m)
{
   
   	unsigned int n;
  	for(n=0;n<m;n++);
}

void x24c02_init()     //24C02初始化
{
   
   
	wp=0;
	scl=1;
	nop();
	sda=1;
	nop();
}

void start()        //啓動I2C總線
{
   
   
	sda=1;
	nop();
	scl=1;
	nop();
	sda=0;
	nop();
	scl=0;
	nop();
}

void stop()         //停止I2C總線
{
   
   
	sda=0;
	nop();
	scl=1;
	nop();
	sda=1;
	nop();
}

void writebyte(unsigned char j)  //寫一個字節
{
   
   
	unsigned char i,temp;
   	temp=j;
   	for (i=0;i<8;i++)
   {
   
   
	   temp=temp<<1;
	   scl=0;
	   nop();
	   sda=CY;		//temp左移時,移出的值放入了CY中
	   nop();
	   scl=1;		//待sda線上的數據穩定後,將scl拉高
	   nop();
   }
   scl=0;
   nop();
   sda=1;
   nop();
}

unsigned char readbyte()   //讀一個字節
{
   
   
   unsigned char i,j,k=0;
   scl=0; nop(); sda=1;
   for (i=0;i<8;i++)
   {
   
     
		nop(); scl=1; nop();
      	if(sda==1) 
		j=1;
      	else
		j=0;
      	k=(k<<1)|j;
	  	scl=0;
	}
   	nop();
	return(k);
}

void clock()         //I2C總線時鐘
{
   
   
   unsigned char i=0;
   scl=1;
   nop();
   while((sda==1)&&(i<255))
   	  i++;
   scl=0;
   nop();
}

從24c02的地址address中讀取一個字節數據/
unsigned char read24c02(unsigned char address)
{
   
   
   unsigned char i;
   start();
   writebyte(0xa0);
   clock();
   writebyte(address);
   clock();
   start();
   writebyte(0xa1);
   clock();
   i=readbyte();
   stop();
   delay1(100);
   return(i);
}

//向24c02的address地址中寫入一字節數據info/
void write24c02(unsigned char address,unsigned char info)
{
   
   
   start();
   writebyte(0xa0);
   clock();
   writebyte(address);
   clock();
   writebyte(info);
   clock();
   stop();
   delay1(5000); //這個延時一定要足夠長,否則會出錯。因爲24c02在從sda上取得數據後,還需要一定時間的燒錄過程。
}

12864的代碼

/*************************************************
D羅電子設計
***************************************************/
#include <reg52.h>
#include <intrins.h>
#include"12864.h"
/**************************************************************
這裏採用串行方式控制,因爲不要接數據傳輸的腳,爲了省實物焊接過程。
**************************************************************/	    
unsigned char code AC_TABLE[]={
   
   				           //座標編碼
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
};
/****************************************************************	  
              發送一個字節
*****************************************************************/
void SendByte(unsigned char Dbyte)
{
   
   
	unsigned char i;
	for(i=0;i<8;i++)
	{
   
   
		SCK = 0;
		Dbyte=Dbyte<<1;
		SID = CY;
		SCK = 1;
		SCK = 0;
	}
}
/**********************************************************
              接收一個字節
***********************************************************/

unsigned char ReceiveByte(void)
{
   
   
	unsigned char i,temp1,temp2;
	temp1=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 CheckBusy( void )
{
   
   
	do SendByte(0xfc);     //11111,RW(1),RS(0),0
	while(0x80&ReceiveByte());
}

/******************************************************************
           寫一個字節的指令
*******************************************************************/
void WriteCommand( unsigned char Cbyte )
{
   
   
	CS = 1;
	CheckBusy();
	SendByte(0xf8);          
	SendByte(0xf0&Cbyte);
	SendByte(0xf0&Cbyte<<4);
	CS = 0;
}
/*************************************************************
                 寫一個字節的數據
**************************************************************/
void WriteData( unsigned char Dbyte )
{
   
   
	CS = 1;
	CheckBusy();
	SendByte(0xfa);          //11111,RW(0),RS(1),0
	SendByte(0xf0&Dbyte);
	SendByte(0xf0&Dbyte<<4);
	CS = 0;
}

/******************************************************************
                         lcd初始化函數
*******************************************************************/
void LcmInit( void )
{
   
   
     WriteCommand(0x30);
     WriteCommand(0x03);
     WriteCommand(0x0c);
     WriteCommand(0x01);
     WriteCommand(0x06);
}

/*******************************************************************************************************
                                 設定光標函數
********************************************************************************************************/
void Location_xy_12864(unsigned char x,unsigned char y)
{
   
   
	switch(x)
	{
   
   
		case 0:
			x=0x80;break;
		case 1:
			x=0x90;break;
		case 2:
			x=0x88;break;
		case 3:
			x=0x98;break;
		default:
			x=0x80;
	}
	y=y&0x07;
	WriteCommand(0x30);
	WriteCommand(y+x);
	WriteCommand(y+x);

}
/***********************************************************************************
                  清除文本
************************************************************************************/
void LcmClearTXT( void )
{
   
   
	unsigned char i;
	WriteCommand(0x30);
	WriteCommand(0x80);
	for(i=0;i<64;i++)
	WriteData(0x20);
	Location_xy_12864(0,0);	    
}


/***********************************************************************
                      顯示字符串
***********************************************************************/
void PutStr(unsigned char row,unsigned char col,unsigned char *puts)
{
   
       
	WriteCommand(0x30);
	WriteCommand(AC_TABLE[8*row+col]);
	while(*puts != '\0')
	{
   
   
		if(col==8)
		{
   
   
			col=0;
			row++;
		}
		if(row==4) row=0;
		WriteCommand(AC_TABLE[8*row+col]);
		WriteData(*puts);
		puts++;
		if(*puts != '\0')
		{
   
   
			WriteData(*puts);
			puts++;
			col++;
		}  
	}
}

按鍵掃描

unsigned char Keycan(void)
{
   
   
 	unsigned char row,col,i;
 	P1=0xf0;
 	if((P1&0xf0)!=0xf0)
 	{
   
   
	   	delay(50);
        delay(50);
   		if((P1&0xf0)!=0xf0)
		{
   
   
    		row=P1^0xf0;          //確定行線
			i=0;
			P1=a[i];	          //精確定位
			while(i<4)
			{
   
   
	 			if((P1&0xf0)!=0xf0)
	  			{
   
   
	   				col=~(P1&0xff);	  //確定列線
	   				break;            //已定位後提前退出   
	  			}
				else 
	  			{
   
   
	   				i++;
	   				P1=a[i];
	  			}
			}
		}
		else 
		{
   
   
			return 0;
		}
		while((P1&0xf0)!=0xf0);
		return (row|col);	 		//行線與列線組合後返回
 	}
 	else 
    return 0;	         		//無鍵按下時返回0
}

void KeyDeal(unsigned char Key)
{
   
     //unsigned char n;
   if(Key!=0)
 {
   
   
		   switch(Key)
		   {
   
   
		   case 0x11: K=1; break;	 
		   case 0x21: K=2; break;  
		   case 0x41: K=3; break;  
		   case 0x81: break;       
		   case 0x12: K=4; break;
		   case 0x22: K=5; break;
		   case 0x42: K=6; break;
		   case 0x82: break;		
		   case 0x14: K=7; break;
		   case 0x24: K=8; break;
		   case 0x44: K=9; break;
		   case 0x84: break;		
		   case 0x18: break;		
		   case 0x28: K=0; break;
		   case 0x48: K=11; break;
		   case 0x88: K=34;break;		
		   default: break;
		   }
  }
}

仔細講解一下錄指紋

附上代碼。

//不可改變與可以改變的數組如下所示
unsigned char code a[]={
   
   0xFE,0xFD,0xFB,0xF7};   //按鍵掃描數組
unsigned char code FPM10A_Pack_Head[6] = {
   
   0xEF,0x01,0xFF,0xFF,0xFF,0xFF};  //協議包頭
unsigned char code FPM10A_Get_Img[6] = {
   
   0x01,0x00,0x03,0x01,0x00,0x05};    //獲得指紋圖像
unsigned char code FPM10A_Img_To_Buffer1[7]={
   
   0x01,0x00,0x04,0x02,0x01,0x00,0x08}; //將圖像放入到BUFFER1  PageId+0x07
unsigned char code FPM10A_Img_To_Buffer2[7]={
   
   0x01,0x00,0x04,0x02,0x02,0x00,0x09}; //將圖像放入到BUFFER2  PageId+0x07
unsigned char code FPM10A_Reg_Model[6]={
   
   0x01,0x00,0x03,0x05,0x00,0x09}; //將BUFFER1跟BUFFER2合成特徵模版
unsigned char code FPM10A_Search[11]={
   
   0x01,0x00,0x08,0x04,0x01,0x00,0x00,0x03,0xE7,0x00,0xF8}; //搜索指紋搜索範圍0 - 999,使用BUFFER1中的特徵碼搜索    //起始頁+頁數+校驗和
unsigned char code FPM10A_Delete_All_Model[6]={
   
   0x01,0x00,0x03,0x0d,0x00,0x11};//刪除指紋模塊裏所有的模版
volatile unsigned char FPM10A_Delete_Finger[10]={
   
   0x01,0x00,0x07,0x0c,0x00,0x00,0x00,0x01,0x00,0x15};//刪除指紋模塊裏的模版
volatile unsigned char FPM10A_Save_Finger[9]={
   
   0x01,0x00,0x06,0x06,0x02,0x00,0x0B,0x00,0x19};//將BUFFER1中的特徵碼存放到指定的位置

串口初始化代碼如下:

void UART_Init()
{
   
   
	SCON= 0x50;               //串口方式1	//REN=1; 允許接收
	PCON=0x00;                //SMOD=0
	TMOD= 0x20;               //定時器1定時方式2
	TH1= 0xFD;                //11.0592MHz  模塊默認波特率爲9600bps
	TL1= 0xFD;										 
	TR1= 1;                   //啓動定時器 
	EA=1;	
}

/***********************************************************************************************
串口發送函數
D羅電子設計qq:1679960378 qq:672939453
***********************************************************************************************/
void Uart_Send_Byte(unsigned char c)//UART Send a byte
{
   
   
	SBUF = c;
	while(!TI);		
	TI = 0;
}

unsigned char Uart_Receive_Byte()//UART Receive a byteg
{
   
   	
	unsigned char dat;
	while(!RI);	  
	RI = 0;
	dat = SBUF;
	return (dat);
}

大家還是不要看後面的註釋哈,有的是最開始就註釋了的,但是後面改了忘了修改註釋。
在添加指紋代碼之前,現將各種包頭、與接收的數據寫成函數

void FPM10A_Cmd_Send_Pack_Head(void)
{
   
   
	int i;	
	for(i=0;i<6;i++) //包頭
    {
   
   
     Uart_Send_Byte(FPM10A_Pack_Head[i]);   
    }		
}

//接收反饋數據緩衝
void FPM10A_Receive_Data(unsigned char ucLength)
{
   
   
  unsigned char i;

  for (i=0;i<ucLength;i++)
     FPM10A_RECEICE_BUFFER[i] = Uart_Receive_Byte();

}

//FINGERPRINT_獲得指紋圖像命令
void FPM10A_Cmd_Get_Img(void)
{
   
   
    unsigned char i;
    FPM10A_Cmd_Send_Pack_Head(); //發送通信協議包頭
    for(i=0;i<6;i++) //發送命令
	{
   
   
       Uart_Send_Byte(FPM10A_Get_Img[i]);
	}
}

//將圖像轉換成特徵碼存放在Buffer1中
void FINGERPRINT_Cmd_Img_To_Buffer1(void)
{
   
   
 	unsigned char i;
	FPM10A_Cmd_Send_Pack_Head(); //發送通信協議包頭      
   	for(i=0;i<7;i++)             //發送命令 將圖像轉換成 特徵碼 存放在 CHAR_buffer1
     {
   
   
      Uart_Send_Byte(FPM10A_Img_To_Buffer1[i]);
   	 }
}

//將圖像轉換成特徵碼存放在Buffer2中
void FINGERPRINT_Cmd_Img_To_Buffer2(void)
{
   
   
     unsigned char i;
     for(i=0;i<6;i++)    //發送包頭
	 {
   
   
    	Uart_Send_Byte(FPM10A_Pack_Head[i]);   
   	 }
     for(i=0;i<7;i++)   //發送命令 將圖像轉換成 特徵碼 存放在 CHAR_buffer2
      {
   
   
      	Uart_Send_Byte(FPM10A_Img_To_Buffer2[i]);
   	  }
}


//合成特徵模板
void FPM10A_Cmd_Reg_Model(void)
{
   
   
	unsigned char i;	   
	FPM10A_Cmd_Send_Pack_Head(); //發送通信協議包頭
	for(i=0;i<6;i++)
    {
   
   
		Uart_Send_Byte(FPM10A_Reg_Model[i]);   
   	}
}

再就是添加指紋函數了,添加指紋函數有如下幾步
發送包頭,發送添加指紋的指令這個函數 FPM10A_Cmd_Get_Img(void);在前文添加指紋的指令中我們發現如果返回來接收到的數據是0則接收到了指紋,如果沒有則一直掃描指紋,直到接收到。在錄入了指紋之後應該先與指紋庫比對一下,如果指紋庫中有這個指紋則不再存入。如果指紋庫中沒有這個指紋則再次按下指紋,於是將指紋存下來,此時指紋ID加1,24C02中的區域中也要存下ID值,以便掉電存儲。

/***********************************************************************************************
添加指紋函數合集
D羅電子設計qq:1679960378 qq:672939453
***********************************************************************************************/

//保存指紋
void FPM10A_Cmd_Save_Finger( unsigned int storeID )
{
   
   
	unsigned long temp = 0;
	unsigned char i;
	FPM10A_Save_Finger[5] =(storeID&0xFF00)>>8;
	FPM10A_Save_Finger[6] = (storeID&0x00FF);
	for(i=0;i<7;i++)   //計算校驗和
	{
   
   
		temp = temp + FPM10A_Save_Finger[i]; 	
	}
	FPM10A_Save_Finger[7]=(temp & 0x00FF00) >> 8; //存放校驗數據
	FPM10A_Save_Finger[8]= temp & 0x0000FF;		   
	FPM10A_Cmd_Send_Pack_Head(); //發送通信協議包頭	
	for(i=0;i<9;i++)  
	Uart_Send_Byte(FPM10A_Save_Finger[i]);      //發送命令 將圖像轉換成 特徵碼 存放在 CHAR_buffer2
    		
}

//添加指紋
void FPM10A_Add_Fingerprint()
{
   
   
	uchar IDa1,IDa2,IDa3;
	LcmClearTXT();
	PutStr(1,2,"請按手指");
    delayms(2000);
    FPM10A_Cmd_Get_Img(); //獲得指紋圖像
    FPM10A_Receive_Data(12);
	while(FPM10A_RECEICE_BUFFER[9]!=0)
	{
   
   
		FPM10A_Cmd_Get_Img(); //獲得指紋圖像
		FPM10A_Receive_Data(12);
	}
    if(FPM10A_RECEICE_BUFFER[9]==0)
	{
   
   
		FINGERPRINT_Cmd_Img_To_Buffer1();
		FPM10A_Receive_Data(12);
		FPM10A_Cmd_Search_Finger();
		FPM10A_Receive_Data(16);
		if(FPM10A_RECEICE_BUFFER[9] == 0)    //搜索是否已經存儲
		{
   
   

			PageID = FPM10A_RECEICE_BUFFER[10]*256 + FPM10A_RECEICE_BUFFER[11];
			IDa1=PageID/100;
			IDa2=PageID/10%10;
			IDa3=PageID%10;
			LcmClearTXT();
			PutStr(0,1,"該指紋已存儲");
			PutStr(1,1,"編號爲:");
			WriteCommand(0x8D); 
			WriteData(0x30+IDa1);
			WriteData(0x30+IDa2);
			WriteData(0x30+IDa3);
			PutStr(3,0,"  按任意鍵繼續"); 
            while(Keycan()==0);
		}
		if(FPM10A_RECEICE_BUFFER[9] == 9)
		{
   
   	
			LcmClearTXT();		
			PutStr(1,1,"請再次按指紋");
			FPM10A_Cmd_Get_Img(); //獲得指紋圖像
		    FPM10A_Receive_Data(12);
			if(FPM10A_RECEICE_BUFFER[9] == 0)
			{
   
   
				FINGERPRINT_Cmd_Img_To_Buffer2();
				FPM10A_Receive_Data(12);
				FPM10A_Cmd_Reg_Model();
			    FPM10A_Receive_Data(12);
			    IDa1=PageID/100;
			    IDa2=PageID/10%10;
			    IDa3=PageID%10;
			    LcmClearTXT();
			    PutStr(1,1,"指紋採集成功");
			    PutStr(2,1,"編號爲:");
			    WriteCommand(0x8D); 
			    WriteData(0x30+IDa1);
			    WriteData(0x30+IDa2);
			    WriteData(0x30+IDa3);
			    delay(1000);
				write24c02(116,PageID+1);
			    FPM10A_Cmd_Save_Finger(PageID++);
				FPM10A_Receive_Data(12);				
			}
		}
	    PutStr(3,0,"  按任意鍵繼續"); 
	    while(Keycan()==0);
	}
	LcmClearTXT();
}

由於篇幅關係,只介紹錄入指紋的代碼,但是其餘代碼都大同小異,只要弄清楚指令就可以了。
另外將剩下的的代碼都附錄如下,以便大家學習借鑑。

/***********************************************************************************************
管理員與開鎖合集
D羅電子設計——鄧工
***********************************************************************************************/

void shuazhiwen()
{
   
    
	LcmClearTXT();
	PutStr(1,1,"請按手指開鎖");      
	FPM10A_Find_Fingerprint();
}

void gaimima()      //修改用戶密碼
{
   
   
	uchar i,j=0,mima1[6],mima2[6];
	uchar k,temp;
	LcmClearTXT();
	PutStr(1,1,"請輸入新密碼");
	for(i=0;i<6;i++)
	{
   
   
		mima1[i]=0;
	}									
	Key=Keycan();
    while(Key!=queren)
	{
   
   
	    Key=Keycan();
	    KeyDeal(Key);
	    delay(30);				                              
	    if(Key==0)
		{
   
   
			K=10;		
		}
	    if((K>=0)&&(K<=9))
	    {
   
   
			mima1[j]=K;
			if(j<6)
			{
   
   	
				WriteCommand(0x89+j);		//指定第三行顯示位置
				//WriteData(0x0f);	
				WriteData(K+0x30);
			}
			++j;
			if(j==7)
			j=6;												   
	    }   //顯示LCD12864並行顯示 
		if(K==34)		//按了刪除鍵
		{
   
   
		    if(j==0)
			{
   
   
				WriteCommand(0x89);		//指定第三行顯示位置
				WriteData(0x20);
			}
			else
			{
   
   
				--j;
				WriteCommand(0x89+j);	    //指定第三行顯示位置
				WriteData(0x20);
			}
		}
	}
	LcmClearTXT();
	j=0;
	PutStr(1,0,"請再次輸入新密碼");
	for(i=0;i<6;i++)
	{
   
   
		mima2[i]=0;
	}									
	Key=Keycan();
    while(Key!=queren)
	{
   
   
		Key=Keycan();
	    KeyDeal(Key);
	    delay(30);				                              
	    if(Key==0)
		{
   
   
			K=10;
		}
	    if((K>=0)&&(K<=9))
	    {
   
   
			mima2[j]=K;
			if(j<6)
			{
   
   		
				WriteCommand(0x89+j);		//指定第三行顯示位置
				//WriteData(0x0f);	
				WriteData(K+0x30);	
			}
	        ++j;
		    if(j==7)
	        j=6;												   
	    }   //顯示LCD12864並行顯示 
		if(K==34)		//按了刪除鍵
		{
   
   
		    if(j==0)
			{
   
   
				WriteCommand(0x89);		//指定第三行顯示位置
				WriteData(0x20);
			}
			else
			{
   
   
				--j;
				WriteCommand(0x89+j);	    //指定第三行顯示位置
				WriteData(0x20);
			}
		}
	}
	LcmClearTXT();
	if((mima1[0]==mima2[0])&&(mima1[1]==mima2[1])&&(mima1[2]==mima2[2])&&(mima1[3]==mima2[3])&&(mima1[4]==mima2[4])&&(mima1[5]==mima2[5]))
	{
   
   
		for(i=0;i<6;i++)
		mimaID[i]=mima1[i];
		for(i=0;i<6;i++)           //密碼限制在6位以內
		{
   
   
			UserPassword[i]=mima1[i]+0x30;                          	
		}
		temp=(Member-1)*100+10;	
		delayms(5);
		for(k=0;k<6;k++)
		{
   
   
			write24c02(temp,UserPassword[k]);
			delayms(10);
			temp++;
		}  
		//
		PutStr(0,1,"密碼修改成功"); 
		PutStr(3,0,"  按任意鍵繼續");
		Member=0;                              //方便下次修改密碼
		while(Keycan()==0);
	}
	else
	{
   
   
		PutStr(0,0,"  密碼修改失敗  ");
		PutStr(1,0,"兩次輸入的密碼不"); 
		PutStr(2,0,"一致,請重新操作");       
		PutStr(3,0,"  按任意鍵繼續"); 
		while(Keycan()==0);
	}
	LcmClearTXT();
}

void zhu()
{
   
     	 
    LcmClearTXT();
	PutStr(1,2,"門已打開");
   	jidianqi=0;
	delay(2500); 
	jidianqi=1;
	PutStr(3,0,"  按任意鍵繼續");
	while(Keycan()==0);
}

void guanliyuan()       //管理員
{
   
    
	uchar i,j=0,x=1;uchar Right_flag;
    LcmClearTXT();
	PutStr(1,1,"請輸入密碼:");	
	for(i=0;i<6;i++)
	{
   
   
		mima[i]=0;	
	}
	Key=Keycan();
    while(Key!=queren)
	{
   
   
		Key=Keycan();
	    KeyDeal(Key);
	    delay(30);				                              
	    if(Key==0)
		{
   
   
			K=10;		
		}
	    if((K>=0)&&(K<=9))
	    {
   
   
			mima[j]=K;
			if(j<6)
		    {
   
   	
				WriteCommand(0x89+j);		//指定第三行顯示位置
				WriteData(0x0f);	
		    }
	        ++j;
		    if(j==7)
			{
   
   
	            j=6;			
			}
												  
	    }   //顯示LCD12864並行顯示 
		if(K==34)		//按了刪除鍵
		{
   
   
			if(j==0)
			{
   
   
		        WriteCommand(0x89);		//指定第三行顯示位置
	            WriteData(0x20);
			}
			else
			{
   
   
			    --j;
		        WriteCommand(0x89+j);	    //指定第三行顯示位置
	            WriteData(0x20);
			}
		}
	}
    LcmClearTXT();
    for(i=0;i<6;i++)
    {
   
   
		UserPassword[i]=mima[i]+0x30;
	
    } 
	if(j==6)
    {
   
   
	    Right_flag=PassWord_Chack(); 
	}
	if (Right_flag==1)
	{
   
   
	  	Right_flag=0;
		Key=Keycan();
		while(Key!=tuichu)
		{
   
   	 
			PutStr(0,0,"按鍵1 : 增加指紋"); 
			PutStr(1,0,"按鍵2 : 刪去指紋");
			PutStr(2,0,"按鍵3 : 清空所有");
			PutStr(3,0,"按鍵4 : 修改密碼");
			Key=Keycan();
			KeyDeal(Key);  
			switch(K)
			{
   
   
			case 1:
				FPM10A_Add_Fingerprint(); K=8;      //僅錄一次,如果不設置K=8(可以比4大就行),會一直錄指紋
				break;
			case 2: 
				FPM10A_Delete_Fingerprint();				
				break;
			case 3:	   
				FPM10A_Delete_All_Fingerprint();  
				break;
			case 4:    
				gaimima();     
				break;
			default:   
				break;
			}
		}
    }
    else
    {
   
   

		alarm=0;
		PutStr(1,2,"密碼錯誤");
		PutStr(2,0,"  請重新操作!"); 
		PutStr(3,0,"  按任意鍵繼續");
        delay(2500);
        alarm=1;		
		while(Keycan()==0);
    }
	Key=0;
	LcmClearTXT();
}


//功能介紹
void MEMU()
{
   
   
	PutStr(0,2,"歡迎使用");
	PutStr(1,1,"D羅電子設計");
	PutStr(2,1,"qq1679960378");
	PutStr(3,1,"qq:672939453");
    Key=Keycan();
    if(k2==1)		//指紋刷機
    {
   
   
		LcmClearTXT();
		shuazhiwen();
		LcmClearTXT();
    }
	if(Key==0x81)			//管理員操作
    {
   
   
		LcmClearTXT();
		guanliyuan();
		LcmClearTXT();
    }
}	
     
void main()
{
   
    	
	UART_Init();	   //串口初始化	
	x24c02_init();     //24C02初始化
	LcmInit();	       //LCD12864初始化
	LcmClearTXT();	   //LCD12864清屏
//	write24c02(110,0x30);
//  write24c02(111,0x30);//24c02的第110到115地址單元作爲密碼存儲區
//  write24c02(112,0x30);
//	write24c02(113,0x30);
//	write24c02(114,0x30);
//	write24c02(115,0x30);
//	write24c02(116,0);
	PageID=read24c02(116);
	while(1) 
	{
   
   
		
		MEMU();
		delay(100);	  
	}	
}

附上實物圖

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
圖中所示的3.2是5v降壓到3.3的顯示屏,大家降壓可以前文提到的AMS1117模塊。


串口通訊失敗的原因

1、串口初始化有問題,如果想知道初始化是否正確,用USB TO TTL串口下載器進行調試一下,如果不對,大家再多查一下串口的資料。
2、另外,最後最重要的是,AS608模塊是有波特率的,一開始你不可能一下就能把波特率設置對。你可以自己用單片機串口初始化設置波特率。運用指紋上位機調試指紋模塊波特率,與單片機一致就可以了。

指紋上位機去我的資源裏下載,免費哈。
指紋模塊波特率設置就是與下載器普通的連接就行了。RXD----TXD,TXD-----RXD。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章