#include <reg52.h>
#include "delay.h"
#include "1602.h"
#define uc unsigned char
#define port P1
sbit kaisuo=P2^4;
// in:输入的密码和确认密码 k:已输入密码的个数 set:设置的密码,count:密码的个数 set1:用于设置密码
uc in[16],k=0,set[16]={0,1,2},count=3,set1[16],count1=0;
uc i=0,j=0,t=0,hang=0,lie=0; // i:按的是哪个键 j:接收键值 t:比较结果
unsigned int tt,ii,jj; // 是否大于5秒
void delay(uc c);
void delay1(uc c1);
void setting(void);
void again(void);
uc keyscan(void);
uc input(void);
uc compare(uc *m,uc x,uc *n,uc y);
void delay1(uc c1)
{
uc a1,b1;
for(;c1>0;c1--)
{
for(a1=38;a1>0;a1--)
for(b1=130;b1>0;b1--);
port = 0xf0;
if(port != 0xf0)
return;
}
}
void delay(uc c)
{
uc a,b;
for(;c>0;c--)
for(a=38;a>0;a--)
for(b=130;b>0;b--);
}
uc keyscan(void)
{
delay(1);
port=0xf0;
switch(port)
{
case 0xe0:lie=0;break;
case 0xd0:lie=1;break;
case 0xb0:lie=2;break;
case 0x70:lie=3;break;
}
port=0x0f;
switch(port)
{
case 0x0e:hang=0;break;
case 0x0d:hang=1;break;
case 0x0b:hang=2;break;
case 0x07:hang=3;break;
}
i=4*hang+lie;
return i;
}
uc input(void)
{
LCD_Write_String(0,0,"INPUT:");
while(1)
{
j=keyscan(); // 获取键值
port=0xf0;
while(port != 0xf0) // 消抖
{
delay(1);
port=0xf0;
}
delay(1);
if(j==15) // OK键
{
LCD_Clear();
return k;
}
if(j==14) // 设置密码
{
count1=0; j=0;
for(ii=0;ii<k;ii++) in[ii]=0;
for(ii=0;ii<count1;ii++) set1[ii]=0;
setting(); return k;
}
LCD_Write_Com(0xc0+k); // 按键后显示
LCD_Write_Data(j+'0');
in[k++]=j; // 存储
while(1) // 如果大于5秒,退出
{
tt++;
delay1(1);
if(tt>=500)
{
LCD_Clear();
LCD_Write_String(3,0,"TIME OUT!");
tt=0;
k=0;
delay1(100);
LCD_Clear();
return 0;
}
port=0xf0;
if(port != 0xf0)
{
tt=0;
break;
}
}
}
}
uc compare(uc *m,uc x,uc *n,uc y)
{
if(x != y) // 如果长度不相等,一定是错的
{
LCD_Write_String(4,0,"FALSE!");
delay1(100);
LCD_Clear();
k=0;j=0;
for(ii=0;ii<x;ii++) in[ii]=0;
return 0;
}
else // 如果长度相等但是某个字符不等,也是错的
{
for(jj=0;jj<y;jj++)
{
if(m[jj] != n[jj])
{
LCD_Write_String(4,0,"FALSE!");
delay1(100);
LCD_Clear();
k=0;j=0;
for(ii=0;ii<x;ii++) in[ii]=0;
return 0;
}
}
return 1;// 所有的错误类型都判断过就剩下正确的了
}
}
void setting(void)
{
LCD_Write_String(1,0,"INPUT OLD:");
delay1(200);
k=0;
k=input();
if(compare(in,k,set,count)==1)
{
LCD_Write_String(4,0,"TRUE!");
delay1(100);
LCD_Clear();
k=0;j=0;
for(ii=0;ii<k;ii++) in[ii]=0;
}
else
return;
LCD_Write_String(1,0,"INPUT:");
delay1(500);
port=0xf0;
if(port!=0x0f)
{
while(1)
{
j=keyscan();
port=0xf0;
while(port != 0xf0) // 消抖
{
delay(1);
port=0xf0;
}
delay(1);
if(j<=9&&count1<=16) // 输入合法,存储
set1[count1++]=j;
if(j==15) // 确认密码
{
LCD_Clear();
LCD_Write_String(0,0,"INPUT AGAIN:");
delay1(200);
j=0; k=0;
while(j!=15) // 直到按下确认键退出
{
again();
while(1) // 如果大于5秒,退出
{
tt++; delay1(1);
if(tt>=500)
{
LCD_Clear();
LCD_Write_String(3,0,"TIME OUT!");
tt=0; k=0; delay1(100);
LCD_Clear(); return;
}
port=0xf0;
if(port != 0xf0)
{
tt=0; break;
}
}
}
if(compare(in,k,set1,count1)==1) //对比成功
{
LCD_Clear();
LCD_Write_String(0,0,"SUCCESS!");
delay1(200);
for(ii=0;ii<count1;ii++) set[ii]=set1[ii];
count=count1;
}
else
{
LCD_Clear();
LCD_Write_String(0,0,"UNSUCCESS!");
delay1(200);
for(ii=0;ii<count1;ii++) set1[ii]=0;
}
delay1(100); LCD_Clear();
k=0;j=0;
for(ii=0;ii<k;ii++) in[ii]=0;
return;
}
if(j>=10&&j<=13) // 输入非法,重新输入
{
LCD_Clear(); LCD_Write_String(0,0,"ERROR!");
delay1(100); LCD_Clear();
for(ii=0;ii<count1;ii++) set1[ii]=0;
return;
}
LCD_Write_Com(0xc0+count1); // 按键后显示
LCD_Write_Data(j+'0');
while(1) // 如果大于5秒,退出
{
tt++;
delay1(1);
if(tt>=500)
{
LCD_Clear(); LCD_Write_String(3,0,"TIME OUT!");
tt=0; k=0; count1=0; for(ii=0;ii<count1;ii++) set1[ii]=0;
delay1(100); LCD_Clear();
return;
}
port=0xf0;
if(port != 0xf0)
{
tt=0;
break;
}
}
}
}
}
void again(void)
{
LCD_Write_String(0,0,"INPUT AGAIN:");
delay1(200);
j=keyscan();
port=0xf0;
while(port != 0xf0) // 消抖
{
delay(1);
port=0xf0;
}
delay(1);
if(j==15) // 按下OK键跳出
{
LCD_Clear();
return;
}
in[k++]=j;// 输入到in数组内
LCD_Write_Com(0xc0+k); // 按键后显示
LCD_Write_Data(j+'0');
}
void main()
{
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏 P2=0;
LCD_Write_String(0,0,"INPUT:");
while(1)
{
port=0xf0;
if(port!=0xf0)
{
k=0;
k=input();
if(k==0)
continue;
if(compare(in,k,set,count)==1)
{
LCD_Write_String(4,0,"TRUE!");
delay1(100);
LCD_Clear();
k=0;j=0;
for(ii=0;ii<k;ii++) in[ii]=0;
}
}
}
}
以上程序还存在一定的漏洞,还请各位大佬批评指正
- 接线:
- LCD1602数据线接P0
- 其他参照1602.h连接
- 矩阵键盘接P1