如何实现一种基于STM32单片机的电子密码锁设计

2023-08-22  

一、功能简介


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


主要功能:


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


二、软件设计


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


函 数 名 : TIM2_IRQHandler

函数功能 : TIM2中断函数

输 入 : 无

输 出 : 无

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


void TIM2_IRQHandler(void)


{


static u32 i=0;


if(TIM_GetITStatus(TIM2,TIM_IT_Update))


{


i++;


if(i>=(100*AFRESH_TIME))//时间到


{


i=0;


TIM_Cmd(TIM2,DISABLE);//关闭定时器


sys_ctrl.time_flag=1;


}


}


TIM_ClearITPendingBit(TIM2,TIM_IT_Update);


}


//主界面,输入密码提示


void main_display(void)


{


memset(sys_ctrl.password,0,6);//密码数据清零


sys_ctrl.time_flag=0;


sys_ctrl.resive_flag=0;


delay_ms(500);


lcd1602_clear();


lcd1602_show_string(0,0,"Password Input:");


}


//密码输入错误次数超过规定值,等待指定时间后可重新输入


void password_error_wait_afreah_input(void)


{


TIM_Cmd(TIM2,ENABLE);//开启定时器


lcd1602_clear();


lcd1602_show_string(0,0,"Error Too much!");


lcd1602_show_string(0,1,"Please Wait...");


while(1)


{


if(sys_ctrl.time_flag)//时间到


{


RELAY=1;


sys_ctrl.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(sys_ctrl.resive_flag==0)


{


 sys_ctrl.password[cnt]=key-1;//记录用户输入密码


 if(PASSWORD_SHOW_HIDE==0)


  lcd1602_show_num(cnt,1,'*',0);


 else


  lcd1602_show_num(cnt,1,sys_ctrl.password[cnt],1);



else//修改密码状态


{


 sys_ctrl.save_password[cnt]=key-1;//记录验证密码


 lcd1602_show_num(cnt,1,sys_ctrl.save_password[cnt],1); 



cnt++;

}


}


//输入撤回


if(cnt>0)//有输入密码,撤回才有效


{


if(key==11)//撤回键


{


beep_alarm(100,10);


cnt--;


if(sys_ctrl.resive_flag==0)


{


 sys_ctrl.password[cnt]=' ';


 lcd1602_show_num(cnt,1,sys_ctrl.password[cnt],0); 


}


else//修改密码状态


{


 sys_ctrl.save_password[cnt]=' ';


 lcd1602_show_num(cnt,1,sys_ctrl.save_password[cnt],0); 


}

}


}


//密码确认


if(key==12)//密码确认键


{


beep_alarm(100,10);


if(sys_ctrl.resive_flag==0)


{


if(sys_ctrl.error_cnt< ERROR_PASSWORD_CNT)//密码输错,还可继续重新输入


{


 if(memcmp(sys_ctrl.password,sys_ctrl.save_password,6))//密码错误


 {


  sys_ctrl.error_cnt++;


  lcd1602_show_string(0,1,"Password Error!");


  //密码错误,不可继续输入,需等待10S重新输入


  if(sys_ctrl.error_cnt==ERROR_PASSWORD_CNT)


   password_error_wait_afreah_input(); 


  break;    


 }


 else//密码正确,开锁


 {


  RELAY=0;


  sys_ctrl.error_cnt=0;


  lcd1602_show_string(0,1,"Password OK!");


  delay_ms(2000);


  RELAY=1;


  break;  


 }  


}

}


else//修改密码状态


{


sys_ctrl.resive_flag=0;//修改完成


lcd1602_show_string(0,1,"Password Set OK!");


AT24CXX_Write(0,sys_ctrl.save_password,6);//存储新密码


break;

}


}


//密码修改


if(key==13)//密码修改键


{


beep_alarm(100,10);


sys_ctrl.resive_flag=1;


cnt=0;


lcd1602_clear();


lcd1602_show_string(2,0,"Password Set:");


}


}


}


//应用控制系统


void appdemo_show(void)


{


u8 i=0;


u8 init_flag=0;


ctrl_pin_init();


key_matrix_init();


BEEP_Init();


lcd1602_init();//LCD1602初始化


TIM2_Init(500-1,71);//定时10ms


AT24CXX_Init();


init_flag=AT24CXX_ReadOneByte(250);


if(init_flag!=0xAA)//初始化一次,防止重复初始化密码


{


AT24CXX_WriteOneByte(250,0xAA);


for(i=1;i<7;i++)sys_ctrl.save_password[i-1]=i;


delay_ms(10);


AT24CXX_Write(0,sys_ctrl.save_password,6);//写入初始密码123456


}


AT24CXX_Read(0,sys_ctrl.save_password,6);//读取密码


while(1)


{


main_display();//主界面显示


password_input();//密码输入、修改


}


}

三、实验现象

图片

图片


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。