基于51单片机的密码锁程序

/*
密码锁程序,已调试成功
*/

#include
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit lcd_rs=P2^5;//1602lcd数据/命令选择引脚
sbit lcd_rw=P2^6;//1602lcd读写引脚
sbit lcd_en=P2^7;//1602lcd使能端
sbit scl=P1^5; //24c08 SCL
sbit sda=P3^6; //24c08 SDA
sbit Int0=P3^2; //外部中断0
sbit In=P3^3;//输入密码键
sbit Ch=P3^4;//修改密码键
sbit d=P1^2;//蜂鸣器驱动引脚
uchar Count;
uchar m,tmp,lock_flag;
static uint kai=0;
uchar code Seg_table[]="0123456789ABCDEF";
uchar Enter[14]="Iput Password:";
uchar init_password[6]="123456";
uchar a[5]="RIGHT";
uchar b[16]="The new password";
unsigned char code pu[282]={
0x03,0xfb,0x05,0x00,0x00,0x04,
0x03,0xfb,0x02,0x03,0xfb,0x02,
0x43,0xfc,0x02,0x0b,0xfc,0x02,
0x8f,0xfb,0x02,0x8f,0xfb,0x02,
0x8f,0xfb,0x02,0x03,0xfb,0x02,
0x8f,0xfb,0x05,0x00,0x00,0x03,
0x43,0xfc,0x02,0x8f,0xfb,0x02,
0x43,0xfc,0x02,0x8f,0xfb,0x02,
0x43,0xfc,0x04,0x8f,0xfb,0x02,
0x03,0xfb,0x02,0x8f,0xfb,0x02,
0x03,0xfb,0x02,0x14,0xfa,0x02,
0x8f,0xfb,0x02,0x03,0xfb,0x05,
0x00,0x00,0x03,0x03,0xfb,0x05,
0x00,0x00,0x04,0x03,0xfb,0x02,
0x03,0xfb,0x02,0x43,0xfc,0x02,
0x0b,0xfc,0x02,0x8f,0xfb,0x02,
0x8f,0xfb,0x02,0x8f,0xfb,0x02,
0x03,0xfb,0x02,0x8f,0xfb,0x02,
0x00,0x00,0x03,0x43,0xfc,0x02,
0x8f,0xfb,0x02,0x43,0xfc,0x02,
0x8f,0xfb,0x02,0x43,0xfc,0x04,
0x8f,0xfb,0x02,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0x08,0xfd,0x02,
0xab,0xfc,0x02,0x00,0x00,0x03,
0x08,0xfd,0x02,0xab,0xfc,0x02,
0x08,0xfd,0x02,0xab,0xfc,0x02,
0x08,0xfd,0x04,0xab,0xfc,0x02,
0x43,0xfc,0x02,0xab,0xfc,0x02,
0x43,0xfc,0x02,0x43,0xfc,0x04,
0x08,0xfd,0x04,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0x08,0xfd,0x04,
0xab,0xfc,0x04,0xab,0xfc,0x02,
0x43,0xfc,0x02,0x43,0xfc,0x04,
0x43,0xfc,0x04,0x8f,0xfb,0x04,
0xab,0xfc,0x04,0x00,0x00,0x04,
0x08,0xfd,0x02,0xab,0xfc,0x02,
0x08,0xfd,0x02,0xab,0xfc,0x02,
0x08,0xfd,0x04,0xab,0xfc,0x02,
0x43,0xfc,0x02,0xab,0xfc,0x02,
0x43,0xfc,0x02,0x43,0xfc,0x02,
0x08,0xfd,0x04,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0x08,0xfd,0x02,
0xab,0xfc,0x02,0xab,0xfc,0x05,
0x00,0x00,0x02,0x03,0xfb,0x02,
0x8f,0xfb,0x02,0xab,0xfc,0x04,
0x43,0xfc,0x02,0x43,0xfc,0x05
};

/*******************************************************************
*名称:delay_music()
*功能:音乐节拍延时
*输入:a a=1,1/16/拍,a=2,1/8拍,a=4,1/4拍
*输出:无
********************************************************************/
void delay_music(unsigned char a)
{
unsigned int b;
while(a--)
{
for(b=10300;b>=1;b--);
}
}
/********************************************************************
* 名称 : delay1()
* 功能 : 短暂延时
* 输入 : x
* 输出 : 无
***********************************************************************/
void delay1(uchar x)
{
uint i;
for(i=0; i}
/********************************************************************
* 名称 : Delay_1m

s()
* 功能 : 延时,延时时间为 1ms * i
* 输入 : i(延时1ms的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)
{
uchar x, j;
for(j=0; jfor(x=0; x<=148; x++);
}
/********************************************************************
* 名称 : Delay_xMs()
* 功能 : 延时子程序,经过软件调试,测得延时程序大概为55us.
* 输入 : x
* 输出 : 无
***********************************************************************/
void Delay_xMs(uint x)
{
uint i,j;
for(i=0; i{
for(j=0; j<3; j++);
}
}
/********************************************************************
* 名称 : flash()
* 功能 : 延时,时间为2个NOP,大概为2US
* 输入 : 无
* 输出 : 无
***********************************************************************/
void flash(void)
{
_nop_();
_nop_();
}

/********************************************
*名称:delay()
*功能:延时大概140us
*输入:无
*输出:无
*********************************************/
void delay()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++);
}
/*********************************************
*名称:lcd_writecom(uchar com)
*功能:向1602写入命令
*输入:命令
*输出:无
**********************************************/
void lcd_writecom(uchar com)
{
lcd_rs=0;
lcd_rw=0;
lcd_en=0;
P0=com;
delay();
lcd_en=1;
delay();
lcd_en=0;
}
/**********************************************
*名称:lcd_readdata(uchar dat)
*功能:向1602lcd写入数据
*输入:dat
*输出:无
***********************************************/
void lcd_writedata(uchar dat)
{
lcd_rs=1;
lcd_rw=0;
lcd_en=0;
P0=dat;
delay();
lcd_en=1;
delay();
lcd_en=0;
}
/*****************************************
*名称:lcd_init()
*功能:1602lcd初始化
*输入:无
*输出:无
******************************************/
void lcd_init()
{
lcd_writecom(0x38);
lcd_writecom(0x0c);
lcd_writecom(0x06);
lcd_writecom(0x01);
lcd_writecom(0x80);
}
/************************************************
*名称:lcd_char(uchar row ,uchar cloum,uchar dat)
*功能:在lcd的第row行,第cloum列,写入数据dat
*输入:row cloum dat
*************************************************/
void lcd_char(uchar row ,uchar cloum,uchar dat)
{
if(row==1)
{
lcd_writecom(0x80+cloum);
lcd_writedata(dat);
}
else
{
lcd_writecom(0x80+0x40+cloum);
lcd_writedata(dat);
}
}
/*********************************************
名称:lcd_string(uchar row,uchar cloum,uchar *p)
功能:从第row行 ,第cloum列,把一串字符写入lcd
输入:row cloum p
**********************************************/
void lcd_string(uchar row,uchar cloum, uchar *p)
{
uchar a;
if(row==1) a=0x80;
if(row==2) a=0xc0;
a=a+cloum-1;
lcd_writecom(a);
while(1)
{
if(*p=='\0') break;
lcd_writedata(

*p);
p++;
}


}
/********************************************************************
* 名称 : x24c02_init()
* 功能 : 24c02初始化子程序
* 输入 : 无
* 输出 : 无
***********************************************************************/
void x24c02_init(void)
{
scl = 1;
flash();
sda = 1;
flash();
}
/********************************************************************
* 名称 : start(void)
* 功能 : 启动I2C总线
* 输入 : 无
* 输出 : 无
***********************************************************************/
void start(void)
{
sda = 1;
flash();
scl = 1;
flash();
sda = 0;
flash();
scl = 0;
flash();
}
/********************************************************************
* 名称 : stop()
* 功能 : 停止I2C总线
* 输入 : 无
* 输出 : 无
***********************************************************************/
void stop()
{
sda = 0;
flash();
scl = 1;
flash();
sda = 1;
flash();
}
/********************************************************************
* 名称 : writex()
* 功能 : 写一个字节
* 输入 : j(需要写入的值)
* 输出 : 无
***********************************************************************/
void writex(uchar j)
{
uchar i,temp;
temp = j;
for(i=0; i<8; i++)
{
temp = temp << 1;
scl = 0;
flash();
sda = CY;
flash();
scl = 1;
flash();
}
scl = 0;
flash();
sda = 1;
flash();
}
/********************************************************************
* 名称 : readx()
* 功能 : 读一个字节
* 输入 : 无
* 输出 : 读出的值
***********************************************************************/
uchar readx(void)
{
uchar i, j, k = 0;
scl = 0;
flash();
sda = 1;
for(i=0; i<8; i++)
{
flash();
scl = 1;
flash();
if(sda == 1)
{
j = 1;
}
else j = 0;
k = (k << 1) | j;
scl = 0;
}
flash();
return(k);
}
/********************************************************************
* 名称 : clock()
* 功能 : I2C总线时钟
* 输入 : 无
* 输出 : 无
***********************************************************************/
void clock(void)
{
uchar i = 0;
scl = 1;
flash();
while((sda == 1) && (i < 255))
{
i++;
}
scl = 0;
flash();
}
/********************************************************************
* 名称 : x24c02_read()
* 功能 : 从24c02中读出值
* 输入 : address(要在这个地址读取值)
* 输出 : 从24c02中读出的值
***********************************************************************/
uchar x24c02_read(uchar address)
{
uchar i;
start();
writex(0xa0);
clock();
writex(address);
clock();
start();
writex(0xa1);
clock();
i = readx();
stop();
delay1(10);
return(i);
}
/********************************************************************
* 名称 : x24c02_write()
* 功能 : 想24c02中写入数据
* 输入 : address(地址) , info(值)
* 输出 : 无
**********************

*************************************************/
void x24c02_write(uchar address, uchar info)
{
start();
writex(0xa0);
clock();
writex(address);
clock();
writex(info);
clock();
stop();
delay1(50);
}
/*******************************************************
*函数名:keyscan()
*功能:键盘扫描
*输入:无
*输出:键值
********************************************************/
uchar keyscan()
{
uchar temp,num,k;
P1=0xfe;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
Delay_1ms(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:num=1;
break;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=4;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
k=Seg_table[num-1];

}
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
Delay_1ms(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=5;
break;
case 0xdd:num=6;
break;
case 0xbd:num=7;
break;
case 0x7d:num=8;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
k=Seg_table[num-1];

}
}

P1=0xfb;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
Delay_1ms(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=9;
break;
case 0xdb:num=10;
break;
case 0xbb:num=11;
break;
case 0x7b:num=12;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
k=Seg_table[num-1];

}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
Delay_1ms(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=13; break;
case 0xd7:num=14; break;
case 0xb7:num=15; break;
case 0x77:num=16; break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
k=Seg_table[num-1];
}

}
return k;
}
/********************************************************************
*名称:play()
*功能:播放音乐《猪之歌》
*输入:无
*输出:无
*************************************

********************************/
void play()
{
uchar xun=94;
kai=0;
TMOD=0x01;
EA=1;
ET0=1;
TH0=0xff;
TL0=0xf0;
while(xun>=1)
{
TR0=1;
if((pu[kai==0])&(pu[kai+1]==0))
TR0=0;
delay_music(pu[kai+2]);
TR0=0;
kai+=3;
xun--;
}
}
/*********************************************
*名称Input_password()
*功能:输入密码
*输入:无
*输出:无
**********************************************/
void Input_password()
{
uchar i,j,k=0,flag;
uchar input[6];
while(1)
{
if(lock_flag==5)break;
if(In==0)
{
Delay_1ms(5);
if(In==0)
{
lcd_init();
lcd_string(1,1,"Input Password");
while(!In);
P1=0xf0;
while(1)
{
while((P1&0xf0)!=0xf0)
{
m=keyscan();
lcd_char(2,j,'*');
input[j]=m;
P1=0xf0;
j++;
if(j==6)
{
break;
}
}
if(j==6)
{
j=0;
break;
}
}

for(i=0;i<6;i++)
{
if(input[i]=x24c02_read(i))
flag=1;
else
{
flag=0;lcd_init();
lcd_string(1,4,"Error!!!");lock_flag++;break;
}
}
if(flag==1)
{
lcd_init();
lcd_string(1,5,"MUSIC");
lcd_string(2,5,"A PIG'SONG");
while(1)
{
play();
}
}
}

}
}
}
/*********************************************
*名称:Change_Password()
*功能:改变密码
*输入:无
*输出:无
**********************************************/
void Change_Password()
{
uchar i,j,flag;
uchar input[6];
uchar input2[6],input1[6];
while(1)
{
if(Ch==0)
{
Delay_1ms(5);
if(Ch==0)
{
lcd_init();
lcd_string(1,1,"The old Password");
while(Ch);
P1=0xf0;
while(1)
{
while((P1&0xf0)!=0xf0)
{
m=keyscan();
lcd_char(2,j,'*');
input[j]=m;
P1=0xf0;
j++;
if(j==6)
{
break;
}
}
if(j==6)
{
j=0;
break;
}
}
for(i=0;i<6;i++)
{
if(input==x24c02_read(i))
flag=1;
else
{
flag=0;
lcd_init();
lcd_string(1,4,"Error!!!");
break;
}
}
while(flag==1)
{
lcd_init();
lcd_string(1,1,"Password RIGHT!");
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
lcd_init();
lcd_string(1,1,"The new password");
P1=0xf0;
while(1)
{
while((P1&0xf0)!=0xf0)
{

m=keyscan();
lcd_char(2,j,'*');
input1[j]=m;
P1=0xf0;
j++;
if(j==6)
{
//j=0;
break;
}
}
if(j==6)
{
j=0;
break;
}
}

lcd_init();
tmp=input1[5];
lcd_string(1,2,"Input again");
P1=0xf0;
while(1)
{
while((P1&0xf0)!=0xf0)
{
m=keyscan();
lcd_char(2,j,'*');
input2[j]=m;
P1=0xf0;
j++;
if(j==6)
{
break;
}
}
if(j==6)
{
j=0;
break;
}
}
flag=0;
for(i=0;i<6;i++)
{
if(input1==input2) flag=1;
else
{

flag=0;
lcd_init();
lcd_string(1,1,"Don't agree!!");
break;
}
}
if(flag==1)
{
for(i=0;i<6;i++)
{
x24c02_write(i,input2);
Delay_1ms(100);
}

lcd_init();
lcd_string(1,6,"Modify");
lcd_string(2,2,"Successfully!");
tmp=input2[5];
Input_password();
}
}

}
}

}
}
/********************************************************************
* 名称 : Time0_Init()
* 功能 : 定时器的初始化,定时时间可用光碟中软件计算,11.0592MZ晶振,10ms
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Init()
{
TMOD = 0x01;
IE = 0x82;
TH0 = 0xDC;
TL0 = 0x00;
}
/********************************************************************
* 名称 : Time0_Int()
* 功能 : 定时器中断,中断中实现 长度加1
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Int() interrupt 1
{
TL0=pu[kai];
TH0=pu[kai+1];
d=~d; //长度加1
}


/********************************************************************
* 名称 : Main(void)
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{
uchar i;
x24c02_init() ;
lcd_init();
Time0_Init();
lcd_string(1,1,"Password Lock");
for(i=0;i<6;i++);
{
x24c02_write(i,init_password);
Delay_1ms(100);
}
while(1)
{
if(In==0)
{
Delay_1ms(5);
if(In==0)
Input_password();
if(lock_flag==5)
{
lcd_init();
lcd_string(1,3,"NOT ALlOW ");
lcd_string(2,5,"ACCESS!!!");
break;
}
}
if(Ch==0)
{
Delay_1ms(5);
if(Ch==0)
Change_Password();
}

}

while(1);
}







********************************************************************
* 文件名 : 液晶1602显示.c
* 描述 : 该程序实现了对液晶1602的控制。
* 创建人 : 东流,2009年4月10日
* 版本号 : 2.0
**************************

*********************************************/
//#include
//#define uchar unsigned char
//#define uint unsigned int

//这三个引脚参考资料
sbit E=P2^7; //1602使能引脚
sbit RW=P2^6; //1602读写引脚
sbit RS=P2^5; //1602数据/命令选择引脚


/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/

void delay_us()
{
int i,j;
for(i=0; i<=100; i++)
for(j=0; j<=20; j++)
;
}

/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/

void enable(uchar del)
{
P0 = del;
RS = 0;
RW = 0;
E = 0;
delay_us();
E = 1;
delay_us();
}

/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void write(uchar del)
{
P0 = del;
RS = 1;
RW = 0;
E = 0;
delay_us();
E = 1;
delay_us();
}

/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
}

/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}

/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1)
{
if(*p == '\0') break;
write(*p);
p++;
}
}
/*************************************************************

**
显示程序
****************************************************************/
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
**********************************************************************
void Main()
{
uchar i = 48;
L1602_init();
L1602_char(1,5,'b');
L1602_string(1,1," 0123456789 ");
L1602_string(2,1," ABCDEDGHIJ ");
while(1);
} */











相关文档
最新文档