1、设计思路:利用AT24C02将用户输入的密码保存,上电时可以输入8位密码,输入密码与用户保存的密码进行比较,判断是否正确,密码正确则开锁。用户可以修改密码。
2、硬件电路:使用普中51开发板,在LCD1602上显示
3、硬件模块:独立按键,可以设置密码。AT24C02可以写入和读取密码,LCD1602可以显示输入的密码。代码部分,我使用的是模块化封装函数,可移植性高,基本上是将每个功能函数都分别封装在一个函数里,在主函数里面调用,这样可以大大的节约时间,也能更好的了解,在主函数里基本上是实现逻辑部分即可,不用看密密麻麻的函数声明之类的。由于时间原因,我只是要把要基本实现的功能做出来,也比较粗糙,有很大程度的去优化,如果需要,可以自行优化,我会把全部的代码无常的分享,也写好注释,方便理解思路。
4、代码部分:由于代码部分函数模块比较多不好展示,我会以文件的形式发布,以下是部分代码的展示:
#include <REGX52.H>
#include "LCD1602.h"
#include "Key.h"
#include "AT24C02.h"
#include "delay.h"
unsigned char keynum; //按键的键码值
unsigned char count=0;//设置密码标志位数
unsigned char flag=0; //输入密码位数的标志位
unsigned char Set_flag=0; //设置密码的标志
unsigned char password[8]={0,0,0,0,0,0,0,0}; //初始密码的存储数组
unsigned char Enter_password[9]={0,0,0,0,0,0,0,0}; //输入密码的存储数组
void main()
{
LCD_Init();
while(1)
{
keynum=matrixkey();
if(keynum) //判断是否有按键按下
{
if(keynum<9) //如果是键码值小于9就是输入密码
{
password[0]=AT24C02_ReadByte(0); //从AT24C02的0地址读出第一位密码,赋给初始密码数组第0位
password[1]=AT24C02_ReadByte(1); //从AT24C02的1地址读出第二位密码,赋给初始密码数组第1位
password[2]=AT24C02_ReadByte(2); //以此类推
password[3]=AT24C02_ReadByte(3);
password[4]=AT24C02_ReadByte(4);
password[5]=AT24C02_ReadByte(5);
password[6]=AT24C02_ReadByte(6);
password[7]=AT24C02_ReadByte(7);
Enter_password[flag]=keynum; //将键码值赋给输入密码数组,flag代表数组的第几位
if(flag==0){LCD_ShowNum(1,1,Enter_password[0],1);} //更新显示
if(flag==1){LCD_ShowNum(1,2,Enter_password[1],1);}
if(flag==2){LCD_ShowNum(1,3,Enter_password[2],1);}
if(flag==3){LCD_ShowNum(1,4,Enter_password[3],1);}
if(flag==4){LCD_ShowNum(1,5,Enter_password[4],1);}
if(flag==5){LCD_ShowNum(1,6,Enter_password[5],1);}
if(flag==6){LCD_ShowNum(1,7,Enter_password[6],1);}
if(flag==7){LCD_ShowNum(1,8,Enter_password[7],1);}
flag++;
flag%=8; //判断是否大于0--7位,大于7位标志位就清零
}
if(keynum==10) //检测输入密码是否和设置的密码相等
{
if((password[0]==Enter_password[0]) && (password[1]==Enter_password[1])
&& (password[2]==Enter_password[2])&& (password[3]==Enter_password[3])
&& (password[4]==Enter_password[4])&& (password[5]==Enter_password[5])
&& (password[6]==Enter_password[6])&& (password[7]==Enter_password[7]))
{
P2=0;
}
}
if(keynum==16)
{
Set_flag++;//设置密码标志
Set_flag%=5;
LCD_ShowNum(2,10,Set_flag,1); //更新标志位显示
delay(10);
}
if(Set_flag==2) //如果标志位是2时可以设置密码
{
if(keynum==11)
{
count++; //count=0;就是设置第一位密码,2就是第2位
count%=8;
}
if(keynum==13)
{
password[count]++;//密码+
if(password[0]>9){password[0]=0;} //判断溢出边界
if(password[1]>9){password[1]=0;}
if(password[2]>9){password[2]=0;}
if(password[3]>9){password[3]=0;}
if(password[4]>9){password[4]=0;}
if(password[5]>9){password[5]=0;}
if(password[6]>9){password[6]=0;}
if(password[7]>9){password[7]=0;}
if(count==0){LCD_ShowNum(2,1,password[0],1);} //更新显示
if(count==1){LCD_ShowNum(2,2,password[1],1);}
if(count==2){LCD_ShowNum(2,3,password[2],1);}
if(count==3){LCD_ShowNum(2,4,password[3],1);}
if(count==4){LCD_ShowNum(2,5,password[4],1);}
if(count==5){LCD_ShowNum(2,6,password[5],1);}
if(count==6){LCD_ShowNum(2,7,password[6],1);}
if(count==7){LCD_ShowNum(2,8,password[7],1);}
}
if(keynum==12)
{
count--;
count%=8;
}
if(keynum==14)
{
password[count]--;//密码-
if(password[0]<0){password[0]=9;} //判断溢出边界
if(password[1]<0){password[1]=9;}
if(password[2]<0){password[2]=9;}
if(password[3]<0){password[3]=9;}
if(password[4]<0){password[4]=9;}
if(password[5]<0){password[5]=9;}
if(password[6]<0){password[6]=9;}
if(password[7]<0){password[7]=9;}
if(count==0){LCD_ShowNum(2,1,password[0],1);} //更新显示
if(count==1){LCD_ShowNum(2,2,password[1],1);}
if(count==2){LCD_ShowNum(2,3,password[2],1);}
if(count==3){LCD_ShowNum(2,4,password[3],1);}
if(count==4){LCD_ShowNum(2,5,password[4],1);}
if(count==5){LCD_ShowNum(2,6,password[5],1);}
if(count==6){LCD_ShowNum(2,7,password[6],1);}
if(count==7){LCD_ShowNum(2,8,password[7],1);}
}
}
if(Set_flag==4) //密码设置确认
{
AT24C02_WriteByte(0,password[0]); //写入密码到AT24C02里,0--7 字节
delay(5); //写入要延时,否则写入会出错
AT24C02_WriteByte(1,password[1]);
delay(5);
AT24C02_WriteByte(2,password[2]);
delay(5);
AT24C02_WriteByte(3,password[3]);
delay(5);
AT24C02_WriteByte(4,password[4]);
delay(5);
AT24C02_WriteByte(5,password[5]);
delay(5);
AT24C02_WriteByte(6,password[6]);
delay(5);
AT24C02_WriteByte(7,password[7]);
delay(5);
LCD_ShowString(1,1,"Write OK");
delay(1000);
LCD_ShowString(1,1," ");
delay(1000);
}
if(Set_flag==2)
{
LCD_ShowNum(2,13,count,2); //更新设置密码标志位
}
}
}
}
到这里就结束啦,可以根据自身的需求添加功能,这个密码锁,我也是摸索了两三天的了,可惜由于时间的原因没办法再做更多的功能和优化BUG了,代码可在网盘里取。
链接:https://pan.baidu.com/s/1bd8f2kmJ704shjkExCzclg
提取码:w5a7