【51单片机】 指纹锁+矩阵键盘+蜂鸣器+AT24C02

本文介绍了使用51单片机开发的一个指纹锁系统,结合了OLED显示、矩阵键盘输入、蜂鸣器反馈和AT24C02存储模块。系统通过AS608指纹模块进行身份验证,矩阵键盘用于密码输入,OLED显示相关信息,蜂鸣器提供操作提示。代码包括主函数、副函数、各模块接口及延时、中断配置等详细实现。
摘要由CSDN通过智能技术生成

在这里插入图片描述

【51单片机】 OLED+指纹锁+矩阵键盘+蜂鸣器+AT24C02

模块介绍

(等过百赞再讲解)

模块资料

指纹模块接口图

请添加图片描述

原理图设计

请添加图片描述

请添加图片描述

详细代码

主函数main.c

#include "Minor_function.h"
#include "uart.h"

void main()
{
	OLED_Init();//OLED
	OLED_Clear();//清理屏幕
	Xianshi_8X16(0,0,"A");
	UART_Init();//串口
	Xianshi_8X16(0,0,"B");
	Timer0Init();//计数器
	Xianshi_8X16(0,0,"C");
	UART_RX_STA=0;
	
	

	
	Minor_function();//主干函数
	
}

副函数Minor_function.h

个人代码习惯于,主函数里模块初始化,副函数进行主要部分的编写

#ifndef __Minor_function_H__
#define __Minor_function_H__

#include "Oled096.h"
#include "public.h"
#include "buzz.h"
#include "Timer0Init.h"
#include "AT24C02.h"
#include "Matrix_Key.h"
#include "as608.h"




typedef struct 
{
    unsigned char hour;//时
    unsigned char min;//分
    unsigned char sec;//秒
}Tim;



void time_change();//显示时间

void Printf_PassNum(unsigned int Num);//密码显示

void Printf_windows(unsigned char mod);//信息反馈窗口

unsigned int PassNum_initialize();//从外部加载密码

void Pass_save();//保存密码到外部

void change_password();//更改密码并且保存

void Minor_function(void);//副函数

#endif

/*

#include "Minor_function.h"
*/

副函数Minor_function.c


#include "Minor_function.h"
#include "as608.h"
//***************************************************************
extern unsigned int Pass=1234;//初始密码
extern unsigned int Key=0;//上次按键键值
extern unsigned int Num=0;//实时输入内容
extern unsigned char MOD=0X00;//模式
extern Tim Ti={23,59,30};//时间管理结构体初始化
unsigned int Location;//输入的位
u16 ValidN=0;//模块内有效指纹个数
xdata SysPara AS608Para;//指纹模块AS608参数

//***************************************************************
void time_change()//显示时间
{
	while(Ti.sec>=60){Ti.sec -=60;Ti.min++;}
	if(Ti.min>=60){Ti.min -=60;Ti.hour++;}
	if(Ti.hour>=24){Ti.hour-=24;}
	OLED_ShowNum(22+8*0,0,Ti.hour,2);
	Xianshi_16X16(22+8*2,0,8);
	OLED_ShowNum(22+8*4,0,Ti.min,2);
	Xianshi_16X16(22+8*6,0,8);
	OLED_ShowNum(22+8*8,0,Ti.sec,2);
}
//***************************************************************
void Printf_PassNum(unsigned int Num)//密码显示
{
	
	unsigned char N1=Num/1000;
	unsigned char N2=Num/100-N1*10;
	unsigned char N3=Num/10-N1*100-N2*10;
	unsigned char N4=Num/1-N1*1000-N2*100-N3*10;

	Xianshi_16X16(0,5,0);
	Xianshi_16X16(16,5,1);
	
	
	OLED_ShowNum(32,5,N1,1);
	OLED_ShowNum(40,5,N2,1);
	OLED_ShowNum(48,5,N3,1);
	OLED_ShowNum(56,5,N4,1);
	
}
//***************************************************************
void Printf_windows(unsigned char mod)//信息反馈窗口
{
	int i; 
	
	
	Xianshi_8X16(0,2,"                 ");
	
	
	switch(mod)
	{
		case 1:
			/*请输入密码*/
		
		Xianshi_8X16(0,2,"PleaseEnter");
			break;
		
		
		case 2:
			/*解锁*/
		Xianshi_8X16(0,2,"Unlock");
		Buzz_Times(1);//蜂鸣器响
		delay_ms(1000);

			break;
		
		
		case 3:
			/*错误*/
			Xianshi_16X16(0,2,2);
			Xianshi_16X16(16,2,3);
			Buzz_Times(2);//蜂鸣器响
			delay_ms(1000);

			break;
		
		
		case 4:
			/*已锁定*/
		Xianshi_8X16(0,2,"Locked:");
		for(i=15;i>0;i--)
		{
			OLED_ShowNum(8*8,2,i,2);
			delay_ms(1000);
			Num=0;
			time_change();//显示时间
		}
		Xianshi_8X16(0,2,"         ");
		Xianshi_8X16(0,2,"ReloadEnter");//重新输入
			break;
		
		
		case 5:/*识别中*/
			Xianshi_8X16(0,2,"Identifying");
			return;
		
		
		case 6:/*保存成功*/
			Xianshi_8X16(0,2,"SaveUcceed");
			break;
		
		
		
		default:/*出错*/
		Xianshi_8X16(16,2,"ERROR");
			break;
	
	
	}






}
//***************************************************************
unsigned int PassNum_initialize()//从外部加载密码
{
	
	
	unsigned char N1,N2,N3,N4;
	unsigned int Password;

	N1=AT24C02_Read(0);
	N2=AT24C02_Read(1);
	N3=AT24C02_Read(2);
	N4=AT24C02_Read(3);
	Password=N1*1000+N2*100+N3*10+N4*1;

	return Password;
}
//***************************************************************
void Pass_save()//保存密码到外部
{
	unsigned char N1=Num/1000;
	unsigned char N2=Num/100-N1*10;
	unsigned char N3=Num/10-N1*100-N2*10;
	unsigned char N4=Num/1-N1*1000-N2*100-N3*10;

		AT24C02_Write(0,N1);
		delay_ms(5);
		AT24C02_Write(1,N2);
		delay_ms(5);
		AT24C02_Write(2,N3);
		delay_ms(5);
		AT24C02_Write(3,N4);
		delay_ms(5);


}
//***************************************************************
void change_password()//更改密码并且保存
{
	
	Pass_save();
	Buzz_Times(500);//蜂鸣器响;//蜂鸣器响
	delay_ms(1000);


}
//***************************************************************//***************************************************************
//***************************************************************//***************************************************************
//***************************************************************//***************************************************************
void Fingerprint_Mod()//指纹模式
{
	SearchResult seach;
	u8 ensure=0;
	
	
	
	
	OLED_Clear();//清理屏幕
	
	Printf_windows(5);//“识别中”
	while(PS_HandShake(&AS608Addr))//与AS608模块握手
	{
		Xianshi_8X16(0,0,"AS608 Error!");
		delay_ms(500);
		OLED_Clear();//清理屏幕
	}
	Xianshi_8X16(0,0,"FingerprintMod");
	
	Buzz_Times(500);//蜂鸣器响;//蜂鸣器响
	
	

	
	ensure=PS_ValidTempleteNum(&ValidN);//读库指纹个数
	ensure=PS_ReadSysPara(&AS608Para);  //读参数
	Xianshi_8X16(0,0,"Finger Success!");
	Xianshi_8X16(0,2,"ID:");
	OLED_ShowNum(16*3,2,AS608Para.PS_max-ValidN,2);
	Xianshi_8X16(0,4,"Scor:");
	OLED_ShowNum(16*3,4,AS608Para.PS_level,1);
	
	
	
	
	while(MOD==0XFF)//刷指纹
	{
		ensure=PS_GetImage();
		if(ensure==0x00)//获取图像成功
		{
			ensure=PS_GenChar(CharBuffer1);
			if(ensure==0x00) //生成特征成功
			{
				ensure=PS_HighSpeedSearch(CharBuffer1,0,AS608Para.PS_max,&seach);
				
				if(ensure==0x00)//搜索成功
				{
					OLED_Clear();
					Xianshi_8X16(0,0,"Finger Success!");
					Xianshi_8X16(0,2,"ID:");
					OLED_ShowNum(16*3,2,seach.pageID,2);
					Xianshi_8X16(16*8,4,"Scor:");
					OLED_ShowNum(16*13,4,seach.mathscore,3);			
					
					break;
				}
			}
		}
		
	}
	OLED_Clear();
	Xianshi_16X16(0,0,6);//WIFI
	Xianshi_16X16(112,0,7);//电量
	Num =0;Location =1000;
	return ;
	
}
//***************************************************************//***************************************************************
//***************************************************************//***************************************************************
//***************************************************************//***************************************************************

void Minor_function(void)
{
	
	unsigned char metering=0;//输入计次
	
	unsigned char tmp;
	//*************************************************************
	Xianshi_16X16(0,0,6);//WIFI
	Xianshi_16X16(112,0,7);//电量
	
	
	Pass=PassNum_initialize();//加载密码
	//*************************************************************
	
	Num =0;Location =1000;
	while(1)
	{
		
		time_change();//显示时间
		Printf_PassNum(Num);//实时显示输入
		
		//*************************************************************
		if(metering==3)//多次错误已锁定
		{
			
			Printf_windows(4);/*已锁定*/
			metering=0;
		}
		else
		{
			Printf_windows(1);//“请输入密码”
			
		
		}
		//***************************************************************
		if(Location==0)//如果输入完
		{
			if(Num==Pass)
			{
				Printf_windows(2);//“解锁”
				for(tmp=5;tmp>0;tmp--)
				{
					Buzz_Times(500);//蜂鸣器响
					delay_ms(20);
				}
			}
			else//密码输入错误
			{
				Printf_windows(100);//“错误”
				Buzz_Times(500);//蜂鸣器响
				Num =0;Location =1000;metering++;
			}
			
		}

		//*************************************************************
		if(MOD==0XFF)//如果指纹模式
		{
				Fingerprint_Mod();
		}
		//*************************************************************
		
	}//while



}
//***************************************************************//***************************************************************
//***************************************************************//***************************************************************
//***************************************************************//***************************************************************

/*定时器中断函数模板*/
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;//这个用来记时
	static unsigned int T1Count;//这个用来记时
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	T1Count++;
	if(T0Count>=1000)//这里可以改,1000ms=1s
	{T0Count-=1000;Ti.sec++;}
	if(T1Count>150)
	{
		T1Count -= 150;
		Key=Test_Key();
		
		if(Key!=0)//如果没有按下
		{
			T0Count+=10;
			if((Location>0)&&(Key>=1)&&(Key<=9))//输入
			{Num += Key*Location;Location /=10;}
			if(Key==10)//输入0
			{Num += 0*Location;Location /=10;}
			if(Key==11)//清空
			{Num =0;Location =1000;}
			if(Key==12)//切换模式
			{MOD=~MOD;}
			
			Key=0;
		}
	}
}


OLED模块

Oled096.h
#ifndef __Oled096_H__
#define __Oled096_H__

void Olde096_WriteDate(unsigned char Date);
void Olde096_WriteCom(unsigned char Com);
void Set_add(unsigned char x, unsigned char y);
void OLED_Init(void);
void OLED_Clear(void);
void Xianshi_16X16(unsigned char x, unsigned char y, unsigned char N);

void Xianshi_8X16(unsigned char x, unsigned char y,unsigned char ch[]);	

void OLED_ShowNum(unsigned char x, unsigned char y,unsigned char Num,unsigned char Len);

#endif

/*
#include "I2C.h"
#include "Oled096.h"

*/
Olde_fong.h
#ifndef __Olde_fong_H__
#define __Olde_fong_H__
/*
#include "Olde_fong.h"

*/
 
/* 16X16的像素点 */
static unsigned char code F16x16[][16] = 	 
{ 

{0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00},
{0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00},/*"密",0*/

{0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00},
{0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00},/*"码",1*/

{0x10,0x10,0x10,0xFF,0x10,0x90,0x00,0x3F,0x48,0x48,0x44,0x44,0x44,0x42,0x70,0x00},
{0x04,0x44,0x82,0x7F,0x01,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00},/*"指",2*/

{0x20,0x30,0xAC,0x63,0x10,0x08,0x08,0xF8,0x09,0x0E,0x08,0xF8,0x08,0x08,0x00,0x00},
{0x22,0x67,0x22,0x12,0x92,0x80,0x40,0x21,0x16,0x08,0x16,0x21,0x40,0x80,0x80,0x00},/*"纹",3*/

{0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,0x00},
{0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00},/*"正",4*/

{0x04,0x84,0xE4,0x5C,0x44,0xC4,0x20,0x10,0xE8,0x27,0x24,0xE4,0x34,0x2C,0xE0,0x00},
{0x02,0x01,0x7F,0x10,0x10,0x3F,0x80,0x60,0x1F,0x09,0x09,0x3F,0x49,0x89,0x7F,0x00},/*"确",5*/


{0x00,0x00,0x60,0x30,0x98,0x4C,0x44,0x44,0x44,0x44,0x4C,0x98,0x30,0x60,0x00,0x00},/*"WiFi",6*/
{0x00,0x00,0x00,0x00,0x00,0x02,0x03,0x19,0x19,0x03,0x02,0x00,0x00,0x00,0x00,0x00},


{0x00,0xC0,0xC0,0xF0,0x10,0x10,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x00},/*"电池",7*/
{0x00,0x01,0x01,0x07,0x04,0x04,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00},


{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",8*/




};
 
///****************************************8*16的点阵************************************/
static const unsigned char code F8X16[]=	  
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//  0
  0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
  0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
  0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
  0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
  0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
  0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
  0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
  0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
  0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
  0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
  0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
  0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
  0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
  0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
  0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
  0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
  0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
  0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
  0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
  0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
  0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
  0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
  0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
  0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
  0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
  0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
  0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
  0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
  0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
  0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
  0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
  0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
  0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
  0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
  0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
  0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
  0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
  0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
  0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
  0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
  0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
  0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
  0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
  0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
  0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
  0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
  0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
  0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
  0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
  0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
  0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
  0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
  0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
  0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
  0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
  0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
  0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
  0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
  0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
  0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
  0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
  0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
  0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
  0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
  0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
  0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
  0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
  0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
  0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
  0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
  0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
  0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
  0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
  0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
  0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
  0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
  0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
  0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
  0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
  0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
  0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
  0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
  0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
  0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
  0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
  0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};


#endif

Olde_fong.c
#include <REGX52.H>
#include "IIC.h"
#include "Olde_fong.h"



void delay(unsigned int z)
{
	unsigned int i,j;
	for(i=z;i>0;i--)
	for(j=114;j>0;j--);
}



 /*
	*介绍:发送数据
	*参数:Date数据
	*返回值:无
	*/
void Olde096_WriteDate(unsigned char Date)
{
	
	IIC_traffic_light(0);//开始
	IIC_Save(0x78);
	IIC_Upload_Ack();//接收应答
	IIC_Save(0x40);
	IIC_Upload_Ack();
	IIC_Save(Date);
	IIC_Upload_Ack();
	IIC_traffic_light(1);//终止
}

 /*
	*介绍:发送命令
	*参数:Com命令
	*返回值:无
	*/
void Olde096_WriteCom(unsigned char Com)
{
	
	IIC_traffic_light(0);//开始
	IIC_Save(0x78);
	IIC_Upload_Ack();//接收应答
	IIC_Save(0x00);
	IIC_Upload_Ack();
	IIC_Save(Com);
	IIC_Upload_Ack();
	IIC_traffic_light(1);//终止
}


//坐标设置
//x表示列(0~127),y表示页(0~7)
void Set_add(unsigned char x, unsigned char y) 
{ 	
	Olde096_WriteCom(0xb0+y);                        //设置页地址(0~7)
	Olde096_WriteCom(((x&0xf0)>>4)|0x10);             //设置显示位置—列高地址
	Olde096_WriteCom((x&0x0f));                        //设置显示位置—列低地址
} 

/*********************OLED初始化************************************/
void OLED_Init(void)
{
	delay(500);//初始化之前的延时很重要!
	Olde096_WriteCom(0xae);//--turn off oled panel
	Olde096_WriteCom(0x00);//---set low column address
	Olde096_WriteCom(0x10);//---set high column address
	Olde096_WriteCom(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	Olde096_WriteCom(0x81);//--set contrast control register
	Olde096_WriteCom(0xcf); // Set SEG Output Current Brightness
	Olde096_WriteCom(0xa1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	Olde096_WriteCom(0xc8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	Olde096_WriteCom(0xa6);//--set normal display
	Olde096_WriteCom(0xa8);//--set multiplex ratio(1 to 64)
	Olde096_WriteCom(0x3f);//--1/64 duty
	Olde096_WriteCom(0xd3);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	Olde096_WriteCom(0x00);//-not offset
	Olde096_WriteCom(0xd5);//--set display clock divide ratio/oscillator frequency
	Olde096_WriteCom(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
	Olde096_WriteCom(0xd9);//--set pre-charge period
	Olde096_WriteCom(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	Olde096_WriteCom(0xda);//--set com pins hardware configuration
	Olde096_WriteCom(0x12);
	Olde096_WriteCom(0xdb);//--set vcomh
	Olde096_WriteCom(0x40);//Set VCOM Deselect Level
	Olde096_WriteCom(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
	Olde096_WriteCom(0x02);//
	Olde096_WriteCom(0x8d);//--set Charge Pump enable/disable
	Olde096_WriteCom(0x14);//--set(0x10) disable
	Olde096_WriteCom(0xa4);// Disable Entire Display On (0xa4/0xa5)
	Olde096_WriteCom(0xa6);// Disable Inverse Display On (0xa6/a7) 
	Olde096_WriteCom(0xaf);//--turn on oled panel
	Olde096_WriteCom(0x00); //初始清屏
	Set_add(0,0);
} 



//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
//先选中页,初始位置,然后128列全部清零
void OLED_Clear(void)  
{  
	unsigned char i,n;		    
	for(i=0;i<8;i++)  
	{  
		Olde096_WriteCom (0xb0+i); //选中页地址(0~7)
		Olde096_WriteCom (0x00);   //选中显示位置—列低地址
		Olde096_WriteCom (0x10);   //选中显示位置—列高地址   
		for(n=0;n<128;n++)  //选中所有像素点
		    Olde096_WriteDate(0);   //关闭像素点
	} //更新显示
}

//16x16显示函数 (已修改为二维)
/***功能描述:显示16*16点阵  显示的坐标(x,y),y为页范围0~7****************************/
void Xianshi_16X16(unsigned char x, unsigned char y, unsigned char N)
{
	unsigned char wm=0;
	Set_add(x , y);
	for(wm = 0;wm < 16;wm++)
	{
		Olde096_WriteDate(F16x16[(N*2)][wm]);
		
	}
	
	Set_add(x,y + 1);
	for(wm = 0;wm < 16;wm++)
	{
		Olde096_WriteDate(F16x16[(N*2)+1][wm]);
	} 	  	
}
 
 
/* 8X16显示 */
//可以自己找出来数据对应的数组
/*******************功能描述:显示8*16一组标准ASCII字符串	 显示的坐标(x,y),y为页范围0~7****************/
//ch[]:想要输入的数据,会自动在F8X16[]中寻找出来并发送给OLED
void Xianshi_8X16(unsigned char x, unsigned char y,unsigned char ch[])
{
	unsigned char c=0,i=0,j=0;
	while (ch[j]!='\0')
	{
		c =ch[j]-32;
		if(x>120){x=0;y++;}
		
		Set_add(x,y);     //一共两页,第一页
		for(i=0;i<8;i++)
		Olde096_WriteDate(F8X16[c*16+i]);
		 
		Set_add(x,y+1);   //一共两页,第二页
		for(i=0;i<8;i++)     
		Olde096_WriteDate(F8X16[c*16+i+8]);
		
		x+=8;
		j++;
	}
}


/*
X:横像素位置
y:0~7的位置
Num:0~256需要显示的数字
Len:长度
*/
void OLED_ShowNum(unsigned char x, unsigned char y,unsigned char Num,unsigned char Len)
{
	unsigned char c=0,i=0,j=1;

	while (Len>0)
	{
		
//		c =ch[j]-32;//ASCLL表中0是48,而字模库里0是16
		for(i=1,j=1;i<Len;i++){j*=10;}
		c = Num/j;//取高位
		Num %=j;//删高位
		c += 16;
		if(x>120){x=0;y++;}//超过就换行
		
		Set_add(x,y);     //一共两页,第一页
		for(i=0;i<8;i++)
		Olde096_WriteDate(F8X16[c*16+i]);
		 
		Set_add(x,y+1);   //一共两页,第二页
		for(i=0;i<8;i++)     
		Olde096_WriteDate(F8X16[c*16+i+8]);
		
		x+=8;
		Len--;
	}
}


AT24C02模块

AT24C02.h
#ifndef __AT24C02_H__
#define __AT24C02_H__

void AT24C02_Write(unsigned char Address,Date);
	
unsigned AT24C02_Read(unsigned char Address);

#endif
/*
#include "AT24C02.h"


*/
AT24C02.C
#include <REGX52.H>
#include "IIC.h"

 /*
	*介绍:写入地址和数据
	*参数:Address地址 Date数据
	*返回值:无
	*/
void AT24C02_Write(unsigned char Address,Date)
{
	
	IIC_traffic_light(0);//开始
	IIC_Save(0xA0);
	IIC_Upload_Ack();//接收应答
	IIC_Save(Address);
	IIC_Upload_Ack();
	IIC_Save(Date);
	IIC_Upload_Ack();
	IIC_traffic_light(1);//终止
}
 /*
	*介绍:读取数据
	*参数:无
	*返回值:读取AT24C02的内容
	*/
unsigned AT24C02_Read(unsigned char Address)
{
	unsigned char Date;
	
	/*获取总线的控制权*/
	IIC_traffic_light(0);//开始
	IIC_Save(0xA0);
	IIC_Upload_Ack();//接收应答
	IIC_Save(Address);
	IIC_Upload_Ack();
	IIC_traffic_light(0);//开始
	IIC_Save(0xA0|0x01);
	IIC_Upload_Ack();
	
	Date=IIC_Upload();//获取
	IIC_Save_Ack(1);
	
	IIC_traffic_light(1);//终止
	return Date;
}

IIC通信

IIC.h
#ifndef __IIC_H__
#define __IIC_H__


void IIC_traffic_light(unsigned char num);//红绿灯 0是开始 1是停止 

void IIC_Save(unsigned char Byte);//保存

unsigned char IIC_Upload(void);//加载

void IIC_Save_Ack(unsigned char Ack);//保存应答

unsigned char IIC_Upload_Ack(void);//接收应答

#endif



IIC.c
#include <REGX52.H>
#include <INTRINS.H>

sbit SCL=P3^3;
sbit SDA=P3^2;

/*
num=0时是开始模式
num=1时是停止模式
*/
void IIC_traffic_light(unsigned char num)//红绿灯
{
	if(num==0)//初始条件
	{
	SDA=1;
	SCL=1;
		
	SDA=0;//必须先
		_nop_();
		
	SCL=0;//再
		_nop_();
		
	}
	if(num==1)//终止条件
	{
	SCL=0;
	SDA=0;
		
	SCL=1;//必须先
		_nop_();
	SDA=1;//再
		_nop_();
	}
}

/*
发送字节
Byte 要发送的字节
*/
void IIC_Save(unsigned char Byte)//保存
{
	unsigned char i;
	for(i=0;i<8;i++)//保存一个字节
	{
	SDA=Byte&(0x80>>i);//1000 0000 取一位	
	SCL=1;
	_nop_();//1微秒
	SCL=0;
	}
}

/*
读取字节  
*/
unsigned char IIC_Upload(void)//加载
{
	unsigned char i,Byte;
	for(i=0;i<8;i++)//写入一个字节
	{
		SDA=1;
		SCL=1;
		if(SDA==1)//如果变为1
		{Byte|=(0x80>>i);}//相应位数变为1
		else{Byte|=0x00;}//否则变为0;
		SCL=0;
	}
	return Byte;
}

/*
Ack是应答位 0为应答,1为非应答
*/
void IIC_Save_Ack(unsigned char Ack)//保存应答
{
	SDA=Ack;
	SCL=1;
	_nop_();//1微秒
	SCL=0;
}

/* 
返回Ack是接收到的应答位  0为应答,1为非应答
*/
unsigned char IIC_Upload_Ack(void)//接收应答
{
	unsigned char Ack;
	SDA=1;
	SCL=1;
	Ack=SDA;
	SCL=0;
	return Ack;
	
}


AS608指纹模块

as608.h

#ifndef _as608_H
#define _as608_H

#include "public.h"


#define CharBuffer1 0x01
#define CharBuffer2 0x02

extern u32 AS608Addr;//模块地址

typedef struct  
{
	u16 pageID;//指纹ID
	u16 mathscore;//匹配得分
}SearchResult;

typedef struct
{
	u16 PS_max;//指纹最大容量
	u8  PS_level;//安全等级
	u32 PS_addr;
	u8  PS_size;//通讯数据包大小
	u8  PS_N;//波特率基数N
}SysPara;



u8 PS_GetImage(void); //录入图像 
 
u8 PS_GenChar(u8 BufferID);//生成特征 

u8 PS_Match(void);//精确比对两枚指纹特征 

u8 PS_Search(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p);//搜索指纹 
 
u8 PS_RegModel(void);//合并特征(生成模板) 
 
u8 PS_StoreChar(u8 BufferID,u16 PageID);//储存模板 

u8 PS_DeletChar(u16 PageID,u16 N);//删除模板 

u8 PS_Empty(void);//清空指纹库 

u8 PS_WriteReg(u8 RegNum,u8 DATA);//写系统寄存器 
 
u8 PS_ReadSysPara(SysPara *p); //读系统基本参数 

u8 PS_SetAddr(u32 addr);  //设置模块地址 

u8 PS_WriteNotepad(u8 NotePageNum,u8 *content);//写记事本 

u8 PS_ReadNotepad(u8 NotePageNum,u8 *note);//读记事 

u8 PS_HighSpeedSearch(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p);//高速搜索 
  
u8 PS_ValidTempleteNum(u16 *ValidN);//读有效模板个数 

u8 PS_HandShake(u32 *PS_Addr); //与AS608模块握手

const char *EnsureMessage(u8 ensure);//确认码错误信息解析

#endif

as608.c

#include "as608.h"
#include "uart.h"
#include <string.h>
#include "Oled096.h"


u32 AS608Addr = 0XFFFFFFFF; //默认



//串口发送一个字节
static void MYUSART_SendData(u8 dat)
{
	ES=0; //关闭串口中断
	TI=0; //清发送完毕中断请求标志位
	SBUF=dat; //发送
	while(TI==0); //等待发送完毕
	TI=0; //清发送完毕中断请求标志位
	ES=1; //允许串口中断
}

//发送包头
static void SendHead(void)
{
	MYUSART_SendData(0xEF);
	MYUSART_SendData(0x01);
}
//发送地址
static void SendAddr(void)
{
	MYUSART_SendData(AS608Addr>>24);
	MYUSART_SendData(AS608Addr>>16);
	MYUSART_SendData(AS608Addr>>8);
	MYUSART_SendData(AS608Addr);
}
//发送包标识,
static void SendFlag(u8 flag)
{
	MYUSART_SendData(flag);
}
//发送包长度
static void SendLength(int length)
{
	MYUSART_SendData(length>>8);
	MYUSART_SendData(length);
}
//发送指令码
static void Sendcmd(u8 cmd)
{
	MYUSART_SendData(cmd);
}
//发送校验和
static void SendCheck(u16 check)
{
	MYUSART_SendData(check>>8);
	MYUSART_SendData(check);
}

//与AS608握手 PS_HandShake
//参数: PS_Addr地址指针
//说明: 模块返新地址(正确地址)	
u8 PS_HandShake(u32 *PS_Addr)
{
	SendHead();
	SendAddr();
	MYUSART_SendData(0X01);
	MYUSART_SendData(0X00);
	MYUSART_SendData(0X00);
	delay_ms(200);
	while(1)
	{
		if(UART_RX_STA==12)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				*PS_Addr=(UART_RX_BUF[2]<<24) + (UART_RX_BUF[3]<<16)
							+(UART_RX_BUF[4]<<8) + (UART_RX_BUF[5]);
				UART_RX_STA=0;
				return 0;
			}
			UART_RX_STA=0;
			return 1;	
		}	
	}			
}

//判断中断接收的数组有没有应答包
//waittime为等待中断接收数据的时间(单位1ms)
//返回值:数据包首地址
static u8 *JudgeStr(u16 waittime)
{
//	char *dat;
	u8 i=0;
	xdata u8 str[8];
	str[0]=0xef;str[1]=0x01;str[2]=AS608Addr>>24;
	str[3]=AS608Addr>>16;str[4]=AS608Addr>>8;
	str[5]=AS608Addr;str[6]=0x07;str[7]='\0';
	UART_RX_STA=0;
	while(--waittime)
	{
			for(i=0;i<7;i++)
			{
				if(UART_RX_BUF[i]==str[i])return UART_RX_BUF; 
			}	
		
	}
	return 0;
}

//读系统基本参数 PS_ReadSysPara
//功能:  读取模块的基本参数(波特率,包大小等)
//参数:  无
//说明:  模块返回确认字 + 基本参数(16bytes)
u8 PS_ReadSysPara(SysPara *p)
{
	u16 temp;
	u8  ensure=0;
	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x03);
	Sendcmd(0x0F);
	temp = 0x01+0x03+0x0F;
	SendCheck(temp);
	while(1)
	{
		if(UART_RX_STA==28)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				p->PS_max = (UART_RX_BUF[14]<<8)+UART_RX_BUF[15];
				p->PS_level = UART_RX_BUF[17];
				p->PS_addr=(UART_RX_BUF[18]<<24)+(UART_RX_BUF[19]<<16)+(UART_RX_BUF[20]<<8)+UART_RX_BUF[21];
				p->PS_size = UART_RX_BUF[23];
				p->PS_N = UART_RX_BUF[25];
				UART_RX_STA=0;
				return ensure;
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}		
		}
	}
}


//录入图像 PS_GetImage
//功能:探测手指,探测到后录入指纹图像存于ImageBuffer。 
//模块返回确认字
u8 PS_GetImage(void)
{
	u16 temp;
	u8  ensure;

	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x03);
	Sendcmd(0x01);
	temp =  0x01+0x03+0x01;
	SendCheck(temp);
	
	while(1)
	{
		if(UART_RX_STA==12)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				UART_RX_STA=0;
				return ensure;	
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}		
		}	
	}
}

//生成特征 PS_GenChar
//功能:将ImageBuffer中的原始图像生成指纹特征文件存于CharBuffer1或CharBuffer2			 
//参数:BufferID --> charBuffer1:0x01	charBuffer1:0x02												
//模块返回确认字
u8 PS_GenChar(u8 BufferID)
{
	u16 temp;
	u8  ensure;

	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x04);
	Sendcmd(0x02);
	MYUSART_SendData(BufferID);
	temp = 0x01+0x04+0x02+BufferID;
	SendCheck(temp);
	while(1)
	{
		if(UART_RX_STA==12)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				UART_RX_STA=0;
				return ensure;	
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}		
		}	
	}
}

//高速搜索PS_HighSpeedSearch
//功能:以 CharBuffer1或CharBuffer2中的特征文件高速搜索整个或部分指纹库。
//		  若搜索到,则返回页码,该指令对于的确存在于指纹库中 ,且登录时质量
//		  很好的指纹,会很快给出搜索结果。
//参数:  BufferID, StartPage(起始页),PageNum(页数)
//说明:  模块返回确认字+页码(相配指纹模板)
u8 PS_HighSpeedSearch(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p)
{
	u16 temp;
	u8  ensure=0;

	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x08);
	Sendcmd(0x1b);
	MYUSART_SendData(BufferID);
	MYUSART_SendData(StartPage>>8);
	MYUSART_SendData(StartPage);
	MYUSART_SendData(PageNum>>8);
	MYUSART_SendData(PageNum);
	temp = 0x01+0x08+0x1b+BufferID
			+(StartPage>>8)+(u8)StartPage
			+(PageNum>>8)+(u8)PageNum;
	SendCheck(temp);
	while(1)
	{
		if(UART_RX_STA==16)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				p->pageID 	=(UART_RX_BUF[10]<<8) +UART_RX_BUF[11];
				p->mathscore=(UART_RX_BUF[12]<<8) +UART_RX_BUF[13];
				UART_RX_STA=0;
				return ensure;
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}	
		}	
	}
}

//读有效模板个数 PS_ValidTempleteNum
//功能:读有效模板个数
//参数: 无
//说明: 模块返回确认字+有效模板个数ValidN
u8 PS_ValidTempleteNum(u16 *ValidN)
{
	u16 temp;
	u8  ensure=0;
	
	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x03);
	Sendcmd(0x1d);
	temp = 0x01+0x03+0x1d;
	SendCheck(temp);

	while(1)
	{
		if(UART_RX_STA==14)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				*ValidN = (UART_RX_BUF[10]<<8) +UART_RX_BUF[11];
				UART_RX_STA=0;
				return ensure;
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}	
		}	
	}
}

//精确比对两枚指纹特征 PS_Match
//功能:精确比对CharBuffer1 与CharBuffer2 中的特征文件 
//模块返回确认字
u8 PS_Match(void)
{
	u16 temp;
	u8  ensure;

	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x03);
	Sendcmd(0x03);
	temp = 0x01+0x03+0x03;
	SendCheck(temp);
	while(1)
	{
		if(UART_RX_STA==14)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				UART_RX_STA=0;
				return ensure;
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}	
		}	
	}
}

//合并特征(生成模板)PS_RegModel
//功能:将CharBuffer1与CharBuffer2中的特征文件合并生成 模板,结果存于CharBuffer1与CharBuffer2	
//说明:  模块返回确认字
u8 PS_RegModel(void)
{
	u16 temp;
	u8  ensure;

	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x03);
	Sendcmd(0x05);
	temp = 0x01+0x03+0x05;
	SendCheck(temp);
	while(1)
	{
		if(UART_RX_STA==12)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				UART_RX_STA=0;
				return ensure;
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}	
		}	
	}		
}

//储存模板 PS_StoreChar
//功能:将 CharBuffer1 或 CharBuffer2 中的模板文件存到 PageID 号flash数据库位置。			
//参数:  BufferID @ref charBuffer1:0x01	charBuffer1:0x02
//       PageID(指纹库位置号)
//说明:  模块返回确认字
u8 PS_StoreChar(u8 BufferID,u16 PageID)
{
	u16 temp;
	u8  ensure;

	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x06);
	Sendcmd(0x06);
	MYUSART_SendData(BufferID);
	MYUSART_SendData(PageID>>8);
	MYUSART_SendData(PageID);
	temp = 0x01+0x06+0x06+BufferID+(PageID>>8)+(u8)PageID;
	SendCheck(temp);
	while(1)
	{
		if(UART_RX_STA==12)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				UART_RX_STA=0;
				return ensure;
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}	
		}	
	}		
}

//删除模板 PS_DeletChar
//功能:  删除flash数据库中指定ID号开始的N个指纹模板
//参数:  PageID(指纹库模板号),N删除的模板个数。
//说明:  模块返回确认字
u8 PS_DeletChar(u16 PageID,u16 N)
{
	u16 temp;
	u8  ensure;

	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x07);
	Sendcmd(0x0C);
	MYUSART_SendData(PageID>>8);
	MYUSART_SendData(PageID);
	MYUSART_SendData(N>>8);
	MYUSART_SendData(N);
	temp = 0x01+0x07+0x0C+(PageID>>8)+(u8)PageID+(N>>8)+(u8)N;
	SendCheck(temp);
	while(1)
	{
		if(UART_RX_STA==12)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				UART_RX_STA=0;
				return ensure;
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}	
		}	
	}	
}
//清空指纹库 PS_Empty
//功能:  删除flash数据库中所有指纹模板
//参数:  无
//说明:  模块返回确认字
u8 PS_Empty(void)
{
	u16 temp;
	u8  ensure;

	SendHead();
	SendAddr();
	SendFlag(0x01);//命令包标识
	SendLength(0x03);
	Sendcmd(0x0D);
	temp = 0x01+0x03+0x0D;
	SendCheck(temp);
	while(1)
	{
		if(UART_RX_STA==12)//该条命令对应的响应字节数
		{
			//判断是不是模块返回的应答包
			if(UART_RX_BUF[0]==0XEF&&UART_RX_BUF[1]==0X01&&UART_RX_BUF[6]==0X07)
			{
				ensure=UART_RX_BUF[9];
				UART_RX_STA=0;
				return ensure;
			}
			else
			{
				ensure=0xff;
				UART_RX_STA=0;
				return ensure;	
			}	
		}	
	}	
}


//
//***********************************************************************
//















串口配置

uart.h
#ifndef _uart_H
#define _uart_H

#include "public.h"
#include "stdio.h"


#define UART_REC_LEN  			50  	//定义最大接收字节数 50

extern xdata u8 UART_RX_BUF[UART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u32 UART_RX_STA;         		//接收状态标记	


void UART_Init(void);
void UART_SendData(u8 dat);
void UART_SendString(u8 *pbuf);


#endif

uart.c
#include "uart.h"

#define RELOAD_COUNT 0xFA //宏定义波特率发生器的载入值 9600

void UART_Init(void)
{
	SCON|=0X50;			//设置为工作方式1
	TMOD|=0X20;			//设置计数器工作方式2
	PCON=0X80;			//波特率加倍
	TH1=RELOAD_COUNT;	//计数器初始值设置
	TL1=TH1;
	ES=0;				//关闭接收中断
	EA=1;				//打开总中断
	TR1=1;				//打开计数器
//	TI=1;          //发送中断标记位,如果使用printf函数的必须设置	
}

void UART_SendData(u8 dat)
{
	ES=0; //关闭串口中断
	TI=0; //清发送完毕中断请求标志位
	SBUF=dat; //发送
	while(TI==0); //等待发送完毕
	TI=0; //清发送完毕中断请求标志位
	ES=1; //允许串口中断
}

void UART_SendString(u8 *pbuf)
{
	while(*pbuf!='\0') //遇到空格跳出循环	
	{
		UART_SendData(*pbuf);
		delay_10us(5);
		pbuf++;	
	}
}


xdata u8 UART_RX_BUF[UART_REC_LEN];     //接收缓冲,最大UART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u32 UART_RX_STA=0;       //接收状态标记	


void UART_IRQn(void) interrupt 4
{
	u8 res=0;

	 while(!RI)
	{
		RI=0;
		UART_RX_BUF[UART_RX_STA++]=SBUF;//读取接收到的数据  		
		if(UART_RX_STA>=UART_REC_LEN){
			UART_RX_STA=0;
		}
	}	
}


矩阵键盘模块

Matrix_Key.h
#ifndef __Matrix_Key_H__
#define __Matrix_Key_H__

unsigned int Test_Key(void);

#endif

//#include "Matrix_Key.h"
Matrix_Key.c
#include <REGX52.H>



unsigned int Test_Key(void)
{
	unsigned int Num_Key=0;
	P2=0x0F;//0000 1111  0是有电 1是无电
	if(P2 !=0x0F)//判断是否有按键按下导致P1变化
	{
				unsigned char data i, j;

				i = 20;
				j = 113;
				do
				{
					while (--j);
				} while (--i);
			
			if(P2 !=0x0F)//判断是否有按键按下10ms 
			{
				/*
				接下来开始判断
				S1  S2  S3  S4
				S5  S6  S7  S8
				S9  S10 S11 S12
				S13 S14 S15 S16
				*/
				P2=0x0F;//0000 1111  0是有电 1是无电	
				switch(P2)//先判断竖列
				{
					case (0x07):Num_Key=1;break;//0000 0111 锁定第1列
					case (0x0B):Num_Key=2;break;//0000 1011 锁定第2列
					case (0x0D):Num_Key=3;break;//0000 1101 锁定第3列
					case (0x0E):Num_Key=4;break;//0000 1110 锁定第4列
					default:return 0;
				}
				
				P2=0xF0;//1111 0000  0是有电 1是无电	
				switch(P2)//再判断横列
				{
					case (0x70):Num_Key=Num_Key+0;break;//0111 0000 锁定第1排
					case (0xB0):Num_Key=Num_Key+4;break;//1011 0000 锁定第2排
					case (0xD0):Num_Key=Num_Key+8;break;//1101 0000 锁定第3排
					case (0xE0):Num_Key=Num_Key+12;break;//1110 0000 锁定第4排
					default:return 0;
				}				
			}
	}
	return Num_Key;	

}

延时函数

public.h
#ifndef _public_H
#define _public_H

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;
typedef unsigned long u32;

void delay_10us(u16 ten_us);
void delay_ms(u16 ms);

#endif

public.c
#include "public.h"

/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能		 : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出    	 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}

/*******************************************************************************
* 函 数 名       : delay_ms
* 函数功能		 : ms延时函数,ms=1时,大约延时1ms
* 输    入       : ms:ms延时时间
* 输    出    	 : 无
*******************************************************************************/
void delay_ms(u16 ms)
{
	u16 i,j;
	for(i=ms;i>0;i--)
		for(j=110;j>0;j--);
}

中断配置

Timer0Init.h
#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0Init(void);

#endif

Timer0Init.c
#include <REGX52.H>
#include "Timer0Init.h"
/*
 配置 1毫秒@12.000MHz

  */
void Timer0Init(void)
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式 自动重装载
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;				//允许外部中断和定时器中断。
	PT0=0;
}

/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;//这个用来记时
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000)//这里可以改,1000ms=1s
	{
		T0Count=0;
		
	}
}
*/

蜂鸣器模块

buzz.h
#ifndef _BUZZ_H_
#define _BUZZ_H_
#include<reg52.h>

sbit buzz=P3^6;

void Buzz_Times(unsigned char times);

#endif
buzz.c
#include "buzz.h"
#include "public.h"

void Buzz_Times(unsigned char times)
{
	unsigned char i=0;
	for(i=0;i<times;i++)
	{
		 buzz=0;
		 delay_ms(1);
		 buzz=1;
		 delay_ms(1);
	}
}

edef unsigned char u8;
typedef unsigned long u32;

void delay_10us(u16 ten_us);
void delay_ms(u16 ms);

#endif


#### public.c

#include “public.h”

/*******************************************************************************

  • 函 数 名 : delay_10us
  • 函数功能 : 延时函数,ten_us=1时,大约延时10us
  • 输 入 : ten_us
  • 输 出 : 无
    *******************************************************************************/
    void delay_10us(u16 ten_us)
    {
    while(ten_us–);
    }

/*******************************************************************************

  • 函 数 名 : delay_ms
  • 函数功能 : ms延时函数,ms=1时,大约延时1ms
  • 输 入 : ms:ms延时时间
  • 输 出 : 无
    *******************************************************************************/
    void delay_ms(u16 ms)
    {
    u16 i,j;
    for(i=ms;i>0;i–)
    for(j=110;j>0;j–);
    }



### 中断配置

#### Timer0Init.h

#ifndef TIMER0_H
#define TIMER0_H

void Timer0Init(void);

#endif




#### Timer0Init.c

#include <REGX52.H>
#include “Timer0Init.h”
/*
配置 1毫秒@12.000MHz

*/
void Timer0Init(void)
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式 自动重装载
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1; //允许外部中断和定时器中断。
PT0=0;
}

/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;//这个用来记时
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=1000)//这里可以改,1000ms=1s
{
T0Count=0;

}

}
*/


### 蜂鸣器模块

#### buzz.h

#ifndef BUZZ_H
#define BUZZ_H
#include<reg52.h>

sbit buzz=P3^6;

void Buzz_Times(unsigned char times);

#endif




#### buzz.c

#include “buzz.h”
#include “public.h”

void Buzz_Times(unsigned char times)
{
unsigned char i=0;
for(i=0;i<times;i++)
{
buzz=0;
delay_ms(1);
buzz=1;
delay_ms(1);
}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值