更新程序:#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;
}
}
}
|