其他分享
首页 > 其他分享> > 单片机STC12C5A60S2_RFID_RC522_OLED_门禁系统_菜单设计

单片机STC12C5A60S2_RFID_RC522_OLED_门禁系统_菜单设计

作者:互联网

门禁系统

视频演示
Keil源代码包

系统流程图

/*************************************************
*
*				
*	
*	P0^0 -------  步进电机1
*	P0^1 -------  步进电机2
*	P0^2 -------  步进电机3
*	P0^3 -------  步进电机4
*
*	P1^1 -------  OLED的SDA
*	P1^2 -------  OLED的SCL
*
*	P1^3 -------  RFID的SDA
*	P1^4 -------  RFID的SCK
*	P1^5 -------  RFID的MOSI
*	P1^6 -------  RFID的MISO
*	P1^7 -------  RFID的RQ
*
*	P2^0 -------  AT24C02的SCL
*	P2^1 -------  AT24C02的SDA
*
*	P2^3 -------  BUZZER
*	P2^5 -------  Error LED
*	P2^6 -------  OK LED
*	
*	P3^0 -------  矩阵键盘引脚0
*	P3^1 -------  矩阵键盘引脚1
*	P3^2 -------  矩阵键盘引脚2
*	P3^3 -------  矩阵键盘引脚3
*	P3^4 -------  矩阵键盘引脚4
*	P3^5 -------  矩阵键盘引脚5
*	P3^6 -------  矩阵键盘引脚6
*	P3^7 -------  矩阵键盘引脚7
* 
* 
*
**************************************************/

代码分析

在这里插入图片描述


main.h

#ifndef __MAIN_H__
#define __MAIN_H__
#include "common.h"
#include "user_passwd.h"
#include "keyboard.h"
#include "iic.h"
#include "oled.h"
#include "rc522.h"
#include<mfrc522.h>
#endif

/*************************************************
*
*				引脚配置信息
*	
*	P0^0 -------  步进电机1
*	P0^1 -------  步进电机2
*	P0^2 -------  步进电机3
*	P0^3 -------  步进电机4
*
*	P1^1 -------  OLED的SDA
*	P1^2 -------  OLED的SCL
*
*	P1^3 -------  RFID的SDA
*	P1^4 -------  RFID的SCK
*	P1^5 -------  RFID的MOSI
*	P1^6 -------  RFID的MISO
*	P1^7 -------  RFID的RQ
*
*	P2^0 -------  AT24C02的SCL
*	P2^1 -------  AT24C02的SDA
*
*	P2^3 -------  BUZZER
*	P2^5 -------  Error LED
*	P2^6 -------  OK LED
*	
*	P3^0 -------  矩阵键盘引脚0
*	P3^1 -------  矩阵键盘引脚1
*	P3^2 -------  矩阵键盘引脚2
*	P3^3 -------  矩阵键盘引脚3
*	P3^4 -------  矩阵键盘引脚4
*	P3^5 -------  矩阵键盘引脚5
*	P3^6 -------  矩阵键盘引脚6
*	P3^7 -------  矩阵键盘引脚7
* 
* 
*
**************************************************/

main.c


#include "main.h"
#define NO_TIMER2	//RFID.c中,STC12系列无定时器2
/*******************
* 引用全局变量
********************/
extern uchar key_flag;	//按键标志位
extern uchar admin_passwd[];	//存储管理员密码
extern uchar passwd[];			//存储用户密码
extern uchar key_num;			//矩阵按键返回值
extern UGroup G[];				//UGroup结构体变量,定义与rc522.h头文件中
extern Tips code lines[];		//Tips结构体类型OLED.h头文件中,用于存储显示信息
extern key_table  code  table[];//key_table结构体类型,定义与OLED.h头文件中,用于定义跳转函数
extern uchar code BMP1[];	//存储的图片
extern uchar func_index;	//func函数下标变量
extern uchar UID_S50[];		//存储S50卡卡号,4字节
extern uchar Temp_S50[];	//临时存储S50卡卡号变量


/**********************
* 	系统临时变量
***********************/

uchar  TEMP;
bit OUT = 0;

/**********************
* 	函数声明
***********************/

void (*current_operation_index)();	//指针函数声明
void Timer0Init();					//定时中断0函数声明

/**********************
* 	Main主函数
***********************/
void main(){
	RFID_Init();		//RFID初始化
	OLED_Init();		//OLED初始化
	enterMenu();		//开机LOGO
	Delay1000ms();		//延时1秒,稳定系统
	read_UID_From_EEPROM(G);	//读取存储在AT24C02中的UID用户ID

#if 0 //调试代码,可忽略
	at24c02Write(19,0);//存储卡号的标志位
	save_passwd_EEPROM(passwd,6);//保存用户密码到AT24C02
#endif
	
	
	if(read_passwd_EEPROM(passwd,6)) showOK();	//从AT24C02中读取user passwd用户密码,必须的
	
	OLED_CLS();				//OLED显示:欢迎回家
	OLED_P16x16Ch(23,3,4);
	OLED_P16x16Ch(40,3,5);
	OLED_P16x16Ch(57,3,6);
	OLED_P16x16Ch(74,3,7);
	
	Timer0Init();			//定时器0初始化
	
	while(1)				//while大循环
	{
		if(key_flag == 1)	//矩阵按键标志位
		{
	
			if(key_num == 12)//进入菜单
			{	
				showOK();		//提示OK
				//第一个函数值获取下一个函数号码;第二个函数是执行获取后的函数。
				current_operation_index = table[func_index].current_operation;	(*current_operation_index)();
				while(!OUT)	//检测菜单函数的退出与否的while循环
				{
					TEMP = getDir();//内置while循环
					if(TEMP){
						current_operation_index = table[func_index].current_operation;	(*current_operation_index)();
					}
					key_flag = 0;
				}
				//第一个函数值获取下一个函数号码;第二个函数是执行获取后的函数。
				current_operation_index = table[func_index].current_operation;	(*current_operation_index)();	
				//各个标志位复位
				OUT = 0;
				TEMP = 0;
				func_index = 0;
				key_flag = 0;
			}

			if((key_num == 14)&&verif_user_passwd())//按井号键开始验证密码
			{
				key_flag = 0;
				showOK();
				EA = 0;		//关闭所有中断
				OLED_CLS();	
				OLED_P8x16Str(0,0,"Door Is Opening.");
				Delay500ms();
				OLED_CLS();	//显示:欢迎回家
				OLED_P16x16Ch(23,3,4);
				OLED_P16x16Ch(40,3,5);
				OLED_P16x16Ch(57,3,6);
				OLED_P16x16Ch(74,3,7);
				MotroOpenDoor();
				EA = 1;
				key_flag = 0;
			}
			else 
			{
				showError();	//错误提示
				key_flag = 0;
			}

			key_num = 0;
		
		}
		else
		{
			Auto_Reader();	//RFID扫描函数
		}
	}

}

void Timer0Init()		//2毫秒@11.0592MHz//
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xF8;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1;
}
void time0() interrupt 1
{
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xF8;		//设置定时初值
	keyscanf_maxtrix();
}


keyboard.h

#ifndef __KEYBOARD_H__
#define __KEYBOARD_H__
#include "common.h"
#include "oled.h"
void keyscanf_maxtrix();
uchar get_onece_keyboard();
#endif
/*****************************************************
*			4*4矩阵键盘按键说明:
*
* - 上键:	keyscanf_maxtrix扫描值:3 	再赋值 10
* - 下键:	keyscanf_maxtrix扫描值:15 	再赋值 15
* - 左键:	keyscanf_maxtrix扫描值:7 	再赋值 11
* - 右键:	keyscanf_maxtrix扫描值:11 	再赋值 13
* - 井号键:keyscanf_maxtrix扫描值:14 	再赋值 14
* - 星号键:keyscanf_maxtrix扫描值:12 	再赋值 12
*
* - 星号键进入菜单 值为 12
* - 井号键为确定键 值为 14
* 
****************************************************/

keyboard.c

矩阵键盘

#include "keyboard.h"

uchar key_flag = 0;//标志位
uchar key_num = 16;//默认为"-"

uchar get_onece_keyboard()	//得到一个值,while循环
{	static uchar i = 0;
	uchar temp = 99;
	if(key_flag == 1)
	{
		key_flag = 0;
		while(temp == 99)
		{
			switch(key_num)
			{
				case 0: temp = 1;  break;
				case 1: temp = 2;  break;
				case 2: temp = 3;  break;
				case 3: temp = 10; break;	//上
				case 4: temp = 4;  break;
				case 5: temp = 5;  break;
				case 6: temp = 6;  break;
				case 7: temp = 11; break;	//左
				case 8: temp = 7;  break;
				case 9: temp = 8;  break;
				case 10: temp = 9;  break;
				case 11: temp = 13; break;	//右
				case 12: temp = 12; break;	//星号
				case 13: temp = 0;  break;
				case 14: temp = 14;	break;	//井号
				case 15: temp = 15; break;	//下
			}
		}
		/*************************************
		*  按键又被按下,OLED上会有提示
		*************************************/
		EA = 0;
		if(i%2==0)
		{
			OLED_P8x16Str(0,6,". ");
		}
		else
		{
			OLED_P8x16Str(0,6," .");
		}
		i++;if(i==6){i = 0;}
		EA = 1;		
	}
	key_flag = 0;
	return temp;
}

/**********************************
*		矩阵扫描函数
*	占用8个IO口,进行行的扫描
**********************************/
void keyscanf_maxtrix()	
{
	if(key_flag == 0){
		uchar i;
		uchar cycle = 0xfe;
		for(i=0;i<4;i++){
			uchar temp;
			P3 = cycle;
			temp = P3;
			temp = temp&0xf0;
			if(temp!=0xf0)
			{
			  if(temp!=0xf0)
			  {	
				temp=P3;
				switch(temp)
				{
				  case 0xee:
					key_num=0;
					key_flag = 1;
					break;
				  
				  case 0xde:
					key_num=1;
					key_flag = 1;
					break;

				  case 0xbe:
					key_num=2;
					key_flag = 1;
					break;

				  case 0x7e:
					key_num=3;
					key_flag = 1;
					break;
					
				  case 0xed:
					key_num=4;
					key_flag = 1;
					break;
					
				  case 0xdd:
					key_num=5;
					key_flag = 1;
					break;
					
				  case 0xbd:
					key_num=6;
					key_flag = 1;
					break;
					
				  case 0x7d:
					key_num=7;
					key_flag = 1;
					break;
					
				  case 0xeb:
					key_num=8;
					key_flag = 1;
					break;
					
				  case 0xdb:
					key_num=9;
					key_flag = 1;
					break;
		
				  case 0xbb:
					key_num=10;
					key_flag = 1;
					break;
					
				  case 0x7b:
					key_num=11;
					key_flag = 1;
					break;
				  
				   case 0xe7:
					key_num=12;
					key_flag = 1;
					break;
					
				  case 0xd7:
					key_num=13;
					key_flag = 1;
					break;

				  case 0xb7:
					key_num=14;
					key_flag = 1;
					break;
					
				  case 0x77:
					key_num=15;
					key_flag = 1;
					break;
				 }
			  }
			}
			while(temp!=0xf0)	//按键松手后,跳出循环,防止多按
			{
				temp=P3;
				temp=temp&0xf0;
			}
			cycle = _crol_(cycle,1);//循环左移
		}
	}
	
}

user_passwd.h

#ifndef __USER_PASSWD__
#define __USER_PASSWD__
#include "common.h"
#include "keyboard.h"
#include "iic.h"
#include "rc522.h"
#include "mfrc522.h"
void get_six_number(uchar *arr);
bit modify_admin_passwd();
bit verif_user_passwd();
bit compare_two_four_number(uchar *arr1, uchar *arr2);
bit verif_admin_passwd();
bit modify();
bit read_passwd_EEPROM(uchar *arr,uchar num);
bit save_passwd_EEPROM(uchar *arr, uchar num);
void Auto_Reader();
bit verif_CardID_from_EEPROM(uchar arr[]);
#endif

user_passwd.c

#include "user_passwd.h"

extern uchar key_flag;
extern uchar key_num;
extern uchar UID_S50[];		//S50卡,4字节
extern uchar Temp_S50[];	//S50卡,4字节
extern UGroup G[];			//S50卡组
uchar  admin_passwd[6] = {2,3,2,3,2,3};	//初始化,管理员密码,非缓存区
uchar  passwd[6] = {5,5,5,5,5,5};		//初始化用户密码,缓存区

/*****************************
* 函数功能:
* 
******************************/
/*****************************
* 函数功能:从键盘得到六位数字
* 参数:数组名
******************************/
void get_six_number(uchar *arr)	
{
	uchar i;
	for(i = 0; i < 6; i++){
		key_flag = 0;
		while(key_flag != 1);
		*arr = get_onece_keyboard();
		arr++;
	}
}

/*****************************
* 函数功能:修改超级用户密码
******************************/
bit modify_admin_passwd()		
{
	get_six_number(admin_passwd);
	
	return 1;
}
/*****************************
* 函数功能:修改用户密码
******************************/
bit modify_user_passwd()		
{
	get_six_number(passwd);
	
	return 1;
}
/*****************************
* 函数功能:比较两组六位数的数组
******************************/
bit compare_two_six_number(uchar *arr1, uchar *arr2) 
{
	uchar i;
	for(i = 0; i < 6; i++){
		if((*arr1) != (*arr2)) return 0;
		arr1++;
		arr2++;
	}
	return 1;
}
/*****************************
* 函数功能:比较两组4位数的数组
******************************/
bit compare_two_four_number(uchar *arr1, uchar *arr2) 
{
	uchar i;
	for(i = 0; i < 4; i++){
		if((*arr1) != (*arr2)) return 0;
		arr1++;
		arr2++;
	}
	return 1;
}
/*****************************
* 函数功能:验证管理员密码
******************************/
bit verif_admin_passwd()	
{
	uchar temp[6];
	get_six_number(temp);
	if(compare_two_six_number(temp,admin_passwd))
		return 1;
	else 
		return 0;
}
/*****************************
* 函数功能:验证用户密码
******************************/
bit verif_user_passwd()	
{
	uchar temp[6];
	get_six_number(temp);
	if(compare_two_six_number(temp,passwd))
		return 1;
	else 
		return 0;
}
/*****************************
* 函数功能:修改用户密码函数
******************************/
bit modify()				
{
	if(verif_admin_passwd())//输入并验证 管理员密码admin_passwd
	{
		key_flag = 0;
		showOK();
		{EA=0;OLED_CLS();OLED_P8x16Str(30,3,"Right!");Delay500ms();OLED_CLS();OLED_P8x16Str(30,0,"Contine,");OLED_P8x16Str(0,4,"Enter N Passwd");EA=1;}//OLED提示
		if(modify_user_passwd())	//修改用户密码user_passwd
		{
			save_passwd_EEPROM(passwd,6);
			{EA=0;OLED_CLS();OLED_P8x16Str(10,4,"Updated Passwd!");Delay500ms();EA=1;}
			showOK();
			key_flag = 0;
			return 1;
		}
		else{EA=0;OLED_CLS();OLED_P8x16Str(0,0,"Failed!");Delay500ms();EA=1;return 0;}
	}
	else{
	{EA=0;OLED_CLS();OLED_P8x16Str(0,0,"Failed!");Delay500ms();EA=1;return 0;}
	}
	
}

/*****************************
* 函数功能:从EEPROM中去读用户密码
* 用户密码存储地址:9-14位
******************************/
bit read_passwd_EEPROM(uchar *arr,uchar num)
{	uchar i = 0;
	EA = 0;	//关闭所有中断
	for(i = 0; i < num; i++)
	{
		*arr = at24c02Read(9+i);
		arr++;
		showOK();
		Delay20ms();//延时以稳定AT24C02芯片
	}
	EA = 1;//恢复所有中断
	return 1;
}
/*****************************
* 函数功能:将用户密码存储在EEPROM中
* 用户密码存储地址:9-14位
******************************/
bit save_passwd_EEPROM(uchar *arr, uchar num)	//保存用户密码
{
	uchar i = 0;
	EA = 0;
	for(i = 0; i < num; i++)
	{
		at24c02Write(9+i,*arr);
		Delay20ms();
		showOK();
		arr++;
		
	}
	EA = 1;
	return 1;
}

/*****************************
* 函数功能:将读取的卡号
******************************/
bit verif_CardID_from_EEPROM(uchar arr[]){
	uchar ii = 0;
	for(ii = 0; ii<10; ii++){
		if(compare_two_four_number(G[ii].UID,arr)) return 1;
		else continue;
	}
	return 0;
}

void Auto_Reader()
{
    if(PcdRequest(0x52,Temp_S50) == MI_OK)
	{ 	//寻卡,成功后Temp数组为卡类型
		
		if(PcdAnticoll(UID_S50)== MI_OK )
		{	 	//防冲突,UID数组数据为卡序列号
			showOK();
//			if(compare_two_four_number(UUID,UID_S50)) {showOK();MotroOpenDoor();}    
			if(verif_CardID_from_EEPROM(UID_S50)) {showOK();MotroOpenDoor();}      			
		}
    }

}


common.h

#ifndef __COMMON_H__
#define __COMMON_H__

#include "reg52.h"
#include "intrins.h"
#include "string.h"

#define OSC_FREQ          11059200L				//系统晶振选择
#define  RCAP2_50us      65536L - OSC_FREQ/40417L
#define  RCAP2_1ms       65536L - OSC_FREQ/2000L
#define  RCAP2_10ms      65536L - OSC_FREQ/1200L
#define  TIME0_500us     65536L - OSC_FREQ/8000L
#define  TIME0_10ms      65536L - OSC_FREQ/200

#define TRUE 1
#define FALSE 0

sfr AUXR = 0x8e;	//辅助寄存器


typedef unsigned int uint;
typedef unsigned char uchar;

/***************************
*	系统状态提示声明
****************************/
void showError();
void showOK();

/***************************
*	软件延时函数声明
****************************/
void delay(uint z);
void Delay1ms()	;	
void Delay2ms();
void Delay20ms();		//@11.0592MHz
void Delay100ms();
void Delay200ms();	//@11.0592MHz
void Delay500ms();	//@11.0592MHz	
void Delay1000ms();

/***************************
*	步进电机驱动函数
****************************/
void MotroOpenDoor();

#endif

common.c

#include "common.h"
#define MotorData  P0

sbit Error = P2^5;	//Red led
sbit OK = P2^6;		//Green led
sbit buzzer_ = P2^3;//蜂鸣器
/***************************
*	步进电机位置数组//这没说不太准确,详细请搜索五线四向步进电机原理
****************************/
uchar idata motor_arrA[4] = {0x08,0x04,0x02,0x01};
uchar idata motor_arrB[4] = {0x01,0x02,0x04,0x08};


void delay(uint z)
{
	uchar x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}

void Delay2ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 22;
	j = 128;
	do
	{
		while (--j);
	} while (--i);
}

void Delay4ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 44;
	j = 3;
	do
	{
		while (--j);
	} while (--i);
}
void Delay20ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 1;
	j = 216;
	k = 35;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay100ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 5;
	j = 52;
	k = 195;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay200ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 9;
	j = 104;
	k = 139;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 22;
	j = 3;
	k = 227;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void showOK(){
	OK = 0;
	buzzer_ = 0;
	Delay200ms();
	OK = 1;
	buzzer_ = 1;
	Delay200ms();
}

void showError()
{
	Error = 0;
	buzzer_ = 0;
	Delay200ms();
	Error = 1;
	buzzer_ = 1;
	Delay200ms();
	Error = 0;
	buzzer_ = 0;
	Delay200ms();
	Error = 1;
	buzzer_ = 1;
	Delay200ms();
	
}




void MotorTurnA()	//步进电机正向
{
	uchar i;
	for(i = 0; i <4; i++)
	{
		MotorData = motor_arrA[i];
		Delay4ms();
	}
}

void MotorTurnB()	//步进电机正向
{
 uchar i;
 for(i=0;i<4;i++)
  {
   MotorData = motor_arrB[i];
   Delay4ms();//转速调节
  }
}

void MotorStop()	//步进电机停止
{
	MotorData=0x00;
}


void MotroOpenDoor()
{
	uchar i;
	for(i=0;i<200;i++)
	{
		dula = 0;
		wela = 0;
		MotorTurnA();   //顺时针转动
		
	}
		
	MotorStop();  //停止转动
	Delay500ms();
		
	for(i=0;i<200;i++)
	{
		dula = 0;
		wela = 0;
		MotorTurnB();  //逆时针转动
	} 
	MotorStop();  //停止转动 
	Delay500ms();
}

iic.h

#ifndef _IIC_H__
#define _IIC_H__

#include "common.h"
#include "rc522.h"
/***********************
*	iic基本驱动函数
***********************/
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 

/***********************
*	EEPROM读写函数
***********************/
void at24c02Write(uchar addr, uchar dat);	//写
uchar at24c02Read(uchar addr);						//	读
void at24c02ReadStr(uchar addr, uchar num, uchar *getStr);
void at24c02WriteStr(uchar addr, uchar *p,uchar num);

/***********************
*	用户组G的读取和存储
***********************/
void save_UID_In_EEPROM(uchar *arr);
void read_UID_From_EEPROM(UGroup G[]);
void clearAll();//清除全部UID

#endif

iic.c

#include "iic.h"
#define somenop; _nop_();	//调节通信延时长短
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */
extern UGroup G[];

//总线启动条件
void IIC_Starts(void)
{
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

//总线停止条件
void IIC_Stops(void)
{
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

//应答位控制
void IIC_Ack(bit ackbit)
{
	if(ackbit) 
	{	
		SDA = 0;
	}
	else 
	{
		SDA = 1;
	}
	somenop;
	SCL = 1;
	somenop;
	SCL = 0;
	SDA = 1; 
	somenop;
}

//等待应答
bit IIC_WaitAck(void)
{
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{   
		SCL = 0;
		IIC_Stops();
		return 0;
	}
	else  
	{ 
		SCL = 0;
		return 1;
	}
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		if(byt&0x80) 
		{	
			SDA = 1;
		}
		else 
		{
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}

/*********************************
*	EEPROM的单字节操作函数
***********************************/
uchar at24c02Read(uchar addr)	//	读
{
	uchar dat;
	IIC_Starts();
	IIC_SendByte(0xa0);//写地址(读的函数,要先发送写的指令,写在哪里的地址)
	IIC_WaitAck();
	IIC_SendByte(addr);	
	IIC_WaitAck();
	IIC_Stops();
	
	IIC_Starts();
	IIC_SendByte(0xa1);//正式开始
	IIC_WaitAck();
	dat = IIC_RecByte();
	IIC_Ack(0);
	IIC_Stops();
	
	return dat;
}

void at24c02Write(uchar addr, uchar dat)	//写
{

	IIC_Starts();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(dat);	
	IIC_WaitAck();
	IIC_Stops();
}


/*********************************
*	用户组G的读取、存储、删除
***********************************/
void save_UID_In_EEPROM(uchar *arr)
{
	uchar i;
	uchar n;
	n = at24c02Read(19); 
	Delay100ms();
	n++;
	if(n == 10) n = 0;
	at24c02Write(19,n);
	Delay100ms();
	for(i=0;i<4;i++)
	{
		at24c02Write(20+n*4+i,*arr);
		Delay100ms();
		arr++;
		showOK();
	}
}

void read_UID_From_EEPROM(UGroup G[]){
	uchar i,j,tmp;
	for(i=0;i<10;i++)
	{
		for(j=0;j<4;j++){
			tmp = at24c02Read(20+i*4+j);
			Delay100ms();
			G[i].UID[j] = tmp;
		}
	}
	showOK();
}

void clearAll()
{
	uchar i;
	EA = 0;
	for(i=0;i<41;i++)
	{
		at24c02Write(20+i,0);
		Delay20ms();
	}
	read_UID_From_EEPROM(G);//重新载入
	EA = 1;
}

rc522.h

#ifndef __RC522_H__
#define __RC522_H__

#include "common.h"

#include<mfrc522.h>

#define MAXRLEN 18
sfr   RCAP2LH =   0xCA;
sfr   T2LH    =   0xCC; 

sbit     MF522_NSS  =    P1^3;
sbit     MF522_SCK  =    P1^4;
sbit     MF522_SI   =    P1^5;
sbit     MF522_SO   =    P1^6;
sbit     MF522_RST  =    P1^7;                   //RC500片选
sbit     beep       =    P2^3;                   //检测灯,当寻卡成功后闪烁


typedef struct{
	uchar UID[5];
}UGroup;


void RFID_Init();

char PcdReset(void);
void PcdAntennaOn(void);
void PcdAntennaOff(void);
char PcdRequest(unsigned char req_code,unsigned char *pTagType);   
char PcdAnticoll(unsigned char *pSnr);                                
char PcdComMF522(unsigned char Command, 
                 unsigned char *pInData, 
                 unsigned char InLenByte,
                 unsigned char *pOutData, 
                 unsigned int  *pOutLenBit);
void WriteRawRC(unsigned char Address,unsigned char value);
unsigned char ReadRawRC(unsigned char Address); 
void SetBitMask(unsigned char reg,unsigned char mask); 
void ClearBitMask(unsigned char reg,unsigned char mask); 
char M500PcdConfigISOType(unsigned char type);
void delay_10ms(unsigned int _10ms);
				 

/////////////////////////////////////////////////////////////////////
//MF522命令字
/////////////////////////////////////////////////////////////////////
#define PCD_IDLE              0x00               //取消当前命令
#define PCD_AUTHENT           0x0E               //验证密钥
#define PCD_TRANSCEIVE        0x0C               //发送并接收数据
#define PCD_RESETPHASE        0x0F               //复位

/////////////////////////////////////////////////////////////////////
//Mifare_One卡片命令字
/////////////////////////////////////////////////////////////////////
#define PICC_ANTICOLL1        0x93               //防冲撞
/////////////////////////////////////////////////////////////////////
//MF522 FIFO长度定义
/////////////////////////////////////////////////////////////////////
#define DEF_FIFO_LENGTH       64                 //FIFO size=64byte

/////////////////////////////////////////////////////////////////////
//MF522寄存器定义
/////////////////////////////////////////////////////////////////////
// PAGE 0
#define     RFU00                 0x00    
#define     CommandReg            0x01    
#define     ComIEnReg             0x02    
#define     DivlEnReg             0x03    
#define     ComIrqReg             0x04    
#define     DivIrqReg             0x05
#define     ErrorReg              0x06    
#define     Status1Reg            0x07    
#define     Status2Reg            0x08     
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D	  
#define     CollReg               0x0E
#define     RFU0F                 0x0F
// PAGE 1     
#define     RFU10                 0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxAutoReg             0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     RFU1A                 0x1A
#define     RFU1B                 0x1B
#define     MifareReg             0x1C
#define     RFU1D                 0x1D
#define     RFU1E                 0x1E
#define     SerialSpeedReg        0x1F
// PAGE 2    
#define     RFU20                 0x20  
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     RFU23                 0x23
#define     ModWidthReg           0x24
#define     RFU25                 0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsCfgReg            0x28
#define     ModGsCfgReg           0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F
// PAGE 3      
#define     RFU30                 0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39  
#define     TestDAC2Reg           0x3A   
#define     TestADCReg            0x3B   
#define     RFU3C                 0x3C   
#define     RFU3D                 0x3D   
#define     RFU3E                 0x3E   
#define     RFU3F		  0x3F

/////////////////////////////////////////////////////////////////////
//和MF522通讯时返回的错误代码
/////////////////////////////////////////////////////////////////////
#define MI_OK                          0
#define MI_NOTAGERR                    (-1)
#define MI_ERR                         (-2)


#endif

mfrc522.h

/////////////////////////////////////////////////////////////////////
//函数原型
/////////////////////////////////////////////////////////////////////
char PcdReset(void);
void PcdAntennaOn(void);
void PcdAntennaOff(void);
char PcdRequest(unsigned char req_code,unsigned char *pTagType);   
char PcdAnticoll(unsigned char *pSnr);                                
char PcdComMF522(unsigned char Command, 
                 unsigned char *pInData, 
                 unsigned char InLenByte,
                 unsigned char *pOutData, 
                 unsigned int  *pOutLenBit);
void WriteRawRC(unsigned char Address,unsigned char value);
unsigned char ReadRawRC(unsigned char Address); 
void SetBitMask(unsigned char reg,unsigned char mask); 
void ClearBitMask(unsigned char reg,unsigned char mask); 
char M500PcdConfigISOType(unsigned char type);
void delay_10ms(unsigned int _10ms);
/////////////////////////////////////////////////////////////////////
//MF522命令字
/////////////////////////////////////////////////////////////////////
#define PCD_IDLE              0x00               //取消当前命令
#define PCD_AUTHENT           0x0E               //验证密钥
#define PCD_TRANSCEIVE        0x0C               //发送并接收数据
#define PCD_RESETPHASE        0x0F               //复位

/////////////////////////////////////////////////////////////////////
//Mifare_One卡片命令字
/////////////////////////////////////////////////////////////////////
#define PICC_ANTICOLL1        0x93               //防冲撞
/////////////////////////////////////////////////////////////////////
//MF522 FIFO长度定义
/////////////////////////////////////////////////////////////////////
#define DEF_FIFO_LENGTH       64                 //FIFO size=64byte

/////////////////////////////////////////////////////////////////////
//MF522寄存器定义
/////////////////////////////////////////////////////////////////////
// PAGE 0
#define     RFU00                 0x00    
#define     CommandReg            0x01    
#define     ComIEnReg             0x02    
#define     DivlEnReg             0x03    
#define     ComIrqReg             0x04    
#define     DivIrqReg             0x05
#define     ErrorReg              0x06    
#define     Status1Reg            0x07    
#define     Status2Reg            0x08     
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D	  
#define     CollReg               0x0E
#define     RFU0F                 0x0F
// PAGE 1     
#define     RFU10                 0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxAutoReg             0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     RFU1A                 0x1A
#define     RFU1B                 0x1B
#define     MifareReg             0x1C
#define     RFU1D                 0x1D
#define     RFU1E                 0x1E
#define     SerialSpeedReg        0x1F
// PAGE 2    
#define     RFU20                 0x20  
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     RFU23                 0x23
#define     ModWidthReg           0x24
#define     RFU25                 0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsCfgReg            0x28
#define     ModGsCfgReg           0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F
// PAGE 3      
#define     RFU30                 0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39  
#define     TestDAC2Reg           0x3A   
#define     TestADCReg            0x3B   
#define     RFU3C                 0x3C   
#define     RFU3D                 0x3D   
#define     RFU3E                 0x3E   
#define     RFU3F		  0x3F

/////////////////////////////////////////////////////////////////////
//和MF522通讯时返回的错误代码
/////////////////////////////////////////////////////////////////////
#define MI_OK                          0
#define MI_NOTAGERR                    (-1)
#define MI_ERR                         (-2)


rc522.c

#include "rc522.h"
#include "main.h"


uchar UID_S50[4];	//S50卡存储
uchar Temp_S50[4];	//临时卡号存储数组
UGroup G[10];		//十组用户存储结构体,具体请看rcc522.h


/********************************************************
* 功    能:寻卡
* 参数说明: req_code[IN]:寻卡方式
*                 0x52 = 寻感应区内所有符合14443A标准的卡
*                 0x26 = 寻未进入休眠状态的卡
*           pTagType[OUT]:卡片类型代码
*                 0x4400 = Mifare_UltraLight
*                 0x0400 = Mifare_One(S50)
*                 0x0200 = Mifare_One(S70)
*                 0x0800 = Mifare_Pro(X)
*                 0x4403 = Mifare_DESFire
返    回: 成功返回MI_OK
******************************************************/
char PcdRequest(unsigned char req_code,unsigned char *pTagType){
   char status;  
   unsigned int  unLen;
   unsigned char ucComMF522Buf[MAXRLEN]; 
   ClearBitMask(Status2Reg,0x08);
   WriteRawRC(BitFramingReg,0x07);
   SetBitMask(TxControlReg,0x03);
   ucComMF522Buf[0] = req_code;
   status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);
   if ((status == MI_OK) && (unLen == 0x10))
   {    
       *pTagType     = ucComMF522Buf[0];
       *(pTagType+1) = ucComMF522Buf[1];
   }
   else
   {   status = MI_ERR;   }  
   return status;
}

/********************************************************
* 功    能:防冲撞
* 参数说明: pSnr[OUT]:卡片序列号,4字节
* 返    回: 成功返回MI_OK
******************************************************/ 
char PcdAnticoll(unsigned char *pSnr)
{
    char status;
    unsigned char i,snr_check=0;
    unsigned int  unLen;
    unsigned char ucComMF522Buf[MAXRLEN]; 
    

    ClearBitMask(Status2Reg,0x08);
    WriteRawRC(BitFramingReg,0x00);
    ClearBitMask(CollReg,0x80);
 
    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x20;

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

    if (status == MI_OK)
    {
    	 for (i=0; i<4; i++)
         {   
             *(pSnr+i)  = ucComMF522Buf[i];
             snr_check ^= ucComMF522Buf[i];
         }
         if (snr_check != ucComMF522Buf[i])
         {   status = MI_ERR;    }
    }
    
    SetBitMask(CollReg,0x80);
    return status;
}

/******************************************************
* 功    能:复位RC522
* 返    回: 成功返回MI_OK
/******************************************************/
char PcdReset(void){
    MF522_RST=1;
	_nop_();
    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//空机器指令
    MF522_RST=0;
//    _nop_();
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    MF522_RST=1;
//     _nop_();
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    WriteRawRC(CommandReg,PCD_RESETPHASE);
//	_nop_();
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	    

    WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363,CRCPreset=01
    WriteRawRC(TReloadRegL,30);          //定时器重装值,分为两个8位寄存器,初始值都为0x00      
    WriteRawRC(TReloadRegH,0);
    WriteRawRC(TModeReg,0x8D);           //内部定时器的设置1000 1101,后四位为TPrescalerReg的高四位
    WriteRawRC(TPrescalerReg,0x3E);      //为TPregScaler低8位,Ftimer = 6.78MHZ/TPreScaler
    WriteRawRC(TxAutoReg,0x40);     
    return MI_OK;
}
/**********************************
* 	设置RC632的工作方式 
**********************************/
char M500PcdConfigISOType(unsigned char type){
   if (type == 'A')                     //ISO14443_A
   { 
       ClearBitMask(Status2Reg,0x08);
       WriteRawRC(ModeReg,0x3D);//3
       WriteRawRC(RxSelReg,0x86);//
       WriteRawRC(RFCfgReg,0x7F);   //4F
   	   WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) 
	   WriteRawRC(TReloadRegH,0);
       WriteRawRC(TModeReg,0x8D);
	   WriteRawRC(TPrescalerReg,0x3E);
	   Delay1ms();
       PcdAntennaOn();
   }
   else{ return -1; }
   
   return MI_OK;
}
/**********************************
* 功    能:读RC632寄存器
* 参数说明:Address[IN]:寄存器地址
* 返    回:读出的值
**********************************/
unsigned char ReadRawRC(unsigned char Address){
     unsigned char i, ucAddr;
     unsigned char ucResult=0;

     MF522_SCK = 0;
     MF522_NSS = 0;
     ucAddr = ((Address<<1)&0x7E)|0x80;

     for(i=8;i>0;i--)
     {
         MF522_SI = ((ucAddr&0x80)==0x80);
         MF522_SCK = 1;
         ucAddr <<= 1;
         MF522_SCK = 0;
     }

     for(i=8;i>0;i--)
     {
         MF522_SCK = 1;
         ucResult <<= 1;
         ucResult|=(bit)MF522_SO;
         MF522_SCK = 0;
     }

     MF522_NSS = 1;
     MF522_SCK = 1;
     return ucResult;
} 

/*************************************************************************
//功    能:写RC632寄存器
//参数说明:Address[IN]:寄存器地址
//          value[IN]:写入的值
*************************************************************************/
void WriteRawRC(unsigned char Address, unsigned char value){  
    unsigned char i, ucAddr;

    MF522_SCK = 0;
    MF522_NSS = 0;
    ucAddr = ((Address<<1)&0x7E);

    for(i=8;i>0;i--)
    {
        MF522_SI = ((ucAddr&0x80)==0x80);
        MF522_SCK = 1;
        ucAddr <<= 1;
        MF522_SCK = 0;
    }

    for(i=8;i>0;i--)
    {
        MF522_SI = ((value&0x80)==0x80);
        MF522_SCK = 1;
        value <<= 1;
        MF522_SCK = 0;
    }
    MF522_NSS = 1;
    MF522_SCK = 1;
}

/*************************************************************************
//功    能:置RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:置位值
*************************************************************************/
void SetBitMask(unsigned char reg,unsigned char mask)  
{
    char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg,tmp | mask);  // set bit mask
}

/*************************************************************************
//功    能:清RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:清位值
*************************************************************************/
void ClearBitMask(unsigned char reg,unsigned char mask)  
{
    char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp & ~mask);  // clear bit mask
}

/*************************************************************************
//功    能:通过RC522和ISO14443卡通讯
//参数说明:Command[IN]:RC522命令字
//          pInData[IN]:通过RC522发送到卡片的数据
//          InLenByte[IN]:发送数据的字节长度
//          pOutData[OUT]:接收到的卡片返回数据
//          *pOutLenBit[OUT]:返回数据的位长度
*************************************************************************/
char PcdComMF522(unsigned char Command, 
                 unsigned char *pInData, 
                 unsigned char InLenByte,
                 unsigned char *pOutData, 
                 unsigned int  *pOutLenBit)
{
    char status = MI_ERR;
    unsigned char irqEn   = 0x00;
    unsigned char waitFor = 0x00;
    unsigned char lastBits;
    unsigned char n;
    unsigned int i;
    switch (Command)
    {
       case PCD_AUTHENT:
          irqEn   = 0x12;
          waitFor = 0x10;
          break;
       case PCD_TRANSCEIVE:
          irqEn   = 0x77;
          waitFor = 0x30;
          break;
       default:
         break;
    }
   
    WriteRawRC(ComIEnReg,irqEn|0x80);
    ClearBitMask(ComIrqReg,0x80);
    WriteRawRC(CommandReg,PCD_IDLE);
    SetBitMask(FIFOLevelReg,0x80);
    
    for (i=0; i<InLenByte; i++)
    {   WriteRawRC(FIFODataReg, pInData[i]);    }
    WriteRawRC(CommandReg, Command);
   
    
    if (Command == PCD_TRANSCEIVE)
    {    SetBitMask(BitFramingReg,0x80);  }
    
//    i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms
 i = 2000;//900,1100,1700,2000,2700
    do 
    {
         n = ReadRawRC(ComIrqReg);
         i--;
    }
    while ((i!=0) && !(n&0x01) && !(n&waitFor));
    ClearBitMask(BitFramingReg,0x80);
	      
    if (i!=0)
    {    
         if(!(ReadRawRC(ErrorReg)&0x1B))
         {
             status = MI_OK;
             if (n & irqEn & 0x01)
             {   status = MI_NOTAGERR;   }
             if (Command == PCD_TRANSCEIVE)
             {
               	n = ReadRawRC(FIFOLevelReg);
              	lastBits = ReadRawRC(ControlReg) & 0x07;
                if (lastBits)
                {   *pOutLenBit = (n-1)*8 + lastBits;   }
                else
                {   *pOutLenBit = n*8;   }
                if (n == 0)
                {   n = 1;    }
                if (n > MAXRLEN)
                {   n = MAXRLEN;   }
                for (i=0; i<n; i++)
                {   pOutData[i] = ReadRawRC(FIFODataReg);    }
				
            }
         }
         else
         {   status = MI_ERR;   }
   }
   

   SetBitMask(ControlReg,0x80);           // stop timer now
   WriteRawRC(CommandReg,PCD_IDLE); 
   return status;
}


/*************************************************************************
//开启天线  
//每次启动或关闭天险发射之间应至少有1ms的间隔
*************************************************************************/
void PcdAntennaOn(){
    unsigned char i;
    i = ReadRawRC(TxControlReg);
    if (!(i & 0x03))
    {
        SetBitMask(TxControlReg, 0x03);
    }
}


/*************************************************************************
//关闭天线
*************************************************************************/
void PcdAntennaOff()
{
    ClearBitMask(TxControlReg, 0x03);
}

/*************************************************************************
// Delay 10ms
*************************************************************************/


void delay_10ms(unsigned int _10ms)
{
#ifndef NO_TIMER2
    RCAP2LH = RCAP2_10ms;
    T2LH    = RCAP2_10ms;
    
    TR2 = TRUE;
    while (_10ms--)
    {
	    while (!TF2);
	    TF2 = FALSE;
    }
    TR2 = FALSE;
#else
    while (_10ms--)
    {
	    delay_50us(19);
	    if (CmdValid)
	        return;
	    delay_50us(20);
	    if (CmdValid)
	        return;
	    delay_50us(20);
	    if (CmdValid)
	        return;
	    delay_50us(20);
	    if (CmdValid)
	        return;
	    delay_50us(20);
	    if (CmdValid )
	        return;
	    delay_50us(20);
	    if (CmdValid)
	        return;
	    delay_50us(20);
	    if (CmdValid)
	        return;
	    delay_50us(20);
	    if (CmdValid)
	        return;
	    delay_50us(20);
	    if (CmdValid)
	        return;
	    delay_50us(19);
	    if (CmdValid)
	        return;
    }
#endif
}

//RFID初始化
void RFID_Init()
{
	PcdReset();
	PcdAntennaOff(); 
    PcdAntennaOn();  
	M500PcdConfigISOType( 'A' );
}

oled.h

#ifndef __OLED_H__
#define __OLED_H__

#include "common.h"
#include "keyboard.h"
#include "user_passwd.h"
#include "iic.h"
#define high 1
#define low 0
#define	Brightness	0xCF 
#define X_WIDTH 	128
#define Y_WIDTH 	64
#define Size 16
#define SSize 2


sbit SCL=P1^2; //串行时钟
sbit SDA=P1^1; //串行数据

typedef struct{
	uchar messege[Size];
}Tips;


typedef struct 
{
	uchar current;
	uchar up;
	uchar down;
	uchar enter;
	void (*current_operation)();
}key_table;


extern uchar TEMP;
extern bit OUT;
extern uchar key_num;
extern uchar key_flag;

void OLED_Fill(unsigned char bmp_dat);
void OLED_CLS(void);
void OLED_Init(void);
void OLED_P8x16Str(uchar x, uchar y,uchar ch[]);
void OLED_P16x16Ch(uchar x, uchar y, uchar N);
void Draw_BMP(uchar x0, y0,x1, y1,uchar BMP[]);


void enterMenu();

uchar getDir();

#endif

oled.c

#include "oled.h"
extern uchar Temp_S50[];
extern uchar UID_S50[];
extern UGroup G[];
unsigned char code F16x16[] = 	  	 
{  	 
//一行大小为[16*16]、个数为8个的空行

0x04,0x04,0x44,0xC4,0x4F,0x44,0x44,0xC4,0x24,0x24,0x2F,0xB4,0x24,0x04,0x04,0x00,
0x40,0x44,0x24,0x24,0x15,0x0C,0x04,0xFE,0x04,0x0C,0x15,0x24,0x24,0x44,0x40,0x00,/*"菜",0*/

0x00,0x00,0xF8,0x49,0x4A,0x4C,0x48,0xF8,0x48,0x4C,0x4A,0x49,0xF8,0x00,0x00,0x00,
0x10,0x10,0x13,0x12,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x12,0x13,0x10,0x10,0x00,/*"单",1*/

0x10,0x10,0xD0,0xFF,0x90,0x14,0xE4,0xAF,0xA4,0xA4,0xA4,0xAF,0xE4,0x04,0x00,0x00,
0x04,0x03,0x00,0xFF,0x00,0x89,0x4B,0x2A,0x1A,0x0E,0x1A,0x2A,0x4B,0x88,0x80,0x00,/*"模",2*/

0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0xFF,0x10,0x10,0x11,0x16,0x10,0x00,
0x00,0x20,0x60,0x20,0x3F,0x10,0x10,0x10,0x00,0x03,0x0C,0x10,0x20,0x40,0xF8,0x00,/*"式",3*/


0x04,0x24,0x64,0xC4,0xE4,0xFC,0xDC,0x70,0x3F,0xCF,0xC8,0x08,0x28,0x38,0x18,0x00,
0x10,0x18,0x0E,0x07,0x83,0xCE,0x6C,0x38,0x1E,0x07,0x07,0x1E,0x38,0x60,0xC0,0x80,/*"欢",4*/

0x40,0x40,0x42,0xCE,0xCC,0x00,0xFC,0xFC,0x06,0x02,0xFC,0xFC,0x04,0xFC,0xFC,0x00,
0x00,0x40,0x60,0x3F,0x3F,0x60,0x4F,0x4F,0x46,0x42,0x7F,0x7F,0x46,0x47,0x43,0x40,/*"迎",5*/

0x00,0x00,0xFE,0xFE,0x02,0xF2,0xF2,0x12,0x12,0xF2,0xF2,0x02,0xFE,0xFE,0x00,0x00,
0x00,0x00,0x7F,0x7F,0x20,0x27,0x27,0x24,0x24,0x27,0x27,0x20,0x7F,0x7F,0x00,0x00,/*"回",6*/

0x10,0x3C,0x2C,0x24,0xA4,0xA4,0xE5,0xE7,0xA6,0x24,0x24,0x24,0xA4,0xB4,0x3C,0x0C,
0x40,0x49,0x49,0x69,0x2D,0x34,0x56,0xDB,0xFF,0x7F,0x0E,0x1B,0x11,0x30,0x20,0x20,/*"家",7*/



//一行大小为[16*16]、个数为8个的空行
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",1*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",1*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",2*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",2*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",3*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",3*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",4*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",4*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",5*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",5*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",6*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",6*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",7*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",7*/



0x40,0x42,0xCE,0xCC,0x00,0x44,0x54,0x54,0x54,0x7F,0x7F,0x54,0x54,0x54,0x44,0x40,
0x00,0x00,0x7F,0x7F,0x30,0x10,0xFF,0xFF,0x15,0x15,0x55,0xD5,0xFF,0x7F,0x00,0x00,/*"请",0*/

0x00,0x00,0xFE,0xFE,0x12,0x12,0xF2,0xF2,0x12,0x1E,0x1E,0xF0,0xF0,0x00,0xFF,0xFF,
0x10,0x1E,0x0F,0x3F,0x3F,0x01,0xFF,0xFF,0x31,0x3F,0x1F,0x0F,0x4F,0xC0,0xFF,0x7F,/*"刷",1*/

0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0xFF,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0x40,
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x02,0x06,0x0C,0x18,0x10,0x00,0x00,/*"卡",2*/

0x08,0x08,0xC8,0xC8,0x48,0x48,0xC8,0xC8,0x08,0xFF,0xFF,0x08,0x09,0xCB,0xCA,0x08,
0x00,0x20,0x67,0x67,0x24,0x34,0x97,0x97,0xD0,0x61,0x37,0x1E,0x3E,0x67,0xF9,0xF8,/*"或",0*/

0x88,0xE8,0x7F,0xDF,0xC8,0x18,0xD8,0xDC,0x56,0xD3,0xD3,0x96,0x9C,0xD8,0xD0,0x10,
0x09,0x19,0x19,0xFF,0xFF,0x05,0xFF,0xFF,0x92,0xFF,0xFF,0x5F,0xDF,0xFF,0x7F,0x00,/*"输",4*/

0x00,0x00,0x00,0x00,0x00,0x01,0xE3,0xFE,0xFC,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0xC0,0x60,0x30,0x1C,0x0F,0x03,0x00,0x00,0x03,0x0F,0x3C,0x70,0xC0,0x80,0x80,/*"入",5*/

0x10,0x9C,0xCC,0x44,0xE4,0xE4,0x95,0xB7,0xE6,0x64,0x34,0x94,0xC4,0xD4,0x9C,0x0C,
0x02,0x02,0x7A,0x7B,0x41,0x43,0x43,0x7E,0x7E,0x42,0x42,0x43,0xFB,0xF8,0x00,0x00,/*"密",6*/

0x04,0x84,0xE4,0xFC,0x5C,0xC4,0xC4,0x02,0xF2,0xF2,0x82,0x82,0xFE,0xFE,0x80,0x80,
0x02,0x03,0x7F,0x7F,0x10,0x3F,0x3F,0x08,0x08,0x08,0x08,0x48,0xC8,0xC8,0x7F,0x3F,/*"码",7*/

//一行大小为[16*16]、个数为8个的空行
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",1*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",1*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",2*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",2*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",3*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",3*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",4*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",4*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",5*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",5*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",6*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",6*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",7*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",7*/
};



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=126-32
  0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,/*"箭头(替换~)",95*/
};

//一个128*64的LOGO图片
uchar code BMP1[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0x80,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x60,
0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x3F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x07,0x03,0x03,0x01,0x00,0x00,0x00,
0x80,0xC0,0xF0,0xFC,0x7E,0x3E,0x1F,0x0F,0x07,0x07,0x03,0x03,0x03,0x01,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC0,0xF8,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x7F,0x1F,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x80,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xF8,0xFC,0xFE,
0xFF,0x7F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xC0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xE0,0xF0,0xF8,0xF8,
0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x0F,0x07,0x07,0x03,0x01,0x01,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x03,0x07,0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
0x0F,0x0F,0x0F,0x07,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0xC0,0xE0,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0x40,0x80,
0x80,0x00,0x00,0x00,0x00,0xE0,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x00,0x00,0x00,0xE0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,
0xE0,0x00,0x00,0x00,0x80,0xC0,0xC0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x40,0xC0,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1F,0x3F,0x7F,0xC0,0x80,0x80,0x9C,0x9C,0x84,0x84,0x84,0x84,0x8C,0xFC,
0xFC,0x00,0x00,0x00,0x00,0xFF,0xFF,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
0x86,0x00,0x00,0x00,0xFF,0xFF,0x00,0x01,0x03,0x06,0x06,0x0C,0x18,0x30,0x60,0xFF,
0xFF,0x00,0x00,0x0E,0x1F,0x3F,0x40,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x40,0x30,0x00,0x00,0x00,0xFF,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"D:\_USER_FILE\桌面\1.BMP",0*/
};


/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
   SCL = high;		
   SDA = high;
   SDA = low;
   SCL = low;
}

/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
   SCL = low;
   SDA = low;
   SCL = high;
   SDA = high;
}

/**********************************************
// 通过I2C总线写一个字节
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		if(IIC_Byte & 0x80)
			SDA=high;
		else
			SDA=low;
		SCL=high;
		SCL=low;
		IIC_Byte<<=1;
	}
	SDA=1;
	SCL=1;
	SCL=0;
}

/*********************OLED写数据************************************/ 
void OLED_WrDat(unsigned char IIC_Data)
{
	IIC_Start();
	Write_IIC_Byte(0x78);
	Write_IIC_Byte(0x40);			//write data
	Write_IIC_Byte(IIC_Data);
	IIC_Stop();
}
/*********************OLED写命令************************************/
void OLED_WrCmd(unsigned char IIC_Command)
{
	IIC_Start();
	Write_IIC_Byte(0x78);            //Slave address,SA0=0
	Write_IIC_Byte(0x00);			//write command
	Write_IIC_Byte(IIC_Command);
	IIC_Stop();
}
/*********************OLED 设置坐标************************************/
void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
	OLED_WrCmd(0xb0+y);
	OLED_WrCmd(((x&0xf0)>>4)|0x10);
	OLED_WrCmd((x&0x0f)|0x01);
} 
/*********************OLED全屏************************************/
void OLED_Fill(unsigned char bmp_dat) 
{
	unsigned char y,x;
	for(y=0;y<8;y++)
	{
		OLED_WrCmd(0xb0+y);
		OLED_WrCmd(0x01);
		OLED_WrCmd(0x10);
		for(x=0;x<X_WIDTH;x++)
		OLED_WrDat(bmp_dat);
	}
}
/*********************OLED复位************************************/
void OLED_CLS(void)
{
	unsigned char y,x;
	for(y=0;y<8;y++)
	{
		OLED_WrCmd(0xb0+y);
		OLED_WrCmd(0x01);
		OLED_WrCmd(0x10);
		for(x=0;x<X_WIDTH;x++)
		OLED_WrDat(0);
	}
}
/*********************OLED初始化************************************/
void OLED_Init(void)
{
	delay(500);//初始化之前的延时很重要!
	OLED_WrCmd(0xae);//--turn off oled panel
	OLED_WrCmd(0x00);//---set low column address
	OLED_WrCmd(0x10);//---set high column address
	OLED_WrCmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	OLED_WrCmd(0x81);//--set contrast control register
	OLED_WrCmd(Brightness); // Set SEG Output Current Brightness
	OLED_WrCmd(0xa1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	OLED_WrCmd(0xc8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	OLED_WrCmd(0xa6);//--set normal display
	OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
	OLED_WrCmd(0x3f);//--1/64 duty
	OLED_WrCmd(0xd3);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	OLED_WrCmd(0x00);//-not offset
	OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
	OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
	OLED_WrCmd(0xd9);//--set pre-charge period
	OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	OLED_WrCmd(0xda);//--set com pins hardware configuration
	OLED_WrCmd(0x12);
	OLED_WrCmd(0xdb);//--set vcomh
	OLED_WrCmd(0x40);//Set VCOM Deselect Level
	OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WrCmd(0x02);//
	OLED_WrCmd(0x8d);//--set Charge Pump enable/disable
	OLED_WrCmd(0x14);//--set(0x10) disable
	OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
	OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7) 
	OLED_WrCmd(0xaf);//--turn on oled panel
	OLED_Fill(0x00); //初始清屏
	OLED_Set_Pos(0,0);
} 



/*******************功能描述:显示8*16一组标准ASCII字符串	 显示的坐标(x,y),y为页范围0~7****************/
void OLED_P8x16Str(uchar x, uchar y,uchar ch[])
{
	unsigned char c=0,i=0,j=0;
	while (ch[j]!='\0')
	{
		c =ch[j]-32;
		if(x>120){x=0;y++;}
		OLED_Set_Pos(x,y);
		for(i=0;i<8;i++)
		OLED_WrDat(F8X16[c*16+i]);
		OLED_Set_Pos(x,y+1);
		for(i=0;i<8;i++)
		OLED_WrDat(F8X16[c*16+i+8]);
		x+=8;
		j++;
	}
}
/*****************功能描述:显示16*16点阵  显示的坐标(x,y),y为页范围0~7****************************/
void OLED_P16x16Ch(uchar x, uchar y, uchar N)
{
	unsigned char wm=0;
	unsigned char adder=32*N;
	OLED_Set_Pos(x , y);
	for(wm = 0;wm < 16;wm++)
	{
		OLED_WrDat(F16x16[adder]);
		adder += 1;
	}
	OLED_Set_Pos(x,y + 1);
	for(wm = 0;wm < 16;wm++)
	{
		OLED_WrDat(F16x16[adder]);
		adder += 1;
	} 	  	
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void Draw_BMP(unsigned char x0, y0,x1, y1,unsigned char BMP[])
{
	unsigned int j=0;
	unsigned char x,y;

  if(y1%8==0) y=y1/8;      
  else y=y1/8+1;
	for(y=y0;y<y1;y++)
	{
		OLED_Set_Pos(x0,y);
    for(x=x0;x<x1;x++)
	    {      
	    	OLED_WrDat(BMP[j++]);
	    }
	}
}



#if 0

/***************功能描述:显示6*8一组标准ASCII字符串	显示的坐标(x,y),y为页范围0~7****************/
void OLED_P6x8Str(uchar x, uchar y,uchar ch[])
{
	unsigned char c=0,i=0,j=0;
	while (ch[j]!='\0')
	{
		c =ch[j]-32;
		if(x>126){x=0;y++;}
		OLED_Set_Pos(x,y);
		for(i=0;i<6;i++)
		OLED_WrDat(F6x8[c][i]);
		x+=6;
		j++;
	}
}
#endif

Tips code status[5]=
{
	{"OK."},
	{"Error,Retry."},
	{"1"}
};
/**************************************************
*
*			菜单库
*
***************************************************/
uchar func_index = 0;
//	Tips code line[4]={{"Selection 1    "},{"Selection 2    "},{"Selection 3    "},{"Selection 4    "},};
Tips code line[4]={
//  ("           ADD ");
	{"Modify U PWD   "},
	{"   S50 CARDs   "},
	{"LOG MESSEGES   "},
	{"        Home   "},};
	
//	Tips code lines[4]={{"Selection 1~  "},{"Selection 2~  "},{"Selection 3~  "},{"Selection 4~  "}};
Tips code lines[4]={
//  ("           ADD ");
	{"Modify U PWD  ~"},
	{"   S50 CARDs  ~"},
	{"LOG MESSEGES  ~"},
	{"        Home  ~"}
};


/**************
*	以下函数func0~func14都是菜单功能的循环
*	包含结构体和函数指针的知识,详情请见解析
* 	https://zhidao.baidu.com/question/447214291.html
*********************/	

void func0()		//OLED显示:菜单模式	func_index = 0;
{
	EA = 0;
	OLED_CLS();
	OLED_P16x16Ch(23,3,0);
	OLED_P16x16Ch(40,3,1);
	OLED_P16x16Ch(57,3,2);
	OLED_P16x16Ch(74,3,3);
	EA = 1;
}
	
void func1()	//OLED显示:Modify User Passwd
{
	EA = 0;
	OLED_P8x16Str(0,6,line[3].messege);
	OLED_P8x16Str(0,4,line[2].messege);
	OLED_P8x16Str(0,2,line[1].messege);
	OLED_P8x16Str(0,0,lines[0].messege);
	EA = 1;
}
void func2()	//OLED显示:ADD S50 Cards
{
	EA = 0;
	OLED_P8x16Str(0,0,line[0].messege);
	OLED_P8x16Str(0,2,lines[1].messege);
	OLED_P8x16Str(0,4,line[2].messege);
	OLED_P8x16Str(0,6,line[3].messege);
	EA = 1;
}
void func3()	//OLED显示:LOG MESSEGES
{
	EA = 0;
	OLED_P8x16Str(0,0,line[0].messege);
	OLED_P8x16Str(0,2,line[1].messege);
	OLED_P8x16Str(0,4,lines[2].messege);
	OLED_P8x16Str(0,6,line[3].messege);
	EA = 1;
}
void func4()	//OLED显示:HOME
{
	EA = 0;
	OLED_P8x16Str(0,0,line[0].messege);
	OLED_P8x16Str(0,2,line[1].messege);
	OLED_P8x16Str(0,4,line[2].messege);
	OLED_P8x16Str(0,6,lines[3].messege);
	EA = 1;
}

void func5()	//修改用户密码,执行完毕,func_index = 7(欢迎回家)
{
	EA = 0;
	OLED_CLS();
	OLED_P8x16Str(40,0,"Input");
	OLED_P8x16Str(15,2,"Super Passwd");
	OLED_P8x16Str(100,4,"...");
	EA = 1;
	if(modify()) {EA = 0; OLED_CLS();OLED_P8x16Str(30,3,"Successful!");Delay500ms();EA=1;}
	else {EA=0;OLED_CLS();OLED_P8x16Str(40,4,"Retry!");Delay500ms();EA =1;}
	func_index = 7;
	OUT = 1;
	EA = 1;
}

void func6()//		第四行的Home返回到欢迎界面
{
	OUT = 1;
	TEMP = 0;
	func_index = 7;
	EA = 0;
	OLED_CLS();
	OLED_P8x16Str(3,4,"BACKING HOME!");
	Delay500ms();
//	OLED_P16x16Ch(23,3,1);
//	OLED_P16x16Ch(40,3,2);
//	OLED_P16x16Ch(57,3,3);
//	OLED_P16x16Ch(74,3,4);
	EA = 1;

}
void func7()//OLED显示:“欢迎回家”,内含返回while循环的关键函数
{
	EA = 0;
	OLED_CLS();
	OLED_P16x16Ch(23,3,4);
	OLED_P16x16Ch(40,3,5);
	OLED_P16x16Ch(57,3,6);
	OLED_P16x16Ch(74,3,7);
	OUT = 1;
	TEMP = 0;
	EA = 1;
}

void func8()//版本信息
{
	EA = 0;
	OLED_CLS();
	OLED_P8x16Str(0,0,"Version Messege");
	OLED_P8x16Str(40,2,"V3.99");
	OLED_P8x16Str(30,4,"By LAH");
	OLED_P8x16Str(5,6," 2020421 Update");
	EA = 1;
}

void func9(){
	EA = 0;
	OLED_CLS();
	OLED_P8x16Str(0,3,"Door Is Opening.");
	EA = 1;
	Delay500ms();
	MotroOpenDoor();
	func_index = 7;
	OUT = 1;
	TEMP = 0;
}
void func10(){
	bit Cards_OUT = 0;
	EA = 0;
	OLED_CLS();
	OLED_P8x16Str(40,0,"Input");
	OLED_P8x16Str(15,2,"Super Passwd");
	OLED_P8x16Str(100,4,"...");
	EA = 1;
	if(verif_admin_passwd()) {
		EA = 0; 
		OLED_CLS();
		OLED_P8x16Str(30,3,"Successful!");Delay500ms();
		OLED_CLS();
		OLED_P8x16Str(30,3,"Show Card!");
		EA=1;
		while(!Cards_OUT){
			if(PcdRequest(0x52,Temp_S50) == MI_OK)
			{
				if(PcdAnticoll(UID_S50)== MI_OK )
				{
					save_UID_In_EEPROM(UID_S50);
					Delay200ms();
					Cards_OUT = 1;
				}
			}
		}
		EA = 0; 
		OLED_CLS();
		OLED_P8x16Str(30,2,"Successful!");
		OLED_P8x16Str(30,4,"Updating...");
		Delay500ms();
		read_UID_From_EEPROM(G);
		OLED_CLS();
		EA=1;
	}
	else {EA=0;OLED_CLS();OLED_P8x16Str(40,4,"Retry!");Delay500ms();EA =1;func_index = 7; OUT = 1;TEMP = 0;return;}
	OUT = 1;
	TEMP = 0;
	func_index = 7;
}

void func11(){
	EA = 0;
	OLED_CLS();
	OLED_P8x16Str(0,0,"Warning!");
	OLED_P8x16Str(40,3,"CLEAN");
	OLED_P8x16Str(40,3,"ALl");
	OLED_P8x16Str(40,3,"UID");
	EA = 1;
	clearAll();
	OUT = 1;
	TEMP = 0;
	func_index = 7;
}


void func12(){
	EA = 0;
	
	OLED_P8x16Str(0,0,"           ADD~");
	OLED_P8x16Str(0,2,"       DEL UID ");
	OLED_P8x16Str(0,4,"          Back ");
	OLED_P8x16Str(0,6,"               ");
	EA = 1;
}

void func13(){
	EA = 0;

				    //"Modify U PWD   "
	OLED_P8x16Str(0,0,"           ADD ");
	OLED_P8x16Str(0,2,"       DEL UID~");
	OLED_P8x16Str(0,4,"          Back ");
	OLED_P8x16Str(0,6,"               ");
	EA = 1;
}

void func14(){
	EA = 0;
	OLED_P8x16Str(0,0,"           ADD ");
	OLED_P8x16Str(0,2,"       DEL UID ");
	OLED_P8x16Str(0,4,"          Back~");
	OLED_P8x16Str(0,6,"               ");
	EA = 1;
}

key_table code table[20] =
{
//	{current,up,down,enter,(*current_operation)},
	{0,4,1,0,(*func0)},
	{1,4,2,5,(*func1)},//第一行"Modify User Passwd",确认键进入函数5(修改用户密码),
	{2,1,3,12,(*func2)},//第二行 S50 Cards
	{3,2,4,8,(*func3)},//第三行“LOG Messeges”
	{4,3,1,6,(*func4)},//第四行“HOME”
	
	{5,0,0,0,(*func5)},//功能函数:修改密码函数
	{6,2,0,7,(*func6)},//功能函数:Home返回键,提示“Backing HOME!”,执行完func6,赋值func_index为7,退出后执行函数7,提示“欢迎回家”,之后重回到while大循环中
	{7,7,7,7,(*func7)},//功能函数:OLED显示:“欢迎回家”,内含返回while循环的关键函数
	{8,7,7,7,(*func8)},//功能函数:显示版本等信息,按任意功能键返回HOME
	{9,9,9,9,(*func9)},	//Null
	
	{10,7,7,7,(*func10)},		//添加新S50功能函数
	{11,7,7,7,(*func11)},		//清除全部UID函数
	
	{12,14,13,10,(*func12)},	//显示 ADD
	{13,12,14,11,(*func13)},	//显示DEL跳转func11清除UID函数
	{14,13,12,7,(*func14)},		//显示Back
};



void enterMenu()
{
	EA = 0;
	Draw_BMP(0,0,128,8,BMP1);
	Delay1000ms();
	EA = 1;
}

uchar getDir()// 获取函数下标func_index
{
	uchar temp = 0;
	key_flag = 0;
	temp = key_num;
	if(temp == 3){	func_index = table[func_index].up;	key_num = 99; key_flag = 1;return temp;	}				//上
	else if(temp == 15){	func_index = table[func_index].down; key_num = 99; key_flag = 1;	return temp;	}	//下
	else if(temp == 14){	func_index = table[func_index].enter; key_num = 99; key_flag = 1;	return temp;}		//确定键
	else return 0;
}

标签:RFID,0x08,uchar,0x20,门禁系统,0x00,单片机,0x80,define
来源: https://blog.csdn.net/AISc_O/article/details/105861230