更新程序:#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar code szjianzhibiao[]={0x77,0x7b,0x7d,
0xb7,0xbb,0xbd, //矩陣數字鍵盤鍵值
0xd7,0xdb,0xdd,
0xeb};
uchar code gnjianzhibiao[]={0x7e,0xbe,0xde, //矩陣功能鍵盤鍵值
0xee,0xed,0xe7};
uchar code mima[]={0x77,0x7d,0x77,0xb7, //設定的密碼
0x77,0x7d,0x77,0xb7};
uchar code table[]="HOLLE! User";
uchar code table1[]="Password";
uchar code table2[]="********";
uchar code table3[]=" error!";
uchar code table4[]=" OK! ";
uchar code table5[]=" "; //抹除輸入痕跡的空字符串
uchar code table6[]="0123456789";
uchar code table7[]="012345";
sbit green=P3^2; //綠燈
sbit blue=P3^3; //藍燈
sbit red=P3^4; //紅燈
sbit bao=P1^3; //蜂鳴器
sbit jdq=P3^7; //繼電器
sbit en=P1^2; //定義LCD1602使能端
sbit rw=P1^1;//定義LCD1602讀/寫選擇端
sbit rs=P1^0;//定義LCD1602數據/命令選擇端
uchar T1_NUM=0,T1_NUM1=0,T0_NUM=0,T0_NUM1=0;
uchar j=0,k=0,h=0,y=0,l=0,z=0,flag=0,flag1=0,flag2=0,p=0,d=0;
void delay (uchar del)
{
uint i,j;
for(i=0;i<del;i++) //延時程序
for(j=0;j<130;j++)
;
}
void lcd_wcom(uchar com)
{ rs=0; //選擇指令寄存器
rw=0; //選擇寫
P0=com; //把命令字送入P0
delay(10);
en=0;
delay(10); //延時一小會兒,讓1602準備接收數據
en=1;
delay(10); //使能線電平變化,命令送入1602的8位數據口
en=0;
}
void lcd_wdat(uchar dat) //1602寫數據函數
{
rs=1; //選擇數據寄存器
rw=0; //選擇寫
P0=dat; //把要顯示的數據送入P2
delay(10);
en=0;
delay(10); //延時一小會兒,讓1602準備接收數據
en=1;
delay(10); //使能線電平變化,數據送入1602的8位數據口
en=0;
}
void lcd_init()
{
lcd_wcom(0x38); //8位數據,雙列,5*7字形
lcd_wcom(0x0c); //開啟顯示屏,關光標,光標不閃爍
lcd_wcom(0x06); //顯示地址遞減,即寫一個數據后,顯示位置右移一位
lcd_wcom(0x01); //清屏
}
void xianshi()
{
uchar n,m=0;
lcd_wcom(0x80+0x02); //顯示地址上排第三位
for(m=0;m<12;m++) //將table[]中的數據依次寫入1602顯示
{
lcd_wdat(table[m]);
delay(5);
}
lcd_wcom(0x80+0x40);//顯示地址為0xc4,即下排第1位
for(n=0;n<8;n++) //將table1[]中的數據依次寫入1602顯示
{
lcd_wdat(table1[n]);
delay(5);
}
}
void xianshi1(uchar s)
{
uchar m;
lcd_wcom(0x80+0x48); //顯示地址上排第九位,顯示輸入的*號
for(m=0;m<s;m++) //將table[]中的數據依次寫入1602顯示
{
lcd_wdat(table2[m]);
delay(1);
}
}
void xianshi2()
{
uchar m;
lcd_wcom(0x80+0x48); //顯示地址上排第九位,顯示OK
for(m=0;m<8;m++) //將table[]中的數據依次寫入1602顯示
{
lcd_wdat(table4[m]);
delay(100);
}
}
void xianshi3()
{
uchar m;
lcd_wcom(0x80+0x48); //顯示地址上排第九位,顯示error
for(m=0;m<8;m++) //將table[]中的數據依次寫入1602顯示
{
lcd_wdat(table3[m]);
delay(100);
}
}
void xianshi5()
{
uchar m=0;
lcd_wcom(0x80+0x48); //顯示地上排第九位,清除顯示
for(m=0;m<8;m++) //將table[]中的數據依次寫入1602顯示
{
lcd_wdat(table5[m]);
delay(1);
}
}
void jishuqi( )
{
TMOD=0x10;
TH1=(65536-40000)/256;
TL1=(65536-40000)%256; //定時器T1,設置40ms
ET1=1;
EA=1;
TR1=1;
}
void time1() interrupt 3
{
TH1=(65536-40000)/256;
TL1=(65536-40000)%256;
T1_NUM++;
if(T1_NUM==25) //定時1S
{
T1_NUM=0;
T1_NUM1++;
p++;
lcd_wcom(0x80+0x0f); //顯示個位秒
lcd_wdat(table6[p]);
}
if(T1_NUM1==5) //定時5S
{
T1_NUM1=0;
if(flag==1)
{
red=~red;
bao=1; //紅燈狀態反轉
flag=0;
TR1=0;
lcd_wcom(0x80+0x0e);
lcd_wdat(table6[d]); //顯示十位秒
}
}
if(p==10)
{
p=0; //計時秒開始
d++;
if(d==6) //計時分開始
d=0;
}
}
void jishuqi1( )
{
TMOD=0x10;
TH0=(65536-40000)/256;
TL0=(65536-40000)%256; //定時器T1
ET0=1;
EA=1;
TR0=1;
}
void time0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //設置50ms
T0_NUM++;
if(T0_NUM==100) //定時1S(正常來說T0_NUM應該=20就是1S,由于有誤差,所以設置為100)
{
T0_NUM=0;
T0_NUM1++;
l++;
if(l==10)
{
l=0; //個位定時
z++;
if(z==6) //十位定時
z=0;
}
if(j-1!=flag2) //每1S檢測是否有按鍵按下
flag1=1; //沒有按下,則賦值為1;
}
if(T0_NUM1==50) //定時50S
{
T0_NUM1=0;
if(flag1>0&&flag1==1) //按鍵沒有按下
{
flag1=0; //清零
if(j==flag2&&P2==0xf0) //按鍵未操作且鍵盤按下次數未增加
{
red=0;
delay(30);
red=1; //超過50S未動作,清除數據并且清屏
xianshi5();
j=0;
k=0;
}
}
}
}
void key ()
{
uchar lie,jianzhi,szjianhao,szjianpan1,gnjianhao,caijimima[7],szjianhao2[7],sign,i;
if(flag==1)
{
xianshi3();
delay(100); //鎖定鍵盤并且報警
xianshi5();
}
else
{
P2=0xf0;
if(P2!=0xf0)
{ //按鍵去抖動
delay(10);
if(P2!=0xf0)
{
j=j+1; //數字按鍵計數
k=k+1; //功能按鍵計數
lie=P2;
P2=0x0f;
jianzhi=lie|P2;
for(i=0;i<10;i++)
{
if(jianzhi==szjianzhibiao[i])
{
szjianhao=szjianzhibiao[i]; //對比數字按鍵
szjianpan1=i; //具體按鍵數字保存起來,可作用數碼管顯示,此可以不用理會
sign=0; //是數字按鍵按下標記
break;
}
}
for(i=0;i<6;i++)
{
if(jianzhi==gnjianzhibiao[i])
{
gnjianhao=i; //對比功能按鍵
sign=1; //是功能按鍵按下標記
break;
}
}
while(P2!=0x0f);
delay(10);
}
if(sign==0) //數字按鍵按下判斷
{
bao=0;
delay(30); //蜂鳴器提示音
bao=1;
if(j==9) //連續九次輸入數字按鍵
{
xianshi3();
delay(30000);
xianshi5();
j=0;
k=0; //錯誤提示、報警并且清除數據
red=0;
delay(150);
red=1;
for(i=0;i<8;i++)
caijimima[i]=0;
}
else
{
for(i=j-1;i<j;i++)
{
caijimima[i]=szjianhao; //正確輸入并且暫存儲密碼
szjianhao2[i]=szjianpan1; //具體按鍵數字保存起來,可作用數碼管顯示,此可以不用理會
green=0;
delay(150);
green=1;
}
xianshi1(i);
}
}
if(sign==1) //功能按鍵判斷
{
flag1=0;
if(gnjianhao==3) //確認鍵判斷
{
if(k==9)
{
for(i=0;i<8;i++)
{
if(mima[i]==caijimima[i])
{
h=h+1; //對比計數
}
else
{
h=1;
break;
}
}
if(h==8) //密碼正確
{
k=0;
j=0;
h=0;
blue=0;
delay(150);
blue=1;
for(i=0;i<8;i++)
caijimima[i]=0;
xianshi2();
delay(10000);
xianshi5(); //開鎖
jdq=0;
delay(100);
jdq=1;
}
if(h==1) //密碼錯誤
{
bao=0;
delay(200);
bao=1;
y++; //密碼錯誤次數標記
h=0;
k=0;
j=0;
red=0;
delay(150);
red=1;
for(i=0;i<8;i++)
caijimima[i]=0;
xianshi3();
delay(30000);
xianshi5();
if(y==3)
{
y=0;
red=0;
flag=1; //三次密碼錯誤,鎖定鍵盤參數賦值
bao=0;
jishuqi(); //鎖定10S計數開始
}
}
}
else
{
k=0;
j=0;
xianshi3();//請繼續輸入8位完整密碼后在按確認鍵!
delay(30000);
xianshi5();
}
}
if(gnjianhao==2) //清零鍵判斷
{
for(i=0;i<7;i++)
{
caijimima[i]=0;
}
lcd_wcom(0x01);
xianshi();
k=0;
j=0;
}
if(gnjianhao==1) //退格鍵判斷
{
if(k==1&&j==1)
{
xianshi3();//錯誤,請輸入8位完整密碼!
delay(30000);
xianshi5();
red=0;
delay(200);
red=1;
delay(200);
red=0;
delay(200);
red=1;
j=j-1;
k=k-1;
}
if(j!=0&&k!=0)
{
j=j-2;
k=k-2;
xianshi5();
xianshi1(j);
}
}
if(gnjianhao==4)
;
if(gnjianhao==5)
;
}
}
}
}
void main ()
{
lcd_init(); //液晶初始化
delay(30);
xianshi();
jishuqi1();
while (1)
{
key(); //按鍵子程序
flag2=j; //將按鍵次數參數賦值給flag2
if(flag2==9) //超過九次,清零
flag2=0;
lcd_wcom(0x80+0x01);
lcd_wdat(table6[flag2]); //顯示按鍵次數
if(P2==0xf0) //判斷有沒有按鍵按下
{
lcd_wcom(0x80+0x0f);
lcd_wdat(table6[l]); //沒按鍵按下,就顯示倒計時
lcd_wcom(0x80+0x0e);
lcd_wdat(table6[z]);
}
else
{
l=0;
z=0; //有按鍵按下,這停止倒計時并且清零
T0_NUM=0;
T0_NUM1=0;
}
}
}
|