Proteus仿真:51单片机电子密码锁设计详解

文章目录

  • 一、功能简介
  • 二、软件设计
  • 三、实验现象
  • 联系作者

  • 一、功能简介

    本项目使用Proteus8仿真51单片机控制器,使用LCD1602液晶、矩阵按键、蜂鸣器、EEPROM模块、继电器模块等。

    系统运行后,LCD1602显示密码输入提示界面,系统存储在EEPROM的初始密码为123456,
    用户可通过矩阵按键S1-S10输入数值0-9,当在密码输入过程中有误,可按S11键回删并重新输入。当密码输入完成后,可按S12键确认,校验密码是否正确,如密码输入正确,电磁阀工作开门,对应D3指示灯点亮;如密码输入错误,LCD显示错误信息,可重新输入密码,最多可输入3次,如还输入错误,系统锁死,需等待10S钟解锁系统方可再次输入。当管理员需要更换密码时,可按下S13键,LCD显示更换密码界面,此时可通过S1-S10输入修改密码,修改过程中如需更改可按S11键回删并重新输入。修改密码完成后可按下S12键保存新密码至EEPROM中,更新的密码可断电不丢失。


    二、软件设计

    /*
    作者:嗨小易(QQ:3443792007)
    */
    
    
    
    
    //定时器0中断函数
    void time0() interrupt 1
    {
    	static u32 i=0;
    	
    	TH0=0XDC;	//给定时器赋初值,定时10ms
    	TL0=0X00;
    
    	i++;
    	if(i==(100*AFRESH_TIME))//时间到
    	{
    		i=0;
    		time0_stop();//关闭定时器
    		lock_sys_control.time_flag=1;		
    	}
    }
    
    //主界面,输入密码提示
    void main_display(void)
    {
    	memset(lock_sys_control.password,0,6);//密码数据清零
    	lock_sys_control.time_flag=0;
    	lock_sys_control.resive_flag=0;
    	delay_ms(500);
    	lcd1602_clear();
    	lcd1602_show_string(0,0,"Password Input:");			
    }
    
    //密码输入错误次数超过规定值,等待指定时间后可重新输入
    void password_error_wait_afreah_input(void)
    {
    	time0_start();//开启定时器
    	lcd1602_clear();
    	lcd1602_show_string(0,0,"Error Too much!");
    	lcd1602_show_string(0,1,"Please Wait...");
    	while(1)
    	{
    		if(lock_sys_control.time_flag)//时间到
    		{
    			RELAY=1;
    			lock_sys_control.error_cnt=0;
    			break;	
    		}			
    	}		
    }
    
    //密码输入、修改
    void password_input(void)
    {
    	u8 key=0;
    	u8 cnt=0;
    
    	while(1)
    	{
    		key=key_matrix_flip_scan();
    
    		//密码输入
    		if(key>0&&key<=10)//输入有效数字0-9,排除无效键输入
    		{
    			beep_alarm(100,10);//提示音
    			if(cnt<6)//有效密码位数,确保6位有效
    			{
    				if(lock_sys_control.resive_flag==0)
    				{
    					lock_sys_control.password[cnt]=key-1;//记录用户输入密码
    					if(PASSWORD_SHOW_HIDE==0)
    						lcd1602_show_num(cnt,1,'*',0);
    					else
    						lcd1602_show_num(cnt,1,lock_sys_control.password[cnt],1);
    				}	
    				else//修改密码状态
    				{
    					lock_sys_control.save_password[cnt]=key-1;//记录验证密码
    					lcd1602_show_num(cnt,1,lock_sys_control.save_password[cnt],1);	
    				}	
    				cnt++;	
    			}								
    		}
    		
    		//输入撤回
    		if(cnt>0)//有输入密码,撤回才有效
    		{
    			if(key==11)//撤回键
    			{
    				beep_alarm(100,10);
    				cnt--;
    				if(lock_sys_control.resive_flag==0)
    				{
    					lock_sys_control.password[cnt]=' ';
    					lcd1602_show_num(cnt,1,lock_sys_control.password[cnt],0);	
    				}
    				else//修改密码状态
    				{
    					lock_sys_control.save_password[cnt]=' ';
    					lcd1602_show_num(cnt,1,lock_sys_control.save_password[cnt],0);	
    				}		
    			}		
    		}
    		
    		//密码确认
    		if(key==12)//密码确认键
    		{
    			beep_alarm(100,10);
    			if(lock_sys_control.resive_flag==0)
    			{
    				if(lock_sys_control.error_cnt<ERROR_PASSWORD_CNT)//密码输错,还可继续重新输入
    				{
    					if(memcmp(lock_sys_control.password,lock_sys_control.save_password,6))//密码错误
    					{
    						lock_sys_control.error_cnt++;
    						lcd1602_show_string(0,1,"Password Error!");
    						//密码错误,不可继续输入,需等待10S重新输入
    						if(lock_sys_control.error_cnt==ERROR_PASSWORD_CNT)
    							password_error_wait_afreah_input();	
    						break;				
    					}
    					else//密码正确,开锁
    					{
    						RELAY=0;
    						lock_sys_control.error_cnt=0;
    						lcd1602_show_string(0,1,"Password OK!");
    						delay_ms(2000);
    						RELAY=1;
    						break;		
    					}		
    				}	
    			}
    			else//修改密码状态
    			{
    				lock_sys_control.resive_flag=0;//修改完成
    				lcd1602_show_string(0,1,"Password Set OK!");
    				at24cxx_write_str(lock_sys_control.save_password,0,6);//存储新密码
    				break;			
    			}		
    		}
    		
    		//密码修改
    		if(key==13)//密码修改键
    		{
    			beep_alarm(100,10);
    			lock_sys_control.resive_flag=1;
    			cnt=0;
    			lcd1602_clear();
    			lcd1602_show_string(2,0,"Password Set:");	
    		}		
    	}	
    }
    
    
    //数字密码锁控制系统
    void password_lock_control_sys(void)
    {
    	u8 init_flag=0;
    	u8 i=0;
    	
    	lcd1602_init();//LCD1602初始化
    	time0_init();//初始化定时器0
    
    	init_flag=At24c02Read(250);
    	if(init_flag!=0xAA)//初始化一次,防止重复初始化密码
    	{
    		At24c02Write(250,0xAA);
    		for(i=1;i<7;i++)lock_sys_control.save_password[i-1]=i;
    		delay_ms(10);
    		at24cxx_write_str(lock_sys_control.save_password,0,6);//写入初始密码123456	
    	}
    	at24cxx_read_str(lock_sys_control.save_password,0,6);//读取密码
    
    	while(1)
    	{
    		main_display();//主界面显示
    		password_input();//密码输入、修改					
    	}	
    }
    
    
    

    三、实验现象

    演示视频:https://space.bilibili.com/444388619




    联系作者

    专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

    物联沃分享整理
    物联沃-IOTWORD物联网 » Proteus仿真:51单片机电子密码锁设计详解

    发表评论