在这里插入图片描述
【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);
}
}