基于51单片机的密码锁设计—LCD1602显示

基于51单片机的密码锁设计

(仿真+程序+原理图+设计报告)

具体功能:

1.使用4*4矩阵键盘设置8位数密码,若输入密码正确,则锁打开。LCD1602显示open!

2.可以修改密码(8位数密码),要锁处于打开状态才能改密。为了防止误操作,改密码需要输入两次。

3.如果超过3次密码输入错误次数,蜂鸣器产生报警并把键盘锁定。

4.有复位、掉电保存密码功能。

5.液晶屏亮度会随光线自动调整。

代码

void DisplayInput(void)
{
	unsigned char i;
	if(CorrectCont==1)
	{
		//DisplayListChar(0,0,Input);
		write_1602com(er);
		for(i=0;i<16;i++)
		{
			write_1602dat(Input[i]);	//显示Input
		}
	}
}


//========================重置密码==================================================
//==================================================================================
void ResetPassword(void)
{
	unsigned char i;	
	unsigned char j;
	if(pass==0)
	{
		pass=0;			   
		DisplayChar();	   //显示错误
		ThreeAlam();	   //没开锁时按下重置密码报警3声
	}
	else				   //开锁状态下才能进行密码重置程序
	{
    	if(ReInputEn==1)   //开锁状态下,ReInputEn置1,重置密码允许
		{
			if(N==8)	   //输入8位密码
			{
				ReInputCont++;			//密码次数计数	
				if(ReInputCont==2)		//输入两次密码
				{
					for(i=0;i<8;)
					{
						if(TempPassword[i]==InputData[i])	//将两次输入的新密码作对比
							i++;
						else								//如果两次的密码不同
						{
							//DisplayListChar(0,1,Error);
							write_1602com(er);
							for(j=0;j<16;j++)
							{
								write_1602dat(Error[j]);	//显示错误Error
							}
							ThreeAlam();			//错误提示	
							pass=0;					//关锁
							ReInputEn=0;			//关闭重置功能,
							ReInputCont=0;
							DisplayChar();
						//	ReInputCont=0; //
							break;
						}
					} 
					if(i==8)
					{
						//DisplayListChar(0,1,ResetOK);
						write_1602com(er);
						for(j=0;j<16;j++)
						{
							write_1602dat(ResetOK[j]);	  //密码修改成功,显示
						}

						TwoAlam();				//操作成功提示
					 	WrToROM(TempPassword,0,8);		//将新密码写入24C02存储
						ReInputEn=0;
					}
					ReInputCont=0;
					CorrectCont=0;
				}
				else					  //输入一次密码时
				{
					OneAlam();
					//DisplayListChar(0, 1, again); 		//显示再次输入一次
					write_1602com(er);
					for(j=0;j<16;j++)
					{
						write_1602dat(again[j]);			//显示再输入一次
					}					
					for(i=0;i<8;i++)
					{
						TempPassword[i]=InputData[i];		//将第一次输入的数据暂存起来						
					}
				}
			N=0;						//输入数据位数计数器清零
		   }
	    }
	}

}



//=======================输入密码错误超过三过,报警并锁死键盘======================
void Alam_KeyUnable(void)
{
	P1=0x00;
	{
		ALAM=~ALAM;				 //蜂鸣器一直闪烁鸣响
		ALAM_LED=!ALAM_LED;
		Delay5Ms();
	}
}


//=======================取消所有操作============================================
void Cancel(void)
{	
	unsigned char i;
	unsigned char j;
	//DisplayListChar(0, 1, start_line); 
	write_1602com(er);
	for(j=0;j<16;j++)
	{
		write_1602dat(start_line[j]);	  //显示开机输入密码界面
	}
	TwoAlam();				//提示音
	for(i=0;i<8;i++)
	{
		InputData[i]=0;		//将输入密码清零
	}
	KEY=1;					//关闭锁
	ALAM=1;					//报警关
	ALAM_LED=1;
	operation=0;			//操作标志位清零
	pass=0;					//密码正确标志清零
	ReInputEn=0;			//重置输入充许标志清零
	ErrorCont=0;			//密码错误输入次数清零
	CorrectCont=0;			//密码正确输入次数清零
	ReInputCont=0;			//重置密码输入次数清零 
	open_led=1;				//开锁LED关闭 (选配)
	s3_keydown=0;
	key_disable=0;			//锁定键盘标志清零
	N=0;					//输入位数计数器清零
}


//==========================确认键,并通过相应标志位执行相应功能===============================
void Ensure(void)
{	
	unsigned char i,j;
	RdFromROM(CurrentPassword,0,8); 					//从24C02里读出存储密码
    if(N==8)
	{
		TR1=0;
		sec=0;
	    if(ReInputEn==0)							//重置密码功能未开启
		{
			for(i=0;i<8;)
   			{					
				if(CurrentPassword[i]==InputData[i])	//判断输入密码和24c02中的密码是否相同
				{
					i++;								//相同一位 i就+1
				}
				else 									//如果有密码不同
				{										
					ErrorCont++;						//错误次数++
					if(ErrorCont==3)			//错误输入计数达三次时,报警并锁定键盘
					{
						write_1602com(er);
						for(i=0;i<16;i++)
						{
							write_1602dat(Error[i]);	
						}
						do
						Alam_KeyUnable();
						while(1);
					}
					else					 //错误次数小于3次时,锁死键盘3秒,然后重新可以输入
					{
						TR0=1;				//开启定时
						key_disable=1;			//锁定键盘
						pass=0;					//pass位清零
						break;					//跳出
					}
				}
			}

			if(i==8)					 //密码输入对时
			{
				CorrectCont++;					//输入正确变量++
				if(CorrectCont==1)				//正确输入计数,当只有一次正确输入时,开锁
				{
					//DisplayListChar(0,1,LockOpen);
					write_1602com(er);
					for(j=0;j<16;j++)
					{
						write_1602dat(LockOpen[j]);		  //显示open开锁画面
					}
					TwoAlam();			//操作成功提示音
					KEY=0;											//开锁
					pass=1;											//置正确标志位
					TR0=1;											//开启定时
					open_led=0;										//开锁指示灯亮(选配)
					for(j=0;j<8;j++)								//将输入清除
					{
						InputData[i]=0;								//开锁后将输入位清零
					}
				}	
				else												//当两次正确输入时,开启重置密码功能
				{
					//DisplayListChar(0,1,SetNew);
					write_1602com(er);
					for(j=0;j<16;j++)
					{
						write_1602dat(SetNew[j]);					//显示重置密码界面
					}
					TwoAlam();									    //操作成功提示
					ReInputEn=1;									//允许重置密码输入
					CorrectCont=0;									//正确计数器清零
				}
	  		}
	
			else			//=========================当第一次使用或忘记密码时可以用131420对其密码初始化============
			{
				if((InputData[0]==5)&&(InputData[1]==1)&&(InputData[2]==2)&&(InputData[3]==1)&&(InputData[4]==1)&&(InputData[5]==3)&&(InputData[6]==1)&&(InputData[7]==4))
		  	 	{
					WrToROM(initpassword,0,8); 				//强制将初始密码写入24C02存储
					//DisplayListChar(0,1,initword);			//显示初始化密码
					write_1602com(er);
					for(j=0;j<16;j++)
					{
						write_1602dat(initword[j]);				//显示初始化密码
					}
					TwoAlam();									//成功提示音
					Delay400Ms();								//延时400ms
					TwoAlam();									//成功提示音
					N=0;										//输入位数计数器清零
				}
				else											//密码输入错误
				{
					//DisplayListChar(0,1,Error);
					write_1602com(er);
					for(j=0;j<16;j++)
					{
						write_1602dat(Error[j]);				 //显示错误信息
					}
 					ThreeAlam();										//错误提示音
					pass=0;	
				}
			}
		}

		else											//当已经开启重置密码功能时,而按下开锁键,
		{
			//DisplayListChar(0,1,Er_try);
			write_1602com(er);
			for(j=0;j<16;j++)
			{
				write_1602dat(Er_try[j]);			  //错误,请重新输入
			}
			ThreeAlam();							  //错误提示音
		}
	}

	else				   //密码没有输入到8位时,按下确认键时
	{
		//DisplayListChar(0,1,Error);
		write_1602com(er);
		for(j=0;j<16;j++)
		{
			write_1602dat(Error[j]);		 //显示错误
		}

 		ThreeAlam();										//错误提示音
		pass=0;	
	}
	
	N=0;													//将输入数据计数器清零,为下一次输入作准备

	operation=1;
}


//==============================主函数===============================
void main(void)
{
 	unsigned char KEY,NUM;
	unsigned char i,j;
 	P1=0xFF; 
	TMOD=0x11;
 	TL0=0xB0;
 	TH0=0x3C;
	TH1=0x4b;
	TL1=0xff;
 	EA=1;
 	ET0=1;
	ET1=1;	
 	TR0=0;
	TR1=0;					   //打开定时器开关
 	Delay400Ms(); 	//启动等待,等LCM讲入工作状态
 	lcd_init(); 	//LCD初始化
	write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示
	for(i=0;i<16;i++)
	{
		write_1602dat(name[i]);//向液晶屏写开机画面
	}
	write_1602com(er);
	for(i=0;i<16;i++)
	{
		write_1602dat(start_line[i]);//写输入密码等待界面
	}
	write_1602com(er+9);	//设置光标位置
	write_1602com(0x0f);	//设置光标为闪烁
 	Delay5Ms(); //延时片刻(可不要)

 	N=0;														//初始化数据输入位数
 	while(1)		 //进入循环
 	{
		if(key_disable==1)						//锁定键盘标志为1时
			Alam_KeyUnable();					//报警键盘锁
		else
			ALAM=1;								//关报警

		KEY=keynum();							//读按键的位置码
		if(KEY!=0)								//当有按键按下时
		{	
			if(key_disable==1)					//锁定键盘标志为1时
			{
				second=0;						//秒清零
			}
			else								//没有锁定键盘时
			{
				NUM=coding(KEY);				//根据按键的位置将其编码,编码值赋值给NUM
				{
					switch(NUM)					//判断按键值
					{
						case ('A'): 	; 					break;
						case ('B'):		;     				break;
						case ('C'): 	; 					break;		//ABC是无定义按键
						case ('D'): ResetPassword();		break;      //重新设置密码
						case ('*'): Cancel();				break;      //取消当前输入
						case ('#'): Ensure(); 				break;   	//确认键,
						default: 										//如果不是功能键按下时,就是数字键按下
						{	
							//DisplayListChar(0,1,Input);
							if(N==0)
							{
								write_1602com(er);
								for(i=0;i<16;i++)
								{
									write_1602dat(Input[i]);				//显示输入画面
								}
							}
								
						    operation=0;								//操作标志清零
							if(N<8)                   					//当输入的密码少于6位时,接受输入并保存,大于6位时则无效。
							{  
								OneAlam();								//按键提示音						
								//DisplayOneChar(6+N,1,'*');
						 		for(j=0;j<=N;j++)
								{
									write_1602com(er+6+j);				//显示位数随输入增加而增加
									write_1602dat('*');					//但不显示实际数字,用*代替
								}
								InputData[N]=NUM;						//将数字键的码赋值给InputData[]数组暂存
								N++;									//密码位数加
							}
							else										//输入数据位数大于6后,忽略输入
							{
								N=8;									//密码输入大于6位时,不接受输入
						 		break;
							}
							if(ReInputEn==0)
							{
								TR1=1;
							}
						}
					}
				}
			}
	 	} 
	}
}

//*********************************中断服务函数**************************************
void  time0_int(void) interrupt 1 		   //定时器T0
{
 	TL0=0xB0;
 	TH0=0x3C;		  //定时器重新赋初值
 	//TR0=1;
 	countt0++;			   //计时变量加,加1次时50ms
  	if(countt0==20)		   //加到20次就是1s
   	{
		countt0=0;		   //变量清零
		second++;		   //秒加
		if(pass==1)		   //开锁状态时
		{
			if(second==1)			//秒加到1s时
			{

				TR0=0;				//关定时器
				TL0=0xB0;
 				TH0=0x3C;			//再次赋初值
				second=0;			//秒清零
			}
		}
		else						//不在开锁状态时
		{
			if(second==3)			//秒加到3时
			{
				TR0=0;				//关闭定时器
				ALAM_LED=1;
				second=0;			//秒清零
				key_disable=0;		//锁定键盘清零
				s3_keydown=0;	
				TL0=0xB0;
				TH0=0x3C;			//重新赋初值
			}
			else
			    TR0=1;				//打开定时器
		}
			
   	}
}

void time1_int(void) interrupt 3
{
	uchar i1,m;
	TH1=0x4b;
	TL1=0xff;
	m++;
	if(m==20)
	{
		m=0;
		sec++;
		if(sec==10)
		{
			sec=0;
		//	ALAM_LED=1;
			if(pass==1)
			TR1=0;
			else if(pass==0)
			{
				for(i1=0;i1<30;i1++)
				{
					ThreeAlam();
					
				}
				
				N=0;
				write_1602com(er);
				for(i1=0;i1<16;i1++)
				{
					write_1602dat(Input[i1]);
				}
				TR1=0;
			}
		}
	}
}

硬件设计

使用元器件:

单片机:STC89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

IC座:DIP40;

存储芯片:AT24c02;IC座:DIP8;

液晶屏:LCD1602;排针:5.08*16;

排座:5.08*16;电位器 :103;

蜂鸣器:5V 有源;三极管 :9012;

电阻:1k;排阻:1k*9;

电解电容:10uf ;按键:6*6 ;

继电器 :5V;接线端子:2P;

接线端子:3P;自锁开关:8*8 ;

万能板:9*15 ;导线:若干; 

流程图:

设计资料

01 仿真图

    本设计使用proteus7.8和proteus8.7两个版本设计,向下兼容,无需担心!具体如图!

02 原理图

    本系统原理图采用Altium Designer19设计,具体如图!

03 程序

    本设计使用软件keil4和keil5两个版本编程设计,无需担心!具体如图!

04 设计报告

    一万五千字设计报告,具体如下!

05 资料图

    全部资料包括仿真源文件 、程序(含注释)、AD原理图、开题报告、参考论文、流程图、任务书等。具体内容如下,全网最全! !

下面是51单片机设计资料

​大家共同学习进步:

跳转中...icon-default.png?t=N7T8https://link.zhihu.com/?target=https%3A//pan.baidu.com/s/1xJgNMuQVEg0J3KoUuVfhcw%3Fpwd%3Dtt1s

提取码:tt1s


点赞分享,一起学习进步!

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值