本设计仅供学习参考
基于51单片机LCD1602矩阵键盘密码锁proteus仿真设计(程序+仿真)
原理图:Altium Designer
仿真图proteus 7.8
程序编译器:keil 4/keil 5
编程语言:C语言
编号C0035
【腾讯文档】C0035 网盘链接
资料下载链接
一、主要功能:
1.按键设置6位密码,输入密码若密码正确,则锁打开。显示open!
2.密码可以自己修改(6位密码),必须是锁打开时才能改密。为防止误操作,修改密码得输入两次。
3.若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘。
4.24C02有复位、掉电保存密码功能。
5.液晶屏亮度会随光线自动调整。
二、按键说明:
排列方式:
1 2 3 A
4 5 6 B
7 8 9 C
0 # D
- ABC无定义、 *号键为取消当前操作、#号键为确认、D键为修改密码
三、其他说明:
1、首次使用时输入:131420,对密码进行初始化,当显示:initpassword,证明密码初始化完成,此时的密码为:000000。然后可以改密了。(如密码忘记就再输入131420初始化,然后密码就是000000了,不要告诉别人哦~~~)
2、按下 * 键或复位键,可以关锁并退出。
3、当输入密码错误后,报警并锁定键盘3秒钟。
4、修改密码:在开锁状态下,再次输入正确的密码并按下 # 键,此时听到两声提示,输入新的六位密码并按 D 键,再重复输入一次新密码并按 D ,会听到两声提示音,表示重设密码成功,内部保存新密码并存储。如两次输入的新密码不一样,则重设密码失败。
仿真图(提供源文件):
程序(提供源文件源码):
LCD1602
//==================================================================================================
//=======================================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 keynum(void)
{
unsigned char row,col,i;
P1=0xf0;
if((P1&0xf0)!=0xf0)
{
Delay5Ms();
Delay5Ms();
if((P1&0xf0)!=0xf0)
{
row=P1^0xf0; //确定行线
i=0;
P1=a[i]; //精确定位
while(i<4)
{
if((P1&0xf0)!=0xf0)
{
col=~(P1&0xff); //确定列线
break; //已定位后提前退出
}
else
{
i++;
P1=a[i];
}
}
}
else
{
return 0;
}
while((P1&0xf0)!=0xf0);
return (row|col); //行线与列线组合后返回
}
else return 0; //无键按下时返回0
}
//=======================一声提示音,表示有效输入========================
void OneAlam(void)
{
ALAM=0;
Delay5Ms();
ALAM=1;
}
//========================二声提示音,表示操作成功========================
void TwoAlam(void)
{
ALAM=0;
Delay5Ms();
ALAM=1;
Delay5Ms();
ALAM=0;
Delay5Ms();
ALAM=1;
}
//========================三声提示音,表示错误========================
void ThreeAlam(void)
{
ALAM=0;
Delay5Ms();
ALAM=1;
Delay5Ms();
ALAM=0;
Delay5Ms();
ALAM=1;
Delay5Ms();
ALAM=0;
Delay5Ms();
ALAM=1;
}
重置密码
//========================重置密码==================================================
//==================================================================================
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<6;)
{
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();
break;
}
}
if(i==6)
{
//DisplayListChar(0,1,ResetOK);
write_1602com(er);
for(j=0;j<16;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<16;j++)
{
write_1602dat(again[j]); //显示再输入一次
}
for(i=0;i<6;i++)
{
TempPassword[i]=InputData[i]; //将第一次输入的数据暂存起来
}
}
N=0; //输入数据位数计数器清零
}
}
}
}