一个简易的电子密码锁,6位密码,初始密码是12345
51单片机采用IIC和AT24C02通信
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg52.h>
- #include <IIC.h>
- #include <LCD1602.h>
- #define U 6
- void delay(unsigned int i)
- {
- while(i--);
- }
- int Time30s=30;
- unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-',' '};
- unsigned char code Led1[]={0x00,0x1F,0x04,0x04,0x1F,0x04,0x0D,0x17};//无
- unsigned char code Led2[]={0x04,0x0F,0x19,0x06,0x1C,0x0F,0x09,0x0F};//名
- unsigned char code Led3[]={0x04,0x04,0x04,0x15,0x15,0x04,0x14,0x0C};//小
- unsigned char code Led4[]={0x04,0x04,0x00,0x1F,0x00,0x0A,0x0A,0x11};//六
- char code c1[]="Input Password:";
- char code c2[]="Input New Again:";
- char code c3[][16]={" Correct ",
- " (^_^) "};
- char code c4[][16]={" Error ",
- " (@_@) "};
- char code c5[][16]={"Set New Password",
- "YES or NO"};
- char code c6[]="QQ: 1031594831 ";
- char code c7[16]={" "};
- char code c8[]="Wait 30s: 30s ";
- char code c9[][16]={" Confirm exit ",
- "YES or NO"};
- char code c10[]="New Password: ";
- char code c11[]="Set Success ";
-
- char Word[U]; //初始密码
- bit ai=0; //判断按键是否按下位
- //**********定时器0初始化函数*********//
- void TIME0_INIT()
- {
- TMOD=0x01;
- TH0=0x3C;
- TL0=0xB0;
- ET0=1;
- EA=1;
- TR0=0;
- }
- /**************按键判断函数*********************/
- int keypross()
- {
- int A;
- if(P1!=0xf0)
- {
- delay(1000);
- if(P1!=0xf0)
- {
- ai=1; //按键按下
- switch(P1)
- {
- case 0xe0:
- A=1;break;
- case 0xd0:
- A=2;break;
- case 0xb0:
- A=3;break;
- default:
- ai=0;break;
- }
- P1=0x0f;
- if(P1!=0x0f)
- {
- switch (P1)
- {
- case 0x0e:
- A=A;break;
- case 0x0d:
- A=A+3;break;
- case 0x0b:
- A=A+6;break;
- case 0x07:
- A=A+9;break;
- default:
- break;
- }
- }
- while(P1!=0x0f);//判断按键是否松开
- }
- }
- P1=0xf0;
- return A;
- }
- /**************开机密码判断函数****************/
- bit OpenKey()
- {
- int i,a;
- bit b=0,c=0;
- char w1[U];
- ai=0;
- while(1)
- {
- for(i=0;i<U+1;i++)
- {
- while(!ai)
- {
- P1=0xf0;
- a=keypross();
- if(i==U)
- {
- ai=0;
- if(a==10||a==12)
- {
- break;
- }
- }
- }
- ai=0;
- switch (a)
- {
- case 10:
- b=1;break;
- case 11:
- a=0;break;
- case 12:
- c=1;break;
- default:
- break;
- }
- if(b||c) break;
- w1[i]=ASCII[a];
- DisplayOneChar(i+2,1,'*'); //密码输入时显示‘ * ’符号
-
- }
- if(b)
- {
- for(i=0;i<U;i++)
- {
- if(w1[i]!=Word[i])
- {
- return 0; //密码错误,退出
- }
- }
- return 1; //密码正确,退出
- }
- if(c)
- {
- a=0;
- b=0;
- return 0;
- }
- }
- }
- /*******************************************
- ******* 显示函数 **************
- *******************************************/
- void LcdPross(char *p,char *q)
- {
- int i;
- LCD1602_WRITERCOM(0x80);
- for(i=0;i<16;i++)
- {
- LCD1602_WRITERDAT(*p++);
- }
- LCD1602_WRITERCOM(0xC0);
- for(i=0;i<16;i++)
- {
- LCD1602_WRITERDAT(*q++);
- }
- }
- bit LcdTime30s()
- {
-
-
- if(Time30s==-1)
- {
- TR0=0;
- Time30s=30;
- return 0 ;
- }
- else
- {
- TR0=1;
- return 1;
- }
- }
- //************倒计时30s函数***************//
- bit SetPassword()
- {
- int i,j=0,a;
- char w1[U],w2[U];
- bit b=0,c=0;
- ai=0;
- for(j;j<2;j++)
- {
- if(j==0)
- {
- LcdPross(c10,c7);
- }
- else
- {
- LcdPross(c2,c7);
- }
- for(i=0;i<U+1;i++)
- {
- while(!ai)
- {
- a=keypross();
- if(i==U)
- {
- ai=0;
- if(a==10||a==12)
- break;
- }
- }
- ai=0;
- switch (a)
- {
- case 10:
- b=1;break;
- case 11:
- a=0;break;
- case 12:
- c=1;break;
- default:
- break;
- }
- if(b&&i<U)
- {
- b=0;
- return 0;
- }
- if(b&&i==U)
- {
- b=0;
- break;
- }
- if(c)
- {
- c=0;
- return 0;
- }
- if(j==0)
- {
- w1[i]='0'+a;
- DisplayOneChar(i+2,1,w1[i]);
- }
- else
- {
- w2[i]='0'+a;
- DisplayOneChar(i+2,1,w2[i]);
- }
- }
- }
- for(i=0;i<U;i++)
- {
- if(w1[i]!=w2[i])
- {
- return 0;
- }
- }
- for(i=0;i<U;i++)
- {
- Word[i]=w2[i];
- }
- return 1;
- }
-
- void LcdDisplay()
- {
- int i,a;
- while(1)
- {
- i=4;
- while(--i)
- {
- LcdPross(c1,c7);//显示输入密码
- if(OpenKey()) //判断密码是否正确
- {
- LcdPross(c3[0],c3[1]); //显示正确
- delay(50000);
- break;
- }
- else
- {
- LcdPross(c4[0],c4[1]); //显示错误
- delay(50000);
- }
- }
- if(i==0)
- {
- LcdPross(c8,c7);
- while(LcdTime30s());
- }
- else
- break;
- }
- while(1)
- {
- while(1)
- {
- LcdPross(c5[0],c5[1]); //显示改密码界面
- ai=0;
- while(!ai)
- {
- a=keypross();
- if(a!=10&&a!=12)
- {
- ai=0;
- }
- }
- if(a==12)
- {
- break;
- }
- if(a==10)
- {
- if(SetPassword())
- {
- LcdPross(c11,c7); //显示改密成功
- delay(50000);
- for(i=0;i<U;i++)
- {
- AT24C02Writer(i,Word[i]);
- delay(100);
- }
- delay(50000);
- }
- else
- {
- LcdPross(c4[0],c4[1]);
- delay(50000);
- }
- }
- }
- LcdPross(c9[0],c9[1]); //显示 是否退出界面
- ai=0;
- while(!ai)
- {
- a=keypross();
- if(a!=10&&a!=12)
- {
- ai=0;
- }
- }
- if(a==10)
- {
- break;
- }
- }
- }
- void main()
- {
- int i;
- TIME0_INIT();
- LCD1602_INIT();
- P1=0xf0;
- /*
- for(i=0;i<U;i++)
- {
- DisplayOneChar(i+2,1,AT24C02Read(i)); //开机之前显示密码
- }
- delay(50000);
- delay(50000);
- delay(50000);
- */
- LCD1602_Custom(4,0,0,Led1); //无
- LCD1602_Custom(6,0,1,Led2); //名
- LCD1602_Custom(8,0,2,Led3); //小
- LCD1602_Custom(10,0,3,Led4);//六
- LCD1602_WRITERCOM(0xC0);
- for(i=0;i<16;i++)
- {
- LCD1602_WRITERDAT(c6[i]); //QQ号
- }
- while(!ai)
- {
- keypross(); //按键按下跳转密码输入页面
- }
- ai=0;
- for(i=0;i<U;i++)
- {
- Word[i]=AT24C02Read(i); //读取密码
- }
- while(1)
- {
- LcdDisplay();
- }
- }
- void Time00() interrupt 1
- {
- static unsigned int i;
- TH0=0x3C;
- TL0=0xB0;
- i++;
- if(i==20)
- {
- i=0;
- Time30s--;
- DisplayOneChar(12, 0, ASCII[Time30s/10]);
- DisplayOneChar(13, 0, ASCII[Time30s%10]);
- }
- }
复制代码
所有资料51hei提供下载:
电子密码锁.zip
(123.8 KB, 下载次数: 53)
|