#include
#include
#include
#define uint unsigned int
#define uchar unsigned char
#define NOP4() {_nop_();_nop_();_nop_();_nop_();}
sbit lcdrs=P2^0; //1602液晶控制端
sbit lcdrw=P2^1;
sbit lcden=P2^2;
sbit Beep=P2^3;
sbit Red=P2^4;
sbit Green=P2^5;
sbit Lamp=P2^6;
sbit SCL=P3^0;
sbit SDA=P3^1;
uchar num=0;//按键次数
uchar Wrong=0; //错误次数
uchar Count=0; //开锁次数
uchar Timer=0; //中断计数器
uchar k=0; //数组累加
uchar Sure_temp,Cancel_temp;//保存按下确认键和取消键P1的值
/**************************各数组定义*******************************/
//按键次数码表
uchar code Count_Table[]="123456789";
//键盘特征码
uchar code Key_Table[]={0xee,0xde,0xbe,0x7e,
0xed,0xdd,0xbd,0x7d,
0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77};
uchar Buffer[]={0,0,0,0,0,0}; //按键数值缓存数组
uchar Buffer_Reset[]={0,0,0,0,0,0}; //重置密码缓存
uchar Passedword[]={0,0,0,0,0,0};//密码数组 (这里开始出厂密码为比赛日期57)
/*************************************************/
//声光报警
void Alarm()
{
uchar i;
Red=0;
for(i=0;i<120;i++)
{
Beep=~Beep;
Delay(2);
}
}
void Delay(uchar z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/**********************1602液晶显示器初始化函数********************/
void write_com(uchar com)
{
lcdrs=0; //发送指令RS置低电平
lcdrw=0;
P0=com;
Delay(5);
lcden=1;
Delay(5);
lcden=0;
}
void write_data(uchar dat)
{
lcdrs=1;//发送数据RS置高电平
lcdrw=0;
P0=dat;
Delay(5);
lcden=1;//EN向下脉冲
Delay(5);
lcden=0;
}
void lcd_initial()
{
lcden=0;
lcdrw=0;
write_com(0x38); //设置16*2显示,5*7点阵,8为显示
Delay(1);
write_com(0x0c); //设置开显示,不显示光标
Delay(1);
write_com(0x06); //写一个字符后地址指针加1
Delay(1);
write_com(0x01); //显示清0,数据指针清0
Delay(1);
}
void write_string(uchar *str)
{
uchar i;
write_com(0x80); //第一行显示,主要用于密码重置时的提示
for(i=0;i
{
write_data(str[i]);
}
}
/****************IIC24C04A初始化函数****************************/
void Start()
{
SDA=1;SCL=1;NOP4();SDA=0;NOP4();SCL=0;
}
void Stop()
{
SDA=0;SCL=0;NOP4();SCL=1;NOP4();SDA=1;NOP4();
}
void RACK()
{
SDA=1;NOP4();SCL=1;NOP4();SCL=0;
}
void NO_ACK()
{
SDA=1;SCL=1;NOP4();SCL=0;SDA=0;
}
void Write_A_Byte(uchar b)
{
uchar i;
for(i=0;i<8;i++)
{
b<<=1;SDA=CY;_nop_();SCL=1;NOP4();SCL=0;
}
RACK();
}
uchar Receive_A_Byte()
{
uchar i,d;
for(i=0;i<8;i++)
{
SCL=1;d<<=1;d|=SDA;SCL=0;
}
return d;
}
void Write_Random_Address_Byte(uchar add,uchar dat)
{
Start();
Write_A_Byte(0xa0);
Write_A_Byte(add);
Write_A_Byte(dat);
Stop();
Delay(10);
}
uchar Read_Current_Address_Data()
{
uchar d;
Start();
Write_A_Byte(0xa1);
d=Receive_A_Byte();
NO_ACK();
Stop();
return d;
}
uchar Random_Read(uchar addr)
{
Start();
Write_A_Byte(0xa0);
Write_A_Byte(addr);
Stop();
return Read_Current_Address_Data();
}
/********************按键处理函数***********************/
//确认键处理 按键检测
void Sure_Key()
{
uchar flag;
uchar i;
write_com(0x80); //第一行0x80+0x00
write_data(Count_Table[Count++]);//显示输入次数
Delay(200);
if(Count>=10){P0=0XC0;Count=0;}
for(i=0;i<6;i++)
{
if(Buffer[i]==Passedword[i]){flag=1;continue;}
else {flag=0;break;}
}
//结果处理
if(flag==1){k=0;Green=0;Lamp=0;Red=1;write_com(0x80+0x40);for(i=0;i<16;i++)write_data('\0');Delay(200);}//正确绿灯亮,锁打开
else {k=0;Alarm();Wrong++;Green=1;Lamp=1;write_com(0x80+0x40);for(i=0;i<16;i++)write_data('\0');Delay(200);} //错误则声光报警
if(Wrong==3) {Sure_temp=P1;TR0=1;Wrong=0;} //错误三次则锁定键盘3秒钟
}
//取消键处理
void Cancel_Key()
{
uchar i;
k=0;
for(i=0;i<6;i++)Buffer[i]=0;Delay(100);
write_com(0x80+0x40);
for(i=0;i<16;i++)write_data('\0');
}
//锁定键
void Lock()
{
uchar i;
k=0;Alarm();Green=1;Lamp=1;Delay(200);
Cancel_Key();
}
//清屏键
void Clear_Lcd()
{
k=0;Cancel_Key();
write_com(0x01);
}
//重置键
void Reset_Key()
{
uchar i;
k=0;
write_com(0x10);
write_string("Input Passedword:");
}
//重置确认键
void Reset_Sure_Key()
{
uchar i,flag;
for(i=0;i<6;i++){if(Buffer[i]==Passedword[i]){flag=1;continue;} else {flag=0;break;}}//输入老密码并判断
if(flag==1) {write_com(0x01);write_string("Input Newword:");Cancel_Key();}
else {Reset_Key();}
/*最初的想法是用一个按键来进行重置键处理
uchar state=1; //重置按键第一次为判断是否与老密码一样,第二次进行新密码的保存
state=~state; //初始为state=1;
k=0;
switch(state)
{
case 0:for(i=0;i<6;i++) //输入老密码并判断
{if(Buffer[i]==Passedword[i]){flag=1;continue;}
else {flag=0;break;}}
if(flag==1) {write_com(0x01);write_string("Input Newword:");}
else {state=~state;Reset_Key();}break;
case 1: if(flag==1) {for(i=0;i<6;i++)//老密码正确再保存新密码
Write_Random_Address_Byte(i,Buffer[i]);}
}
*/
}
//重置保存
void Reset_Save()
{
uchar i;
k=0;
for(i=0;i<6;i++) Write_Random_Address_Byte(i,Buffer[i]); //老密码正确再保存新密码
for(i=0;i<6;i++)Passedword[i]=Random_Read(i);
write_com(0x01);write_string("Succeed!");Delay(1000);write_com(0x01);
}
/**************************按键扫描函数***********************************/
//按键扫描
void Key_Play()
{
uchar i=0;
uchar num;
uchar temp;
uchar Key,c;
P1=0xf0;
if(P1!=0xf0)
{
Delay(5);
if(P1!=0xf0)
{
temp=P1;
P1=0x0f;
Key=temp|P1;
for(i=0;i<16;i++)
if(Key==Key_Table[i]) {num=i;break;}
Buffer[k++]=num;
switch(num)
{
case 10:Sure_Key();break; //确认
case 11:Cancel_Key();break; //取消
case 12:Reset_Key();break; //重置
case 13:Reset_Sure_Key();break;//重置确认
case 14:Reset_Save();break; //上锁
case 15:Lock();; //清屏
}
write_com(0x80+0x40); //第二行0x80+0x40
for(i=0;i
write_data('*');
}
do{//等待按键抬起
temp=P1;
temp=temp&0x0f;
}
while(temp!=0x0f);
}
}
//************************主函数************************//
void main()
{
uchar i;
lcd_initial();
P0=0x3f;//次数默认为0
P2=0XFF;//初始全关
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1; //密码错误定时器中断0
for(i=0;i<6;i++)Passedword[i]=Random_Read(i);
while(1)
{
Key_Play();
Delay(2);
}
}
//定时器0中断 键盘锁定3秒
void Inter_Timer0() interrupt 1
{
uchar temp;
Timer++;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
Beep=~Beep;Delay(20);
P1=0xf0;
if(P1!=0xf0)
{
Delay(5);
Timer=0;
}
//如果3秒内无按键则回复正常
if(Timer==60){Timer=0;Beep=0;Red=1;TR0=0;}
}