本课程设计的电子密码锁采用AT89C51作为主控芯片,结合矩阵按键输入模块、数码管显示模块、LCD1602液晶显示、LED、蜂鸣器报警器等电路模块实现开锁、上锁、报警、输入密码功能,设计一款可输入密码且具有报警功能的液晶显示电子密码锁。
- 电路设计
本次设计的电子密码锁主要由AT89C51最小系统+LCD1602液晶显示模块+蜂鸣器模块+LED指示灯模块+矩阵键盘输入模块组成。
- 相关模块介绍
矩阵键盘输入模块:使用一组键或者一个键盘,由于单片机I/O口较少,当系统中需要用到较多按键时,为了更合理利用单片机的I/O口,一般采用矩阵键盘的方式来实现多按键的功能。
LCD1602液晶显示模块:在单片机应用系统中,常用的显示设备有单个发光二极管、八段LED显示器、液晶显示器(LCD)、屏幕显示器(CRT)等。本次设计中,基于设计功能和节约成本等实际情况,采用LCD1602作为本次设计的显示器。
LED指示灯模块:在基于单片机的电子密码锁设计中,用户需要输入密码,密码正确则发出开锁信号实现开锁。设计中是以发光二极管代替电磁锁,二极管亮代表锁开,因此可以设计一个简单的可以点亮二极管的电路系统代替电磁锁开锁机构。
由于单片机I/O口默认为高电平,故初始时二极管不亮,代表锁是闭着的(密码错误)。当用户输入密码并验证正确时,发出开锁信号(二极管点亮)。
蜂鸣器模块:在这次基于单片机的电子密码锁设计中,通过控制蜂鸣器的发音来实现系统的报警功能。蜂鸣器是一种采用直流电压供电的电子讯响器。下图是用蜂鸣器模拟的报警机构仿真图。当P3.7口有脉冲信号输入时,蜂鸣器SOUNDER即会发音。通过控制输入脉冲的频率还能控制蜂鸣器的发音频率
- 使用介绍
输入正确默认密码(1234)之后,点击ENTER(确认),lcd显示屏提示ok(密码正确),led灯点亮。
反之,输入错误密码,按下ENTER,显示屏熄灭,LED灯熄灭,蜂鸣器发出警报声。
- 输入密码模块核心代码
/*键盘*/
void Key(){u8 a=0; //矩形式键盘函数
if(key!=0x0f){delay(1000);
if(key!=0x0f){
key=0x0f;
switch(key){
case 0x07: keyz=0;biao=1;break;
case 0x0b: keyz=1;biao=1;break;
case 0x0d: keyz=2;biao=1;break;
case 0x0e: keyz=3;biao=1;break;
}
key=0xf0;
switch(key){
case 0x70: keyz=keyz;biao=1;break;
case 0xb0: keyz=keyz+4;biao=1;break;
case 0xd0: keyz=keyz+8;biao=1;break;
case 0xe0: keyz=keyz+12;biao=1;break;
}
}
while((a<50)&&(key!=0xf0)){a++;delay(10000);}
}
}
2.2蜂鸣器报警模块
- 这里用到了报警模式,输出密码错误时蜂鸣器发出响声,并且LED灯上锁。
- 核心代码
/*蜂鸣器*/
void Fen(u8 a,b) //蜂鸣器发声函数
{
u8 i,j;
for(i=0;i<a;i++)
{
for(j=0;j<100;j++)
{fen=~fen;delay(b);}
}
}
void delay(u16 i){
while(i--);
}
2.3 LCD灯模块
键盘输入密码后反馈到LCD显示屏中显示密码
void writecom(u8 com){ //LCD写指令
rs=0;
rw=0;
e=0;
P0=com;
delay(5);
e=1;
e=0;
}
void writedat(u8 dat){ //LCD写数据
rs=1;
rw=0;
e=0;
P0=dat;
delay(5);
e=1;
e=0;
}
void initlcd(){ //LCD初始化函数
writecom(0x38); //显示模式设置
writecom(0x0c);
writecom(0x06);
}
void xian(){ //LCD显示数字函数
writedat(num[keyz]);
if(a==10){a=keyz; } //对abcd,四位数的单独赋值
else if(b==10){b=keyz;}
else if(c==10){c=keyz;}
else{d=keyz;}
if(j!=3){j++;}biao=0;
}
2.4其他部分核心代码
- 各数据的定义
//sbit 特殊功能位声明:声明某特殊功能寄存器中的一位
#define key P1 //按键io口
sbit fen=P3^0; //蜂鸣器io口
sbit rs=P3^1; //LCD控制口
sbit rw=P3^2;
sbit e=P3^3;
sbit led=P3^4; //LED灯io口
//bit 位变量声明:定义一个位变量的值
u8 keyz=17,j=0,biao1=0,a=10,b=10,c=10,d=10;
bit biao=0;
u16 zh;
u8 shu[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
u8 zi[]={"lnput password:"};
u8 num[]={"0123456789ABCDEF"};
- 验证密码是否正确
void shi(){u8 i; // 按键值判断函数
if(biao&&keyz!=15){ //判断标志位biao是否为1,为1则有按键操作并且按键的值不等于15
writecom(0x80+0x40+j); //数字显示位置进行累加操作
if(j<0){j=0;} //数字显示位置边界
switch(keyz){ //switch判断按键并执行对应操作
case 0:xian(); break;
case 1:xian(); break;
case 2:xian(); break;
case 3:xian(); break;
case 4:xian(); break;
case 5:xian(); break;
case 6:xian(); break;
case 7:xian(); break;
case 8:xian(); break;
case 9:xian(); break;
case 10:writedat(num[keyz]);
j++;biao=0;break;
case 11:writedat(num[keyz]);
j++;biao=0;break;
case 12:
biao1=0; //重置标志位biao1,上锁
biao=0;break;
case 13:writecom(0x01); delay(1000); //全屏清除
for(i=0;i<sizeof(zi);i++){
writecom(0x80+i);
writedat(zi[i]); }
j=0;biao=0;break;
case 14: //对当前数字位删除的操作
writedat(' ');
j--;
writecom(0x80+0x40+j);writedat(' ');
biao=0;break;
case 15: //确定按键
j++;biao=0;break;
}
}
if(keyz==15){ //判断按键值如果等于15,便视为按下确定键
writecom(0x01);delay(1000);
zh=a*1000+b*100+c*10+d; //将ABCD,四位数合并并进行判断是否为正确密码
if(zh==1234){ //设密码为1234
j=0;
biao1=1; //将biao1标志位置1便为密码正确
keyz=17; //使按键值跳出最大值15便不会循坏显示
}
else{
j=0;
biao1=0; //反之密码错误
keyz=17;
Fen(20,200); //蜂鸣器报警
}
zh=0;a=10,b=10,c=10,d=10; //重置ABCD变量
for(i=0;i<sizeof(zi);i++){
writecom(0x80+i);
writedat(zi[i]); }
}
}