AT89C51单片机电子密码锁

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

AT89C51单⽚机电⼦密码锁
基于AT89C51单⽚机电⼦密码锁
#include "main.h"
/******************** LCD PART START *******************************/ //5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//读状态
unsigned char ReadStatusLCM(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);
}
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太⾼可以在这后加⼩的延时
LCM_E = 0; //延时
LCM_E = 1;
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}
//读数据
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}
void LCMInit(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); // 显⽰开及光标设置
}
void LCD_write_char(unsigned char X,unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能⼤于15,Y不能⼤于1
if (Y)
X |= 0x40; //当要显⽰第⼆⾏时地址码+0x40;
X |= 0x80; // 算出指令码
WriteCommandLCM(X, 0); //这⾥不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显⽰⼀串字符
void LCD_write_string(unsigned char X,unsigned char Y, unsigned char code *DData) {
unsigned char ListLength;
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
#define uchar unsigned char
#define uint unsigned int
/******************** LCD PART START *******************************/
void delay(uint z) //延时
uint x,y;
for(x=z;x>0;x--)
for(y=124;y>0;y--);
}
sbit e=P2^5;
sbit rw=P2^6;
sbit sr=P2^7;
uchar code name[]="zxs"; uchar code name1[]="zcf"; uchar code name2[]="zx"; void write_com(uchar com) {
int rs;
rs=0;
P0=com;
delay(5);
e=1;
delay(5);
e=0;
}
void write_data(uchar date) {
int rs;
rs=1;
P0=date;
delay(5);
e=1;
delay(5);
e=0;
}
void init()
{
e=0;
rw=0;
write_com(0x0c); write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void display()
{
uchar i;
for(i=0;i<3;i++)
{
write_data(name[i]);
}
write_com(0x80+0x40);
for(i=0;i<3;i++)
{
write_data(name1[i]);
}
}
void main()
{
init();
display();
}
#include
#define uchar unsigned char
uchar starbuf[10];
uchar wordbuf[8];
uchar pw[8]={1,2,3,4,5,6,7,8};
uchar pwbuf[8];
uchar count=0; // 初始没有输⼊密码,计数器设为0 uchar inputflag=0; // 先处于密码输⼊状态,⾮密码修改状态bit enterflag=0; // 没有按下确认键
bit pwflag=0; // 密码标志先置为0
sbit warn=P3^6;
#define lcd_data P0
sbit rs=P2^7;
///////////////////////LCD1602驱动程序///////////////////////
void delay_1602(unsigned int i)
{
while(i--);
}
void enrw()
{
rs=0;
rw=0;
e=0;
delay_1602(250);
e=1;
}
write_data(uchar c)
{
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(uchar m)//写命令,注意与写数据的区别
{
enrw();
}
display(uchar row,uchar colum,uchar *s)//⾏列字符写字符串,简单的指针应⽤{ uchar p;
if(row==1)
p=0x82+colum-1;
else
p=0xC0+colum-1;
write_cmd(p);
for(;*s!='\0';s++)
write_data(*s);
}
void lcd_display( unsigned char a, unsigned char b,unsigned char i) //⾏列数{ switch (i)
{
case 0: display( a,b, "0") ; break; /* 0 */
case 1: display( a,b, "1") ; break; /* 1 */
case 2: display( a,b, "2") ; break; /* 2 */
case 3: display( a,b, "3") ; break; /* 3 */
case 4: display( a,b, "4") ; break; /* 4 */
case 5: display( a,b, "5") ; break; /* 5 */
case 6: display( a,b, "6") ; break; /* 6 */
case 7: display( a,b, "7") ; break; /* 7 */
case 8: display( a,b, "8") ; break; /* 8 */
case 9: display( a,b, "9") ; break; /* 9 */
default: break;
}
}
/* 键消抖延时函数 */
void delay(unsigned int i)
{
int j;
for(;i>0;i--)
for(j=0;j<100;j++);
/* 键扫描函数 */
uchar keyscan(void)
{
uchar scancode,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));
}
else scancode = (scancode<<1)|0x01; // ⾏扫描码左移⼀位} }
}
return(0); // ⽆键按下,返回值为0 }
/* 密码⽐较函数 */
bit pwcmp(void)
{
bit flag;
uchar i;
for (i=0;i<8;i++)
{
if (pw[i]==pwbuf[i])
flag = 1;
else
}
return(flag);
}
/* 密码清除函数 */
void pwclk(unsigned char k)
{
unsigned char i;
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清除已经输⼊的密码} }
/* 按键声响函数 */
void alarm()
{
unsigned char i;
for(i=0;i<200;i++)
{
warn=!warn;
delay(1);
}
}
/* 密码报警函数 */
void alarm1()
{
unsigned int i;
for(i=0;i<2000;i++) {
/* 呼叫报警函数 */
void alarm2()
{
unsigned char i=12; unsigned char a,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--;
}
}
/* 按键处理函数 */
void key_conduct(unsigned char a,unsigned char b) {
switch(a)
{
case 0x11: // 1⾏1列,数字0
if (count<8)
{
if(b==0)
{
starbuf[count] = '*'; // 对应密码位上显⽰'*'
pwbuf[count] = 0;
{
pw[count] = 0;
wordbuf[count] = 0;
lcd_display(2,count+1,wordbuf[count]); }
count++;
}
alarm();
break;
case 0x21: // 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;
case 0x41: // 1⾏3列,数字2 if (count<8) {
if(b==0)
{
starbuf[count] = '*'; // 对应密码位上显⽰'*' pwbuf[count] = 2;
pw[count] = 2;
wordbuf[count] = 2;
lcd_display(2,count+1,wordbuf[count]); }
count++;
}
alarm();
break;
case 0x81: // 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;
case 0x12: // 2⾏1列,数字4 if (count<8) {
if(b==0)
{
starbuf[count] = '*'; // 对应密码位上显⽰'*' pwbuf[count] = 4;
}
pw[count] = 4;
wordbuf[count] = 4;
lcd_display(2,count+1,wordbuf[count]); }
count++;
}
alarm();
break;
case 0x22: // 2⾏2列,数字5 if (count<8) {
if(b==0)。

相关文档
最新文档