|
軟件部分(程序清單):
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define SET 10
#define ENTER 11
#define AT 0 // 密碼保存在E2PROM中的地址
//#define PASSWORD_NUM 6
#define PWY 0xA8 // 密碼存在標(biāo)志
typedef struct{
uchar flag;
uchar codes[6];
}PASSWORD;
PASSWORD password;
uchar buf[6];
uchar code table[]="______";
sbit rs=P2^5; //LCD1602
sbit rw=P2^6;
sbit en=P2^7;
sbit scl=P1^5; //24C02
sbit sda=P3^6;
sbit buzz=P2^3; //buzz
//uchar temp;
void delay2(uint cnt);
void delay1();
void delay(uint z);
void buzzer();
#include <keyscan.h>
#include <LCD1602.h>
#include<EEPROM(24C02).h>
/***********蜂鳴器發(fā)聲************/
void buzzer()
{
uint i;
for(i=0;i<80;i++)
{
buzz=~buzz;
delay2(80);
}
buzz=1;
}
/***********輸入密碼************/
void input_password(uchar *buf)
{
uchar i,k_num;
write_com(0x80+0x40);
for(i=0;i<6;i++) //速度很快,底下寫(xiě)密碼時(shí)不用for循環(huán)
{
write_data(table[ i]);
delay(20);
}
i=0; // 密碼的初始位置
while(i<6)
{
k_num=keyscan();
if(k_num==-1)
continue;
else
if((k_num>=0)&&(k_num<=9))
{
buf[ i]=k_num;
write_string(0x80+0x40+i,"*");
i++;
}
}
while(keyscan()!=ENTER);
}
/***********檢測(cè)密碼************/
bit check_buf(uchar *buf1,uchar *buf2)
{
uchar i;
for(i=0;i<6;i++)
{
if(buf1[ i]!=buf2[ i])
return 1;
}
return 0;
}
/***********主程序************/
void main()
{
lcd1602_init();
i2c_init();
read_buf((uchar *)&password,AT,sizeof(PASSWORD));
if(password.flag==PWY)
{
while(1)
{
write_string(0x80,"input password: ");
write_string(0x80+0x40," ");
input_password(buf);
/*if(!check_buf(buf,password.codes))
break;
write_string(0x80,"Password Error! ");
write_string(0x80+0x40," ");*/
while(keyscan()==-1);
}
}
while(1)
{
write_string(0x80, "Hello, welcome! ");
write_string(0x80+0x40, "Please set code");
while (keyscan()!= SET);
write_string(0x80, "New password: ");
write_string(0x80+0x40, " ");
input_password(buf);
write_string(0x80, "Input again: ");
write_string(0x80+0x40, " ");
input_password(password.codes);
if (!check_buf(buf, password.codes))
{
password.flag = PWY;
if (!write_buf((uchar *)&password, AT, sizeof(PASSWORD)))
{
write_string(0x80, "Password ");
write_string(0x80+0x40, "Successfully set");
while (keyscan()==-1);
continue;
}
}
write_string(0x80, "Password ");
write_string(0x80+0x40, "set failed ");
while(keyscan()==-1);
}
}
void delay2(uint cnt)//cnt是計(jì)數(shù)器(counter)
{
while(cnt--);
}
void delay1() //微秒級(jí)延時(shí)函數(shù),大概4~5微秒
{;;}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/***********EEPROM(24C02)存儲(chǔ)器************/
void start() //開(kāi)始信號(hào)
{
sda=1;
delay1();
scl=1;
delay1();
sda=0;
delay1();
}
void stop() //停止
{
sda=0;
delay1();
scl=1;
delay1();
sda=1;
delay1();
}
void respons()//應(yīng)答
{
uchar i;
scl=1; //高電平期間讀取信號(hào)
while((sda==1)&&(i<250))i++;//同時(shí)滿足SDA等于1和i小于250兩個(gè)條件的時(shí)候i=i+1,即i自動(dòng)加1.否則跳出循環(huán)
scl=0;
delay1();
}
void i2c_init()
{
sda=1;
delay1();
scl=1;
delay1();
}
void write_byte(uchar dat)
{
uchar i,temp2;
temp2=dat;
for(i=0;i<8;i++)
{
temp2=temp2<<1;
scl=0;
delay1();
sda=CY; //PSW中的最高位
delay1();
scl=1;
delay1();
}
scl=0;
delay1();
sda=1;
delay1();
}
uchar read_byte()
{
uchar i,j,k;
scl=0;
delay1();
sda=1;
delay1();
for(i=0;i<8;i++)
{
scl=1;
delay1();
if(sda==1)
j=1;
else
j=0;
k=(k<<1)|j;
scl=0;
delay1();
}
return k;
}
bit write_add(uchar address,uchar dat)
{
start();
write_byte(0xa0);//控制字節(jié)
respons();
write_byte(address); //地址
respons();
write_byte(dat); //數(shù)據(jù)
respons();
stop();
return 0;
}
uchar read_add(uchar address)
{
uchar dat;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
dat=read_byte();
stop();
return 0;
}
uchar write_buf(uchar *buf,uchar address,uchar length)
//*buf--代寫(xiě)數(shù)據(jù) ,address--eeprom地址,length--數(shù)據(jù)長(zhǎng)度
{
while(length--)
{
if(write_add(address++,*buf++))
return 1;
}
return 0;
}
uchar read_buf(uchar *buf,uchar address,uchar length)
//*buf--代寫(xiě)數(shù)據(jù) ,address--eeprom地址,length--數(shù)據(jù)長(zhǎng)度
{
while(length--)
{
if(read_add(address++))
buf++;
return 1;
}
return 0;
}
/********鍵盤(pán)掃描*********/
uchar keyscan()
{
uchar temp;
uchar num=-1;
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:num=1;break;
case 0xde:num=2;break;
case 0xbe:num=3;break;
case 0x7e:num=-1;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
if(num>=0)
buzzer();
}
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=4;break;
case 0xdd:num=5;break;
case 0xbd:num=6;break;
case 0x7d:num=-1;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
if(num>=0)
buzzer();
}
}
P1=0xfb;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=7;break;
case 0xdb:num=8;break;
case 0xbb:num=9;break;
case 0x7b:num=-1;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
if(num>=0)
buzzer();
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=0;break;
case 0xd7:num=SET;break;
case 0xb7:num=ENTER;break;
case 0x77:num=-1;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
if(num>=0)
buzzer();
}
}
return num;
}
/***********LCD1602液晶寫(xiě)指令************/
write_com(uchar com)
{
rs=0;
rw=0;
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
/***********LCD1602液晶寫(xiě)數(shù)據(jù)************/
write_data(uchar date)
{
rs=1;
rw=0;
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
/***********LCD1602液晶初始化************/
void lcd1602_init()
{
en=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
void write_string(uchar add_start,uchar *p)
{
write_com(add_start);
while(*p!='\0') // '\0'就是空操作符
{
write_data(*p++);//字符串沒(méi)結(jié)束,繼續(xù)指向下一個(gè)地址
}
}
|
|