#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