B011 - 基于51的多功能指纹智能锁

任务列表

在这里插入图片描述

效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

原理图

在这里插入图片描述

设计资料

由于本设计使用了多个串口,比如使用了GSM通信,指纹识别通信,语音播报通信,这三个模块和单片机采用的通信方式都是串口通信,设置匹配的波特率。本系统采用了多种模式的输入,矩阵键盘,红外遥控,IC卡输入等等,因此设计的难度注意在于多模块的整合,系统工作量是比较大了。讲解包含测试过程的资料都整理的相对齐全。
在这里插入图片描述

源代码

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

* 文件名称:基于51的多功能指纹智能锁

* 实验目的:1.

* 2.

* 程序说明:完整程序Q:2772272579;@: itworkstation@hotmail.com

* 日期版本:基本逻辑都在main程序。需完整工程请联系我。可定制。

*******************************************************************************/
#include"config.h"
#include"delay.h"
uchar Xuhao_Check();
void KeyPress(uchar keycode);
void set_password(void);
void Timer0Init(void);

u8 EEROM_TEST[10]={0};
u8 EEROM_CHECK;

/******************** IO配置函数 **************************/
//sbit  Lock=P5^4;
sbit  Finger_Touch=P4^5;
void GPIO_config(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义

	GPIO_InitStructure.Pin  = GPIO_Pin_4;		//指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
	GPIO_InitStructure.Mode = GPIO_OUT_PP;		//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
	GPIO_Inilize(GPIO_P5,&GPIO_InitStructure);	//初始化

	GPIO_InitStructure.Pin  = GPIO_Pin_0;		//指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
	GPIO_InitStructure.Mode = GPIO_PullUp;		//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
	GPIO_Inilize(GPIO_P0,&GPIO_InitStructure);	//初始化

	GPIO_InitStructure.Pin  = GPIO_Pin_5;		//指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
	GPIO_InitStructure.Mode = GPIO_PullUp;		//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
	GPIO_Inilize(GPIO_P4,&GPIO_InitStructure);	//初始化
}
unsigned char xdata g_ucTempbuf[20];
uchar xdata Xuhao_Panduan[4];
uchar code Xuhao_SQL[]={
0x49,0X10,0XFC,0XB9,	// 蓝色卡
0X8C,0XF3,0XC3,0XDE,   // 白色卡	 
};
unsigned char code password_r[6] = {1,2,3,4,5,6};	//定义初始密码.
unsigned char code password_gl[6] = {8,8,8,8,8,8};	//定义管理员密码.
unsigned char password[6];							//定义密码暂存
const unsigned char muntochar[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//1602液晶数字转字符
unsigned char password_bj[6] = {20,20,20,20,20,20};	//密码比较
bit password_dis = 1;					//声明1个变量,用来记录是显示密码还是隐藏密码.
unsigned char in_password_mun = 255;		//声明1个变量,用来记录密码输入位数.
unsigned char flag_Lock = 0;			//声明1个变量,用来记录密码锁延时关闭时间.
unsigned int err_time = 0;				//声明1个变量,用来记录3次错误输入密码报警时间
unsigned char password_start = 0;		//声明1个变量,用来记录按键延时时间.达到3秒密码复位.
bit password_ok_open = 0;				//定义1个变量,用来记录密码输入正确标志,0表示不成功.1表示成功.
unsigned char password_err_mun = 0;	//声明1个变量用来记录密码输入错误次数.
bit  flag_200ms = 0;								//定义200mS标志位.为1表示200MS到,为0表示没有到.

bit Flag_FPM10A_Set=0;  //指纹设置:1;正常检测:0
char local_date=0,base_date=0;//全局变量,当前箭头位置

bit Flag_SIMSendWarning=0;//发送报警短信标志
unsigned char  SIM_Commend01[]="123456open" ;	 //开锁命令
unsigned char  SIM_Commend02[]="123456close" ;	 //关锁命令
uchar Card_Erro=0,Finger_Erro=0;
void main()
{
	unsigned char keycode; //声明1个变量,用来暂存按键键值.
	unsigned char status=0,i=0,Client=0;
	uchar IR_Rec=0,IR_value=99;
	int ret=0;	 //GSM信号提示

	EX0init();	TIM1_Init();
	GPIO_BuzzConfig();
	GPIO_config();
	Keyboard_GPIO_Config();

	Init_1602();
	write_string(1,0," Welcome To Use ");	
	write_string(2,0," System Init... ");
	delay_ms(1000);	  
	UART4_Init();
	Device_Check();		   	//校对指纹模块是否接入正确,液晶做出相应的提示
	write_com(0x01);   //清屏

	EEPROM_read_n(EEROM_USEADDR,&EEROM_CHECK,1);
	if(EEROM_CHECK == EEROM_CHECK_VALUE)  //旧单片机,已存储密码
	{
		 EEPROM_read_n(EEROM_USEADDR+1,password,6);
	}
	else
	{
		 Beep=0;
		 delay_ms(200);
		 EEPROM_write_n(EEROM_USEADDR,password_r,6);
		 Beep=1;
	}
	/*----GSM配置液晶显示----*/
	write_com(0x01);   //清屏
	write_string(1,0,"   GSM Config   ");
	write_string(2,0,"   Waiting....  ");	
	Timer0Init();
	UART2_Init();
	for(i = 0;i < STABLE_TIMES;i++)//等待GSM网络稳定
	{
		delay_20ms(1);
	}
	ret = check_status();			 //初始化配置	  
	if(ret == 1)
	{
		write_string(2,0,"Docking  success");	
		delay_ms(200);
		ret = config_format();//配置
		if(ret == 1)
		{
			write_string(2,0,"Config   success");
			delay_ms(500);
		}
		else
		{
			write_string(2,0,"Config   failure");	
			delay_ms(500);
		}
	}
	else
	{
		write_string(2,0,"Docking  failure");
		delay_ms(500);
	}
	CLR_Buf();//清空串口数组,准备接收 GSM信息

	/*----开机液晶显示----*/
	write_com(0x01);   //清屏
	write_string(1,0," Password Lock  ");	
	write_string(2,0," Input:         ");

	PcdGpioConfig();
	PcdReset();		//功    能:复位RC522
    PcdAntennaOff();  //关闭天线
	delay_ms(2);
    PcdAntennaOn(); //开启天线  每次启动或关闭天险发射之间应至少有1ms的间隔

	UART3_Init();
	delay_ms(1000);
	MX_6x00SendCmd(MX_SET_VOL,0x14);  //设置音量 0x00-0x1E :0-30
	delay_ms(100);
	MX_6x00SendCmd(MX_SET_CYCLICAL,MX_CYCLICAL_SINGLE_STOP);  //设置播放模式:单曲停止
	delay_ms(100);
	MX_6x00SendCmd(SPECIFIED_SONG,1);//播报语音		
	while(1)
	{			
		if(Flag_FPM10A_Set)	 //指纹设置界面
		{
			if(local_date==0)
			{
				LCD1602_Display(0x80,  " *",0,2);	//	LCD1602_Display(0x80,  "FSFSFSF",5,2);
				LCD1602_Display(0xc0,  "  ",0,2);
				LCD1602_Display(0xc0+8,"  ",0,2);	
			}
			else if(local_date==1)
			{
				LCD1602_Display(0x80,  "  ",0,2);
				LCD1602_Display(0xc0,  " *",0,2);
				LCD1602_Display(0xc0+8,"  ",0,2);	
			}
			else if(local_date==2)
			{
				LCD1602_Display(0x80,  "  ",0,2);
				LCD1602_Display(0xc0,  "  ",0,2);
				LCD1602_Display(0xc0+8," *",0,2);	
			}	
			keycode = Getkeyboard();	
			//有效键值0-15
			if (keycode<16)
			{
			   Buzz_Times(1);
			   if(keycode==13)//确认键	
			 	 {
				 	switch(local_date)
					{
							case 0:  //搜索指纹						
							FPM10A_Find_Fingerprint();	
							write_com(0x01);   //清屏
							/**************回到主功能界面****************/
							write_string(1,0,"  search finger ");	 //第一排显示搜索指纹
							write_string(2,0,"  Add     delete");	 //添加和删除指纹																							
							break;	
							
							case 1:	 //添加指纹
							FPM10A_Add_Fingerprint();
							write_com(0x01);   //清屏
							/**************回到主功能界面****************/
							write_string(1,0,"  search finger ");	 //第一排显示搜索指纹
							write_string(2,0,"  Add     delete");	 //添加和删除指纹
							break; 					
							
							case 2:	//清空指纹
							FPM10A_Delete_All_Fingerprint();
							write_com(0x01);   //清屏
							/**************回到主功能界面****************/
							write_string(1,0,"  search finger ");	 //第一排显示搜索指纹
							write_string(2,0,"  Add     delete");	 //添加和删除指纹
				  			break;
					}
				}			    
				 //切换键
				if(keycode == 12)
				{				
		  	 		if(local_date<=2)
					{
						local_date++;
						if(local_date==3)
							local_date=0;						
					}		
				}
				if(keycode == 10)
				{				
		  	 		Flag_FPM10A_Set=!Flag_FPM10A_Set;
					if(Flag_FPM10A_Set)	
					{
						write_com(0x01);   //清屏
						/**************回到主功能界面****************/
						write_string(1,0,"  search finger ");	 //第一排显示搜索指纹
						write_string(2,0,"  Add     delete");	 //添加和删除指纹
					}
					else
					{
						write_com(0x01);   //清屏
						 /*----开机液晶显示----*/
						write_string(1,0," Password Lock  ");	
						write_string(2,0," Input:         ");
					}	
				}
			}
		}
		else		//正常界面
		{
			if(find_string_flag == 1)
			{
				delay_ms(1000);//延时一点,让串口把数据接收完成
				if(Find("+CMTI"))//说明接收到了短信
				{
					 ret = read_message();					 
					 if(ret == 1)
					 {
					 	for(i=0;i<6;i++)
						{
							SIM_Commend01[i]= password[i]+0x30;	  //替换为正确密码
							SIM_Commend02[i]= password[i]+0x30;	
						}
					 	 if(Find(SIM_Commend01))
						 {
						 	Lock=0;
							MX_6x00SendCmd(SPECIFIED_SONG,2);//播报语音	

							extract_phone_number();	
							ret = send_text_message("The lock is open.");

							password_ok_open = 1;								//密码正确致1,表示输入成功.
							password_err_mun = 0;								//密码错误次数清0.
							write_string(2,0," Input:         ");		//显示还原.
							write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
							for(i = 0;i < 6;i++)								//循环6次
								password_bj[i] = 20;							//置密码比较数组里的数还原到20.
							in_password_mun = 255;								//记录密码输入位数还原.
						 }
						 if(Find(SIM_Commend02))
						 {
							 	if(Lock==0)
							 	 	Lock=1;
							 extract_phone_number();	
							 ret = send_text_message("The lock is closed.");
						 }
					 }
					 CLR_Buf();
				}		
				CLR_Buf();	
			}
			if(Finger_Touch)  //检测到有手指按下,跳转到指纹检测
			{
				Finger_Erro+=FPM10A_Find_Fingerprint_Touch();
			}
			IR_Rec=Handle_Hongwai();
			if(IR_Rec!=0)	
			{
				Buzz_Times(1);
				IR_value=IR_code(IR_Rec);
				 /*=======密码输入处理========*/
				if(IR_value < 10)		//如果输入的键值是数字键
				{
					in_password_mun++;										//每输入一位密码,位数自增1.
					if(in_password_mun == 6)								//密码输入位数控制在6位
						in_password_mun = 5;
			
					password_bj[in_password_mun] = IR_value;					//把键值存入密码比较数组
	
					if(password_dis == 0)									//如果密码是显示的.输入密码显示
					{
						write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
						for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
						{
							if(password_bj[i] != 20)						//如果不是原始数值,说明有新的密码
								write_date(muntochar[password_bj[i]]);	//把新的密码显示在屏上
						}
					}
					if(password_dis == 1)									//如果密码是隐藏的.就显示*号
					{
						write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
						for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
						{
							if(password_bj[i] != 20)						//如果不是原始数值,说明有新的密码
								write_date('*');						//把输入的密码以*号显示出来.
						}
					}
				}
				else
					KeyPress(IR_value);
			}
			keycode = Getkeyboard();	
			//有效键值0-15
			if (keycode<16)
			{
				 Buzz_Times(1);
				 /*=======密码输入处理========*/
				if(keycode < 10)		//如果输入的键值是数字键
				{
					in_password_mun++;										//每输入一位密码,位数自增1.
					if(in_password_mun == 6)								//密码输入位数控制在6位
						in_password_mun = 5;
			
					password_bj[in_password_mun] = keycode;					//把键值存入密码比较数组
	
					if(password_dis == 0)									//如果密码是显示的.输入密码显示
					{
						write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
						for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
						{
							if(password_bj[i] != 20)						//如果不是原始数值,说明有新的密码
								write_date(muntochar[password_bj[i]]);	//把新的密码显示在屏上
						}
					}
					if(password_dis == 1)									//如果密码是隐藏的.就显示*号
					{
						write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
						for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
						{
							if(password_bj[i] != 20)						//如果不是原始数值,说明有新的密码
								write_date('*');						//把输入的密码以*号显示出来.
						}
					}
				}
				else
					KeyPress(keycode);		 
			}	
			status = PcdRequest(PICC_REQALL, g_ucTempbuf);//寻卡
			delay_ms(20);	
			if(status == MI_OK )	//若得到卡,则进行判断卡序号
			{
				status = PcdAnticoll(g_ucTempbuf);//防冲撞
				if (status != MI_OK)
		        {        }
				for(i=0;i<4;i++)		 //卡序列号
				{
					Xuhao_Panduan[i]=g_ucTempbuf[i];
	//				write_hex(2,0+i*2,Xuhao_Panduan[i]);		
				}
				delay_ms(1000);
				Client=Xuhao_Check();
				if(Client!=0)
				{
				 	Lock=0;
					MX_6x00SendCmd(SPECIFIED_SONG,2);//播报语音	

					password_ok_open = 1;								//密码正确致1,表示输入成功.
					password_err_mun = 0;								//密码错误次数清0.
					write_string(2,0," Input:         ");		//显示还原.
					write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
					for(i = 0;i < 6;i++)								//循环6次
						password_bj[i] = 20;							//置密码比较数组里的数还原到20.
					in_password_mun = 255;								//记录密码输入位数还原.
				}
				else	 //未登记的卡
				{
					write_string(2,0,"CardUnregistered");		//显示还原.
					Card_Erro++;
					Buzz_Times(3);
					write_string(2,0," Input:         ");		//显示还原.
				}
			}
			else	 //没有得到卡
	        {    
				PcdReset();
				PcdAntennaOff(); 
				delay_ms(2);
				PcdAntennaOn();
	        }
			//标记1		
			if(flag_200ms == 1)									//如果200ms时间到.
			{
				flag_200ms = 0;									//200ms标志清0
	
				/*--------延时关闭锁---------*/
				if(Lock == 0)									//如果锁是打开的.
				{
					Flag_SIMSendWarning=0;	 //	短信报警恢复
					err_time = 0;							//错误报警延时清0.
					password_err_mun = 0;					//错误次数清0.
					Card_Erro=0;
					Finger_Erro=0;
					Beep = 1;

					flag_Lock++;								//锁延时自增
					if(flag_Lock >= 5 * 10)					//如果延时到达10秒  
					{
						flag_Lock = 0;							//延时清0.
					    Lock = 1;								//关闭密码锁

						password_err_mun = 0;					//错误次数清0.
						Card_Erro=0;
						Finger_Erro=0;
					}
				}else											//如果锁是关闭的.
					flag_Lock = 0;								//延时清0.
	
				/*--------输入错误密码3次,报警1分钟---------*/
				if(password_err_mun >= 3 || Card_Erro>=3 || Finger_Erro>=3)
				{					
					err_time ++;								//错误报警延时自增
					Beep = 0;									//蜂鸣器报警
					if(Flag_SIMSendWarning==0)
					{
						send_text_message_set("Alert, Trespass!!!"); //发送报警短信一次
						Flag_SIMSendWarning=1;
					}
					if(err_time >= 5 * 20)						//如果达到20S
					{
						Flag_SIMSendWarning=0;	 //	短信报警恢复
						err_time = 0;							//错误报警延时清0.
						password_err_mun = 0;					//错误次数清0.
						Card_Erro=0;
						Finger_Erro=0;
						Beep = 1;
					}					
				}
			}
		}
		
	} //while
}
//按键响应程序,参数是键值
//返回键值:
//         1    2    3    10	   //10: 指纹界面/正常界面
//         4    5    6    11	   //11: 修改密码
//         7    8    9    12	   //12: 手动关闭锁 
//         14   0    15   13	   //14:显示/隐藏输入的密码    15:删除    13:确认

void KeyPress(uchar keycode)
{
	uchar i=0;
	switch (keycode)
	{
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
		case 9:	

			break;
		case 15:  	 	/*---------功能(删除1位密码)-----------*/
			if(in_password_mun != 255)
			{
				password_bj[in_password_mun] = 20;
				write_com(0XC7 + in_password_mun);				//液晶AC控制到第2行的第7位置.											
				write_date(' ');
				write_com(0XC7 + in_password_mun);				//液晶AC控制到第2行的第7位置.											
				if(in_password_mun > 0)
					in_password_mun--;
				else
					in_password_mun = 255;									//记录密码输入位数还原.
			}
			break;
		case 13:	  /*---------功能(确定密码是否正确)-----------*/
				for(i = 0;i < 6;i++)										//先比较输入密码
				{
					if(password[i] != password_bj[i])						//如果密码不匹配.
						break;												//跳出for循环.
					
					if(i == 5)												//如果循环6次没有跳出for循环,密码输入正确.
					{
						password_ok_open = 1;								//密码正确致1,表示输入成功.
						password_err_mun = 0;								//密码错误次数清0.
					}
				}	
				if(password_ok_open != 1)										//如果输入密码不正确,再来检测管理员密码如果继电器没有打开,说明密码输入不正确
				{
					for(i = 0;i < 6;i++)										//比较6位密码.
					{
						if(password_bj[i] != password_gl[i])					//如果密码不匹配.
						{
							password_err_mun++;									//密码错误次数自增1.
							write_string(2,0,"    Error  ");
							write_date(muntochar[password_err_mun]);		//密码输入错误次数显示在屏上
							write_string(2,12,"    ");
							Beep = 0;											//蜂鸣提示.
							delay_ms(150);
							Beep = 1;
							delay_ms(250);
							Beep = 0;
							delay_ms(350);
							Beep = 1;
							break;												//跳出for循环.
						}
						
						if(i == 5)												//如果密码输入正确.
						{
							password_ok_open = 1;								//密码正确致1,表示输入成功.
							password_err_mun = 0;								//密码错误次数清0.
						}
					}
				}				
				if(password_ok_open != 1)										//如果密码错误,延时一段时间.
				{
					delay_ms(450);												//延时一段时间.
					Beep = 0;
					delay_ms(550);
					Beep = 1;
				}
				else															//如果正确.
				{
					Lock = 0;													//打开继电器,密码锁开.
					MX_6x00SendCmd(SPECIFIED_SONG,2);//播报语音	
					password_ok_open = 0;										//输入密码成功标志置位.
				}
				write_string(2,0," Input:         ");		//显示还原.
				write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
				for(i = 0;i < 6;i++)								//循环6次
					password_bj[i] = 20;							//置密码比较数组里的数还原到20.
				in_password_mun = 255;								//记录密码输入位数还原.
			break;
		case 14:          /*---------功能(显示输入密码)-----------*/	   
			if(password_dis == 1)
				{
					write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
					for(i = 0;i < 6;i++)
					{
						if(password_bj[i] != 20)
							write_date(muntochar[password_bj[i]]);
					}
				}
				if(password_dis == 0)
				{
					write_com(0XC7);							//液晶AC控制到第2行的第7位置.											
					for(i = 0;i < 6;i++)
					{
						if(password_bj[i] != 20)
							write_date('*');
					}
				}
				password_dis = !password_dis;		
			break;
		case 11:   	  /*---------功能(设置密码)-----------*/
			if(Lock == 0)						//如果密码设置按键被按下,并且密码锁是打开的.
			{
				set_password();									//进入密码设置.
				Lock = 1;										//密码锁关闭.
				for(i = 0;i < 6;i++)							//循环6次,清空密码
					password_bj[i] = 20;						//置密码比较数组里的数还原到20.
				in_password_mun = 255;							//记录密码输入位数还原.
			}
			break;
		case 12:   /*---------功能(手动关闭密码锁)-----------*/ 
			if(Lock == 0)						//如果手动关闭锁按键被按下,并且密码锁是打开的.
				Lock = 1;										//密码锁关闭.	 
			break;
		case 10:
			if(Lock == 0)
			{
				Flag_FPM10A_Set=!Flag_FPM10A_Set;
				if(Flag_FPM10A_Set)
				{
					write_com(0x01);   //清屏
					/**************进入主功能界面****************/
					write_string(1,0,"  search finger ");	 //第一排显示搜索指纹
					write_string(2,0,"  Add     delete");	 //添加和删除指纹
				}
				else
				{
					write_com(0x01);   //清屏
					 /*----开机液晶显示----*/
					write_string(1,0," Password Lock  ");	
					write_string(2,0," Input:         ");
				}
			}
			break;
	    default:break;
   }
}	
uchar Xuhao_Check()
{
	uchar i=0;
	for(i=0;i<4;i++)
	{
		if(Xuhao_Panduan[i]==Xuhao_SQL[i])
			continue;
		else
			break;
	}
	if(i==4)
	{
		return 1; //识别出为客户1 :绿色卡	
	}	
	for(i=0;i<4;i++)
	{
		if(Xuhao_Panduan[i]==Xuhao_SQL[i+4])
			continue;
		else
			break;
	}
	if(i==4)
	{
		return 2; //识别出为客户2 :白色卡	
	}
	else
	{
		return 0; //不在数据库内
	}
}
void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式	16位自重载
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
}

static void Timer0_irt()interrupt 1
{
   static unsigned int time_add = 0,time_add02=0;					//声明一个变量用来记录中断次数,达到记时目的.
	
    time_add ++;										//记录中断次数
	if(time_add == 200)									//200mS
	{ 	
		flag_200ms = 1;									//200mS标志置位
		time_add = 0;									//时间记录清0
	}
	time_add02++;
	if(time_add02 == 20)
	{
		time_add02=0;
		if(count_20ms > 0) //20ms延时计数器
		{
			count_20ms--;
		}
	}
}
/*==================密码设置==================*/
void set_password(void)
{
	unsigned char key_16mun;							//声明1个变量,用来暂存按键的值.
	unsigned char in_password_mun = 255;				//声明1个变量,用来记录密码输入位数.
	unsigned char intput = 1;							//声明1个变量,用来记录是输入第1次还是第2密码
	unsigned char password1[] = {20,20,20,20,20,20};	//暂存第1次输入的密码
	unsigned char password2[] = {20,20,20,20,20,20};	//暂存第2次输入的密码
	unsigned char i;									//声明1个变量,用来循环用.
	unsigned char out_time = 0;							//声明1个变量,用来记录无操作自动退出时间

	/*----开机液晶显示----*/
	write_string(1,0,"Input1:         ");		//液晶显示的字符
	write_string(2,0,"Input2:         ");		//液晶显示的字符
	write_com(0X87);							//液晶AC控制到第1行的第7位置.
	while(1)
	{
		key_16mun = Getkeyboard();							//把扫描到的按键值暂存,方便处理.	
		if(key_16mun != 99)							//只要有按键按下,就蜂鸣一声.
		{
			Beep = 0;									//蜂鸣开.
			delay_ms(100);								//延时一段时间.
			Beep = 1;									//蜂鸣关.
			out_time = 0;								//清退出时间.
		}

		/*=======密码输入处理========*/
		if(key_16mun < 10)											//如果输入的键值是数字键
		{
			in_password_mun++;										//每输入一位密码,位数自增1.
			if(in_password_mun == 6)								//密码输入位数控制在6位
				in_password_mun = 5;	

			if(intput == 1)											//如果是第1次输入新密码.
			{
				password1[in_password_mun] = key_16mun;				//把键值存入第1次暂存密码数组			
				write_com(0X87);							//液晶AC控制到第1行的第7位置.											
				for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
				{
					if(password1[i] != 20)							//如果不是原始数值,说明有新的密码
					{
						if(password_dis == 0)
							write_date('*');						//把输入的密码以*号显示出来.
						else
							write_date(muntochar[password1[i]]);
					}
				}
			}
			else 													//如果是第2次输入的密码
			{
				password2[in_password_mun] = key_16mun;				//把键值存入第2次暂存密码数组			
				write_com(0Xc7);							//液晶AC控制到第2行的第7位置.											
				for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
				{
					if(password2[i] != 20)							//如果不是原始数值,说明有新的密码
					{
						if(password_dis == 0)
							write_date('*');						//把输入的密码以*号显示出来.
						else
							write_date(muntochar[password2[i]]);
					}
				}  
				//主要目的为  * 和实体密码切换显示,照顾到第一次输入的密码值----------------------------
				write_com(0X87);							//液晶AC控制到第1行的第7位置.											
				for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
				{
					if(password1[i] != 20)							//如果不是原始数值,说明有新的密码
					{
						if(password_dis == 0)
							write_date('*');						//把输入的密码以*号显示出来.
						else
							write_date(muntochar[password1[i]]);
					}
				}
				//------------------------------------------------------------
			}
		}

		/*---------功能(确定密码是否正确)-----------*/
		if(key_16mun == 13)											//如果确定键被按下.
		{
			if(intput == 1)											//如果是第1次输入密码
			{
				intput = 2;											//标志第2次输入密码
				in_password_mun = 255;								//密码输入位数记录还原
				write_com(0Xc7);							//液晶AC控制到第2行的第7位置.								
			}
			else													//如果已输入二次新密码,比较密码是否一致.
			{
				for(i = 0;i < 6;i++)								//比较6位密码.
				{
					if(password1[i] != password2[i])				//如果密码不匹配.
					{
						write_string(1,0,"Password failed!");//显示密码不一致辞
						write_string(2,0,"      N0 !       ");//显示密码不一致辞
						break;										//跳出for循环.
					}
					
					if(i == 5)										//如果循环6次没有跳出for循环,密码输入正确.
					{
						write_string(1,0,"Password success");//显示密码不一致辞
						write_string(2,0,"      OK !      ");//显示密码修改成功.
						EEPROM_write_n(EEROM_USEADDR,password1,6); //写入修改好的密码
						EEPROM_read_n(EEROM_USEADDR+1,password,6);   	//读取6位密码.存入password数组.	
					}
				}

				Beep = 1;											//蜂鸣提示.
				delay_ms(250);
				Beep = 0;
				delay_ms(150);
				Beep = 1;
				delay_ms(250);
				delay_ms(250);
				Beep = 0;											
				delay_ms(250);										//延时退出.
				delay_ms(250);
				delay_ms(250);
				Beep = 1;										//蜂鸣关闭.
				/*----液晶还原成待机状态显示----*/
				write_string(1,0," Password Lock  ");		//液晶显示的字符
				write_string(2,0," Input:         ");		//液晶显示的字符
				write_com(0XC7);							//液晶AC控制到第2行的第7位置.
				return;												//函数数返回.
			}
		}

		/*---------功能(删除1位密码)-----------*/
		if(key_16mun == 15 && in_password_mun != 255)
		{
			if(intput == 1)													//如果是第1次输入新密码.
			{
				password1[in_password_mun] = 20;
				write_com(0X87 + in_password_mun);				//液晶AC控制到第2行的第7位置.											
				write_date(' ');
				write_com(0X87 + in_password_mun);				//液晶AC控制到第2行的第7位置.											
			}
			else
			{
				password2[in_password_mun] = 20;
				write_com(0XC7 + in_password_mun);				//液晶AC控制到第2行的第7位置.											
				write_date(' ');
				write_com(0XC7 + in_password_mun);				//液晶AC控制到第2行的第7位置.											
			}
			if(in_password_mun > 0)
				in_password_mun--;
			else
				in_password_mun = 255;										//记录密码输入位数还原.
		}
		/*---------功能(显示输入密码)-----------*/
		if(key_16mun == 14)
		{
			password_dis = !password_dis;
			write_com(0Xc7);							//液晶AC控制到第2行的第7位置.											
			for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
			{
				if(password2[i] != 20)							//如果不是原始数值,说明有新的密码
				{
					if(password_dis == 0)
						write_date('*');						//把输入的密码以*号显示出来.
					else
						write_date(muntochar[password2[i]]);
				}
			}  
			//主要目的为  * 和实体密码切换显示,照顾到第一次输入的密码值----------------------------
			write_com(0X87);							//液晶AC控制到第1行的第7位置.											
			for(i = 0;i < 6;i++)								//循环检查6位密码,并且显示在屏上
			{
				if(password1[i] != 20)							//如果不是原始数值,说明有新的密码
				{
					if(password_dis == 0)
						write_date('*');						//把输入的密码以*号显示出来.
					else
						write_date(muntochar[password1[i]]);
				}
			}
			//------------------------------------------------------------
		}
		/*-------无操作自运退出------*/
		if(flag_200ms == 1)
		{
			flag_200ms = 0;													//200mS标志置位清0
			out_time++;
			if(out_time == 5 * 10)											//10秒时间.
			{
				/*----液晶还原成待机状态显示----*/
				write_string(1,0," Password Lock  ");				//液晶显示的字符
				write_string(2,0," Input:         ");				//液晶显示的字符
				write_com(0XC7);									//液晶AC控制到第2行的第7位置.
				Beep = 0;													//蜂鸣提示.
				delay_ms(250);
				Beep = 1;
				return  ;														//函数返回
			}
		}
	}
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值