【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示 proteus仿真+程序+设计报告+讲解视频

07-14 1303阅读

【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示设计

  • 1.主要功能:
  • 讲解视频:
  • 2.仿真
  • 3. 程序代码
  • 4. 设计报告
  • 5. 设计资料内容清单&&下载链接
      • 资料下载链接:

        【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示设计

        ( proteus仿真+程序+设计报告+讲解视频)

        仿真图proteus8.16(有低版本)

        程序编译器:keil 4/keil 5

        编程语言:C语言

        设计编号:P14

        1.主要功能:

        基于51单片机AT89C51/52(与AT89S51/52、AT89C51/52、STC89C51/52等51内核单片机通用)

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

        1.按键设置6位密码,输入密码若密码正确,则锁打开。显示open!开锁指示灯点亮。

        2.密码可以自己修改(6位密码),必须是开始状态才能改密。为防止误操作,修改密码得输入两次。

        3.若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘,需复位重新开始操作。

        4.系统具有24C02有复位、掉电保存密码功能。

        5.需要在Proteus软件和普中51开发板实现功能验证。

        (目前仅完全适配普中开发板A234,其他普中开发板型号可能需要做代码修改或接线)

        需注意仿真中51单片机芯片是兼容的,AT89C51,AT89C52是51单片机的具体型号,内核是一样的。相同的原理图里,无论stc还是at都一样,引脚功能都是一样的,程序是兼容的,芯片可以替换为STC89C52/STC89C51/AT89C52/AT89C51等51单片机芯片。

        讲解视频:

        仿真讲解+实物演示+代码讲解

        【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示 proteus仿真+程序+设计报告+讲解视频

        2.仿真

        开始仿真

        打开仿真工程,双击proteus中的单片机,选择hex文件路径,然后开始仿真。

        1、首次使用时输入:131420,对密码进行初始化,当显示:initpassword, 证明密码初始化完成,此时的密码为:000000。然后可以改密了。

        (如密码忘记就再输入131420初始化,然后密码就是000000)

        【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示 proteus仿真+程序+设计报告+讲解视频

        2.输入密码正确,LCD显示open,继电器导通模拟开锁动作。

        【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示 proteus仿真+程序+设计报告+讲解视频

        3当输入密码错误后,LCD显示error,报警并锁定键盘3秒钟。

        【普中】基于51单片机的矩阵电子密码锁LCD1602液晶显示 proteus仿真+程序+设计报告+讲解视频

        3. 程序代码

        使用keil4或者keil5编译,代码有注释,可以结合报告理解代码含义。

        //==================================================================================================
        //=======================================LCD1602====================================================
        //==================================================================================================
        #define yi 0x80 //LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80)
        #define er 0x80+0x40 //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)
        //----------------延时函数,后面经常调用----------------------
        void delay(uint xms)//延时函数,有参函数
        {
        	uint x,y;
        	for(x=xms;x>0;x--)
        	 for(y=110;y>0;y--);
        }
        //--------------------------写指令---------------------------
        void write_1602com(uchar com)//****液晶写入指令函数****
        {
        	lcd1602_rs=0;//数据/指令选择置为指令
        	lcd1602_rw=0; //读写选择置为写
        	P0=com;//送入数据
        	delay(1);
        	lcd1602_en=1;//拉高使能端,为制造有效的下降沿做准备
        	delay(1);
        	lcd1602_en=0;//en由高变低,产生下降沿,液晶执行命令
        }
        //-------------------------写数据-----------------------------
        void write_1602dat(uchar dat)//***液晶写入数据函数****
        {
        	lcd1602_rs=1;//数据/指令选择置为数据
        	lcd1602_rw=0; //读写选择置为写
        	P0=dat;//送入数据
        	delay(1);
        	lcd1602_en=1; //en置高电平,为制造下降沿做准备
        	delay(1);
        	lcd1602_en=0; //en由高变低,产生下降沿,液晶执行命令
        }
        //-------------------------初始化-------------------------
        void lcd_init(void)
        {
        	write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
        	write_1602com(0x0c);//开显示不显示光标
        	write_1602com(0x06);//整屏不移动,光标自动右移
        	write_1602com(0x01);//清显示
        }
        //========================================================================================
        //=========================================================================================
        //==============将按键值编码为数值=========================
        unsigned char coding(unsigned char m)	 
        {
        	unsigned char k;
        	switch(m)
        	{
        		case (1): k=1;break;
        		case (2): k=2;break;
        		case (3): k=3;break;
        		case (4): k='A';break;
        		
        		case (5): k=4;break;
        		case (6): k=5;break;
        		case (7): k=6;break;
        		case (8): k='B';break;
        		
        		case (9): k=7;break;
        		case (10): k=8;break;
        		case (11): k=9;break;
        		case (12): k='C';break;
        		
        		case (13): k='*';break;
        		case (14): k=0;break;
        		case (15): k='#';break;
        		case (16): k='D';break;
        	}
        	return(k);
        }
        //=====================按键检测并返回按键值===============================
        void delay_uint(unsigned     int i)//延时
        {
           while(i--);
        }
        完整代码见文末下载链接
        unsigned char keynum(void)
        {
           unsigned char i, j; // 定义变量i和j分别存储行列索引
           i = 0; 
           j = 0;
           // 设置P1端口的低四位输出为0,高四位保持不变,准备读取键盘列信号
           P1 = 0x0f;
           // 判断是否有键被按下(即P1端口的值不全为0x0f)
           if(P1 != 0x0f) {
        	   // 延时去抖,等待10ms再次检测,确保按键稳定
        	   delay_uint(10000);
        	   // 再次检查,确认按键确实被按下
        	   if(P1 != 0x0f) {
        		   // 根据P1的值判断是哪一行被按下
        		   switch(P1) {
        			   case 0x0e: i = 3; break; // 第1行
        			   case 0x0d: i = 2; break; // 第3行
        			   case 0x0b: i = 1; break; // 第3行
        			   case 0x07: i = 0;	   // 第4行
        		   }
        		   // 设置P1端口的高四位输出为0,低四位保持不变,准备读取键盘行信号
        		   P1 = 0xf0;
        		   // 根据P1的新值判断是哪一列被按下
        		   switch(P1) {
        			   case 0xe0: j = 13; break; // 第1列
        			   case 0xd0: j = 9;  break; // 第2列
        			   case 0xb0: j = 5;  break; // 第3列
        			   case 0x70: j = 1;		 // 第4列
        		   }
        	   }
           }
           // 检查新获取的按键值(行列索引组合)是否与上一次的不同
           if(key != i + j) {
        	   // 更新按键值并返回
        	   key = i + j;
        	   return key;
           } else {
        	   // 如果按键值没有变化,返回0表示没有新按键事件
        	   return 0;
           }
        }
        //=======================一声提示音,表示有效输入========================
        void OneAlam(void)
        {
        	beep_cnt=1;
        	beep_time=BEEP_TIME;
        }
        //========================二声提示音,表示操作成功========================
        void TwoAlam(void)
        {
        	beep_cnt=2;
        	beep_time=BEEP_TIME;
        }
        //========================三声提示音,表示错误========================
        void ThreeAlam(void)
        {
        	beep_cnt=3;
        	beep_time=BEEP_TIME;
        }
        //=======================显示提示输入=========================
        void DisplayChar(void)
        {
        	unsigned char i;
        	if(pass==1)
        	{
        		//DisplayListChar(0,1,LockOpen);
        		write_1602com(er);				   //在二行开始显示
        		for(i=0;i
        			write_1602dat(LockOpen[i]);	   //显示open 开锁成功
        		}
        	}
        	else
        	{
        		if(N==0)
        		{
        			//DisplayListChar(0,1,Error);
        			write_1602com(er);
        			for(i=0;i
        				write_1602dat(Error[i]);	//显示错误
        			}
        		}
        		else
        		{
        			//DisplayListChar(0,1,start_line);	
        			write_1602com(er);
        			for(i=0;i
        				write_1602dat(start_line[i]);//显示开始输入	
        			}
        		}
        	}
        }
        //========================重置密码==================================================
        //==================================================================================
        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==6)	   //输入6位密码
        			{
        				ReInputCont++;			//密码次数计数	
        				if(ReInputCont==2)		//输入两次密码
        				{
        					for(i=0;i
        						if(TempPassword[i]==InputData[i])	//将两次输入的新密码作对比
        							i++;
        						else								//如果两次的密码不同
        						{
        							//DisplayListChar(0,1,Error);
        							write_1602com(er);
        							for(j=0;j
        								write_1602dat(Error[j]);	//显示错误Error
        							}
        							ThreeAlam();			//错误提示	
        							pass=0;					//关锁
        							ReInputEn=0;			//关闭重置功能,
        							ReInputCont=0;
        							DisplayChar();
        							break;
        						}
        					} 
        					if(i==6)
        					{
        						//DisplayListChar(0,1,ResetOK);
        						write_1602com(er);
        						for(j=0;j
        							write_1602dat(ResetOK[j]);	  //密码修改成功,显示
        						}
        						TwoAlam();				//操作成功提示
        					 	WrToROM(TempPassword,0,6);		//将新密码写入24C02存储
        						ReInputEn=0;
        					}
        					ReInputCont=0;
        					CorrectCont=0;
        				}
        				else					  //输入一次密码时
        				{
        					OneAlam();
        					//DisplayListChar(0, 1, again); 		//显示再次输入一次
        					write_1602com(er);
        					for(j=0;j
        						write_1602dat(again[j]);			//显示再输入一次
        					}					
        					for(i=0;i
        						TempPassword[i]=InputData[i];		//将第一次输入的数据暂存起来						
        					}
        				}
        			N=0;						//输入数据位数计数器清零
        		   }
        	    }
        	}
        }
        //=======================输入密码错误超过三过,报警并锁死键盘======================
        void Alam_KeyUnable(void)
        {
        	P1=0x00;
        	{
        		beep_cnt=255;
        		beep_time=BEEP_TIME;
        	}
        }
        //=======================取消所有操作============================================
        void Cancel(void)
        {	
        	unsigned char i;
        	unsigned char j;
        	//DisplayListChar(0, 1, start_line); 
        	write_1602com(er);
        	for(j=0;j
        		write_1602dat(start_line[j]);	  //显示开机输入密码界面
        	}
        	TwoAlam();				//提示音
        	for(i=0;i
        		InputData[i]=0;		//将输入密码清零
        	}
        	KEY=1;					//关闭锁
        	pass=0;					//密码正确标志清零
        	ReInputEn=0;			//重置输入充许标志清零
        	ErrorCont=0;			//密码错误输入次数清零
        	CorrectCont=0;			//密码正确输入次数清零
        	ReInputCont=0;			//重置密码输入次数清零 
        	s3_keydown=0;
        	key_disable=0;			//锁定键盘标志清零
        	N=0;					//输入位数计数器清零
        }
        
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]