AT89C51单片机电子密码锁.docx
- 文档编号:23008807
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:27
- 大小:46.03KB
AT89C51单片机电子密码锁.docx
《AT89C51单片机电子密码锁.docx》由会员分享,可在线阅读,更多相关《AT89C51单片机电子密码锁.docx(27页珍藏版)》请在冰豆网上搜索。
AT89C51单片机电子密码锁
基于AT89C51单片机电子密码锁
#include"main.h"
/********************LCDPARTSTART*******************************/
//5ms延时
voidDelay5Ms(void)
{
unsignedintTempCyc=5552;
while(TempCyc--);
}
//读状态
unsignedcharReadStatusLCM(void)
{
LCM_Data=0xFF;
LCM_RS=0;
LCM_RW=1;
LCM_E=0;
LCM_E=0;
LCM_E=1;
Delay5Ms();
while(LCM_Data&Busy);//检测忙信号
return(LCM_Data);
}
//写数据
voidWriteDataLCM(unsignedcharWDLCM)
{
ReadStatusLCM();//检测忙
LCM_Data=WDLCM;
LCM_RS=1;
LCM_RW=0;
LCM_E=0;//若晶振速度太高可以在这后加小的延时
LCM_E=0;//延时
LCM_E=1;
}
//写指令
voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测
{
if(BuysC)ReadStatusLCM();//根据需要检测忙
LCM_Data=WCLCM;
LCM_RS=0;
LCM_RW=0;
LCM_E=0;
LCM_E=0;
LCM_E=1;
}
//读数据
unsignedcharReadDataLCM(void)
{
LCM_RS=1;
LCM_RW=1;
LCM_E=0;
LCM_E=0;
LCM_E=1;
return(LCM_Data);
}
voidLCMInit(void)//LCM初始化
{
LCM_Data=0;
WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1);//显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1);//关闭显示
WriteCommandLCM(0x01,1);//显示清屏
WriteCommandLCM(0x06,1);//显示光标移动设置
WriteCommandLCM(0x0C,1);//显示开及光标设置
}
//按指定位置显示一个字符,x表示列,Y表示行
voidLCD_write_char(unsignedcharX,unsignedcharY,unsignedcharDData)
{
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
if(Y)
X|=0x40;//当要显示第二行时地址码+0x40;
X|=0x80;//算出指令码
WriteCommandLCM(X,0);//这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
voidLCD_write_string(unsignedcharX,unsignedcharY,unsignedcharcode*DData)
{
unsignedcharListLength;
ListLength=0;
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
while(*DData)//若到达字串尾则退出'\0'就是0
{
if(X<=0xF)//X坐标应小于0xF
{
LCD_write_char(X,Y,*DData);//显示单个字符
DData++;
X++;
}
}
}
/************/
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
/********************LCDPARTSTART*******************************/
voiddelay(uintz)//延时
{
uintx,y;
for(x=z;x>0;x--)
for(y=124;y>0;y--);
}
sbite=P2^5;
sbitrw=P2^6;
sbitsr=P2^7;
ucharcodename[]="zxs";
ucharcodename1[]="zcf";
ucharcodename2[]="zx";
voidwrite_com(ucharcom)
{
intrs;
rs=0;
P0=com;
delay(5);
e=1;
delay(5);
e=0;
}
voidwrite_data(uchardate)
{
intrs;
rs=1;
P0=date;
delay(5);
e=1;
delay(5);
e=0;
}
voidinit()
{
e=0;
rw=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
voiddisplay()
{
uchari;
for(i=0;i<3;i++)
{
write_data(name[i]);
}
write_com(0x80+0x40);
for(i=0;i<3;i++)
{
write_data(name1[i]);
}
}
voidmain()
{
init();
display();
}
#include
#defineucharunsignedchar
ucharstarbuf[10];
ucharwordbuf[8];
ucharpw[8]={1,2,3,4,5,6,7,8};
ucharpwbuf[8];
ucharcount=0;//初始没有输入密码,计数器设为0
ucharinputflag=0;//先处于密码输入状态,非密码修改状态
bitenterflag=0;//没有按下确认键
bitpwflag=0;//密码标志先置为0
sbitwarn=P3^6;
#definelcd_dataP0
sbitrs=P2^7;
sbitrw=P2^6;
sbite=P2^5;
///////////////////////LCD1602驱动程序///////////////////////
voiddelay_1602(unsignedinti)
{
while(i--);
}
voidenrw()
{
rs=0;
rw=0;
e=0;
delay_1602(250);
e=1;
}
write_data(ucharc)
{
lcd_data=c;
rs=1;
rw=0;
e=0;
delay_1602(250);
e=1;
}
init_lcd(void)//初始化
{
lcd_data=0x01;//清屏幕
enrw();
lcd_data=0x38;//数据长度为8位,双行显示,5*7字符。
enrw();
lcd_data=0x0c;//打开显示开关
enrw();
lcd_data=0x06;//地址计数递增,显示屏不移动
enrw();
}
write_cmd(ucharm)//写命令,注意与写数据的区别
{
lcd_data=m;
enrw();
}
display(ucharrow,ucharcolum,uchar*s)//行列字符写字符串,简单的指针应用
{
ucharp;
if(row==1)
p=0x82+colum-1;
else
p=0xC0+colum-1;
write_cmd(p);
for(;*s!
='\0';s++)
write_data(*s);
}
voidlcd_display(unsignedchara,unsignedcharb,unsignedchari)//行列数
{
switch(i)
{
case0:
display(a,b,"0");break;/*0*/
case1:
display(a,b,"1");break;/*1*/
case2:
display(a,b,"2");break;/*2*/
case3:
display(a,b,"3");break;/*3*/
case4:
display(a,b,"4");break;/*4*/
case5:
display(a,b,"5");break;/*5*/
case6:
display(a,b,"6");break;/*6*/
case7:
display(a,b,"7");break;/*7*/
case8:
display(a,b,"8");break;/*8*/
case9:
display(a,b,"9");break;/*9*/
default:
break;
}
}
/*键消抖延时函数*/
voiddelay(unsignedinti)
{
intj;
for(;i>0;i--)
for(j=0;j<100;j++);
}
/*键扫描函数*/
ucharkeyscan(void)
{
ucharscancode,tmpcode;
P1=0xf0;//发全0行扫描码
if((P1&0xf0)!
=0xf0)//若有键按下
{
delay
(2);//延时去抖动
if((P1&0xf0)!
=0xf0)//延时后再判断一次,去除抖动影响
{
scancode=0xfe;//第一行变低
while((scancode&0x10)!
=0)//逐行扫描
{
P1=scancode;//输出行扫描码
if((P1&0xf0)!
=0xf0)//本行有键按下
{
tmpcode=(P1&0xf0)|0x0f;
/*返回特征字节码,为1的位即对应于行和列*/
return((~scancode)+(~tmpcode));
}
elsescancode=(scancode<<1)|0x01;//行扫描码左移一位
}
}
}
return(0);//无键按下,返回值为0
}
/*密码比较函数*/
bitpwcmp(void)
{
bitflag;
uchari;
for(i=0;i<8;i++)
{
if(pw[i]==pwbuf[i])
flag=1;
else
{
flag=0;
i=8;
}
}
return(flag);
}
/*密码清除函数*/
voidpwclk(unsignedchark)
{
unsignedchari;
for(i=0;i<8;i++)
{
wordbuf[i]=0;//数码管显示00000000
starbuf[i]=0;
if(k==0)
pwbuf[i]=0;//用FFFFFF清除已经输入的密码
else
pw[i]=0;//用FFFFFF清除已经输入的密码
}
}
/*按键声响函数*/
voidalarm()
{
unsignedchari;
for(i=0;i<200;i++)
{
warn=!
warn;
delay
(1);
}
}
/*密码报警函数*/
voidalarm1()
{
unsignedinti;
for(i=0;i<2000;i++)
{
warn=!
warn;
delay
(1);
}
}
/*呼叫报警函数*/
voidalarm2()
{
unsignedchari=12;
unsignedchara,b;
while(i>0)
{
for(a=0;a<150;a++)
{
warn=!
warn;
delay
(1);
}
for(b=0;b<150;b++)
{
warn=!
warn;
delay
(2);
}
i--;
}
}
/*按键处理函数*/
voidkey_conduct(unsignedchara,unsignedcharb)
{
switch(a)
{
case0x11:
//1行1列,数字0
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=0;
}
else
{
pw[count]=0;
wordbuf[count]=0;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x21:
//1行2列,数字1
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=1;
}
else
{
pw[count]=1;
wordbuf[count]=1;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x41:
//1行3列,数字2
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=2;
}
else
{
pw[count]=2;
wordbuf[count]=2;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x81:
//1行4列,数字3
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=3;
}
else
{
pw[count]=3;
wordbuf[count]=3;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x12:
//2行1列,数字4
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=4;
}
else
{
pw[count]=4;
wordbuf[count]=4;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x22:
//2行2列,数字5
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=5;
}
else
{
pw[count]=5;
wordbuf[count]=5;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x42:
//2行3列,数字6
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=6;
}
else
{
pw[count]=6;
wordbuf[count]=6;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x82:
//2行4列,数字7
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=7;
}
else
{
pw[count]=7;
wordbuf[count]=7;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x14:
//3行1列,数字8
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=8;
}
else
{
pw[count]=8;
wordbuf[count]=8;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x24:
//3行2列,数字9
if(count<8)
{
if(b==0)
{
starbuf[count]='*';//对应密码位上显示'*'
pwbuf[count]=9;
}
else
{
pw[count]=9;
wordbuf[count]=9;
lcd_display(2,count+1,wordbuf[count]);
}
count++;
}
alarm();
break;
case0x44:
//3行3列,确认键
enterflag=1;//确认键按下
if(b==0)
{
if(count==8)//只有输入8个密码后按确认键才作密码比较
pwflag=pwcmp();
else
pwflag=0;//否则直接pmflag赋0
pwclk(b);//输入密码并判断之后清除
}
else
{
if(count==8)//只有输入8个密码后按确认键才作密码比较
pwflag=1;
else
{
pwflag=0;
pwclk(b);
}
}
break;
case0x84:
//3行4列,取消键
count=0;//密码计数清零
pwclk(b);
init
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AT89C51 单片机 电子 密码锁