這款基于51單片機的電子密碼鎖系統(tǒng),單片機用STC89C52RC單片機,電路簡單,制作過程中不需要進行調(diào)試,支持密碼掉電保存功能!密碼儲存于單片機內(nèi)部自帶的的EEPROM中,不需要外置AT24C01保存密碼,是學(xué)習(xí)電子密碼鎖比較好的教學(xué)試驗系統(tǒng),主要功能如下:
1、1602液晶菜單顯示。
2、6位密碼,密碼可重置,重置密碼時,先輸入原始密密,正確后輸入新密碼,再交輸入新密碼,兩次輸入的密碼一致辭時,密碼修改成功。開鎖時,密碼通過鍵盤輸入,若密碼正確,則將鎖打開,諾密碼不正確時,無法開鎖,密碼輸入錯誤三次時,蜂鳴器報 警并且鎖定鍵盤,10分鐘。
3、支持掉電保存密碼功能。單片機中的密碼是儲存于單片內(nèi)部的EEPROM中,在密碼鎖系統(tǒng)斷電時,儲存在密碼鎖系統(tǒng)中的密碼不會丟失。
4、密碼鎖系統(tǒng)采用5V繼電器模擬開鎖過程。
5、輸入的正確時,繼電器吸合2-3秒,開鎖指示燈亮2-3秒,模擬開鎖。
6、密碼錯誤報警且有錯誤提示(顯示Error)。
7、密碼正確開鎖指示。
8、4X4矩陣鍵盤輸入。
9、隨時可修改密碼存儲,支持掉電保存密碼功能,功能更為實用。
10、密碼可以由用戶自己修改設(shè)定(只支持6位密碼),鎖打開后才能 修改密碼。修改密碼之前必須再次輸入密碼,在輸入新密碼時候需要二次確認,以防止誤操作。
源程序如下:
- #include<reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- void key_scan();
- uchar count0,count1,count3,num,n=0,temp,a,j,count4;
- uchar mima[8]; //初始密碼存儲區(qū)
- uchar tab_key[50]; //輸入密碼存儲區(qū)
- uchar code table[]={
- 0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,
- 0x39,0x5e,0x79,0x71};
- bit enterflag; //確認鍵按下與否的標(biāo)志
- bit mimaflag; //密碼正確與否的標(biāo)志
- bit xiugaiflag; //修改密碼標(biāo)志
- bit enter1flag; //修改密碼確認鍵標(biāo)志
- sbit red=P3^7;
- sbit bell=P3^6;
- sbit rs=P2^0;
- sbit rw=P2^1;
- sbit lcden=P2^2;
- sbit scl=P3^4;
- sbit sda=P3^5;
- uchar code table1[]="input the passco";
- uchar code table2[]="de: --------";
- uchar code table3[]="*";
- uchar code table4[]="right (^_^) ";
- uchar code table5[]="first error!!!!";
- uchar code table6[]="second error!!!!";
- uchar code table7[]="third error see ";
- uchar code table8[]="u tomorrow (^_^)";
- uchar code table9[]="define the passc";
- uchar code table10[]="ode: --------";
- uchar code table11[]="code is new";
- //******************************鍵盤消抖函數(shù)*******************************
- void delay1()
- { ;; }
- void delay2(uchar x)
- {
- uchar a,b;
- for(a=x;a>0;a--)
- for(b=100;b>0;b--);
- }
-
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- //****************************e^2room的初始化*******************************
- void start() //開始信號
- {
- sda=1;
- delay1();
- scl=1;
- delay1();
- sda=0;
- delay1();
- }
- void stop() //停止
- {
- sda=0;
- delay1();
- scl=1;
- delay1();
- sda=1;
- delay1();
- }
- //****************************應(yīng)答信號*************************************
- void respond()
- {
- uchar i;
- scl=1;
- delay1();
- while((sda==1)&&(i<250))i++;
- scl=0;
- delay1();
- }
- //*****************************寫字節(jié)操作函數(shù)**********************************
- void write_byte(uchar date)
- {
- uchar i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1; //保持最高位,左移到進位CY
- scl=0;
- delay1();
- sda=CY;
- delay1();
- scl=1;
- delay1();
- }
- scl=0;
- delay1();
- sda=1;//總線釋放
- delay1();
- }
- //*******************************讀字節(jié)操作函數(shù)*****************************
- uchar read_byte()
- {
- uchar i,k;
- scl=0;
- delay1();
- sda=1;
- delay1();
- for(i=0;i<8;i++)
- {
- scl=1;
- delay1();
- k=(k<<1)|sda; //或運算,放到最低位
- scl=0;
- delay1();
- }
- return k;
- }
- //**********************************寫地址函數(shù)******************************
- void write_add(uchar address,uchar date)
- {
- start();
- write_byte(0xa0);
- respond();
- write_byte(address);
- respond();
- write_byte(date);
- respond();
- stop();
- }
- //*******************************讀地址函數(shù)*************************************
- uchar read_add(uchar address)
- {
- uchar date;
- start();
- write_byte(0xa0);
- respond();
- write_byte(address);
- respond();
- start();
- write_byte(0xa1);
- respond();
- date=read_byte();
- stop();
- return date;
- }
- //****************************LCD1602的初始化*******************************
- void write_com(uchar com)
- {
- rs=0;
- lcden=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_date(uchar date)
- {
- rs=1;
- lcden=0;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- //***************************************密碼比較函數(shù)********************************
- bit mimacmp()
- {
- bit flag;
- uchar i;
- for(i=0;i<8;i++)
- {
- if(mima[i]==tab_key[i])
- flag=1;
- else
- {
- flag=0;
- i=8;
- }
- }
- return(flag); //返回flag
- }
- ////**********************************LCD顯示函數(shù)開始**************************************
- void lcd_display()
- {
- uchar i=0;
- write_com(0x80+0x40+8);
- for(i=0;i<n;i++)
- {
- write_date(table3[0]);
- }
- }
- //****************************************鍵盤功能分配函數(shù)群開始****************************
- //** 0 ** 1 **2 ** 3**
- //** 4** 5** 6 **7 **
- //**8** 9** 確認(A) **無效(B)
- //**取消(C)**修改密碼鍵(D)**確認修改鍵(E)**無效(F)
- void key_manage1()
- {
- tab_key[n]=0;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=0;
- count4++;
- }
- }
- void key_manage2()
- {
- tab_key[n]=1;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=1;
- count4++;
- }
- }
- void key_manage3()
- {
- tab_key[n]=2;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=2;
- count4++;
- }
- }
- void key_manage4()
- {
- tab_key[n]=3;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=3;
- count4++;
- }
- }
- void key_manage5()
- {
- tab_key[n]=4;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=4;
- count4++;
- }
- }
- void key_manage6()
- {
- tab_key[n]=5;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=5;
- count4++;
- }
- }
- void key_manage7()
- {
- tab_key[n]=6;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=6;
- count4++;
- }
- }
- void key_manage8()
- {
- tab_key[n]=7;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=7;
- count4++;
- }
- }
- void key_manage9()
- {
- tab_key[n]=8;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=8;
- count4++;
- }
- }
- void key_manage10()
- {
- tab_key[n]=9;
- n++;
- if(xiugaiflag==1)
- {
- mima[count4]=9;
- count4++;
- }
- }
- //**********************************確認鍵**************************************************************
- void key_manage11()
- {
- enterflag=1; //確認鍵按下
- if(n==8) //只有輸入8個密碼后按確認才做比較
- mimaflag=mimacmp();
- else
- mimaflag=0;
- if(enterflag==1)
- {
- enterflag=0;
- n=0;
- //用FFFFFFFF清除已經(jīng)輸入的密碼
- for(count3=0;count3<8;count3++)
- {
- delay(5);
- tab_key[count3]=0x0f;
- }
-
- TR1=1; //打開計數(shù)器1
- count1=0; //定時器1由50MS累計到1S所用的計數(shù)器
- if(mimaflag==1)
- {
- a=0;
-
- write_com(0x01);
- write_com(0x80);
- for(count3=0;count3<16;count3++)
- {
- write_date(table4[count3]); //密碼正確,顯示RIGHT,綠燈亮
- delay(5);
- }
- }
-
- else
- {
- n=0;
- red=0;
- bell=0;
- a++;
- if(a==1)
- {
- for(count3=0;count3<8;count3++) //ffffffff清除密碼
- {
- delay(5);
- tab_key[count3]=0x0f;
- }
- write_com(0x01);
- write_com(0x80);
- for(count3=0;count3<16;count3++)
- {
- write_date(table5[count3]); //密碼錯誤,顯示 first error,紅燈亮
- delay(5);
- }
- TR1=1;
- }
- if(a==2)
- {
- for(count3=0;count3<8;count3++) //ffffffff清除密碼
- {
- delay(5);
- tab_key[count3]=0x0f;
- }
- write_com(0x01);
- write_com(0x80);
- for(count3=0;count3<16;count3++)
- {
- write_date(table6[count3]); //密碼錯誤,顯示SECOND ERROR,紅燈亮
- delay(5);
- }
- TR1=1;
- }
-
- if(a==3)
- {
- for(count3=0;count3<8;count3++) //ffffffff清除密碼
- {
- delay(5);
- tab_key[count3]=0x0f;
- }
- write_com(0x01);
- write_com(0x80);
- for(count3=0;count3<16;count3++)
- {
- write_date(table7[count3]); //密碼錯誤,顯示third error see,紅燈亮
- delay(5);
- }
- write_com(0x80+0x40);
- for(count3=0;count3<16;count3++)
- {
- write_date(table8[count3]);//密碼錯誤,顯示 U TOMORROW ,紅燈亮
- delay(5);
- }
- TR1=0;
-
- }
-
- }
- }
- }
- void key_manage12()
- {
- tab_key[n]=11;
- n++; //密碼計數(shù)清零
- }
- //****************************************************取消鍵********************************************
- void key_manage13()
- {
- n=0; //密碼計數(shù)清零
- write_com(0x80); //指針?biāo)肝恢?br>
- for(count3=0;count3<16;count3++)
- {
- write_date(table1[count3]); //第一行顯示INPUT THE PASSPORD:
- delay(5);
- }
- write_com(0x80+0x40);
- for(count3=0;count3<16;count3++)
- {
- write_date(table2[count3]); //開機顯示--------
- delay(5);
- tab_key[count3]=0x0f; //用FFFFFFFF清楚已經(jīng)輸入的密碼
- }
- }
- //*******************************************修改密碼鍵**********************************
- void key_manage14()
- {
- uchar aa=0;
- n=0;
- xiugaiflag=1;
- write_com(0x01);
- write_com(0x80);
- for(count3=0;count3<16;count3++)
- {
- write_date(table9[count3]); //顯示define the password
- delay(5);
- tab_key[count3]=0x0f; //用FFFFFFFF清楚已經(jīng)輸入的密碼
- }
- write_com(0x80+0x40);
- for(count3=0;count3<16;count3++)
- {
- write_date(table10[count3]); //顯示--------
- delay(5);
- }
- TR0=1;
- }
- //******************************************修改密碼鍵的確認鍵********************************
- void key_manage15()
- {
- n=0;
- enter1flag=1;
- if(enter1flag==1)
- {
- enter1flag=0;
- count4=0;
- for(count3=0;count3<16;count3++)
- {
- tab_key[count3]=0x0f; //用FFFFFFFF清楚已經(jīng)輸入的密碼
- }
- write_com(0x01);
- write_com(0x80);
- for(count3=0;count3<16;count3++)
- {
- write_date(table11[count3]);
- delay(100);
- }
- TR1=1;
- count1=0;
- }
- }
- void key_manage16()
- {
- tab_key[n]=15;
- n++;
- }
- //****************************************定時器1的50MS,共延時1秒*****************************
- void time_1() interrupt 3
- {
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- if(count1<20)
- {
- count1++;
- }
- else //計時到1S
- {
- TR1=0;
- count1=0;
- mimaflag=0;
- red=1;
- bell=1;
- //顯示FFFFFFFF
- write_com(0x01);
- write_com(0x80);
- for(count3=0;count3<16;count3++)
- {
- write_date(table1[count3]); //顯示INPUT THE PASSCODE
- delay(5);
- }
- write_com(0x80+0x40);
- for(count3=0;count3<16;count3++)
- {
- write_date(table2[count3]); //開機顯示FFFFFFFF
- delay(5);
- }
- }
- }
- //***********************************************定時0**********************************************
- void time_0() interrupt 1
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- if(count4<8)
- {
- key_scan();
- }
- else
- {
- TR0=0;
- count4=0;
- }
- }
- //初始化函數(shù)
- void init()
- {
- uchar i;
- lcden=0;
- write_com(0x38); //打開顯示模式設(shè)置
- write_com(0x0c); //打開顯示,光標(biāo)等等設(shè)置未零
- write_com(0x06); //當(dāng)讀或?qū)懸粋€字符后地址指針加一,且光標(biāo)加一,當(dāng)寫一個字符后整頻顯示左移,
- write_com(0x01); //清零指令
- write_com(0x80); //指針?biāo)肝恢?br>
- //定時器初始化
- TMOD=0x11; //T0,T1工作方式1
- TH0=(65536-2000)/256;
- TL0=(65536-2000)%256; //T0初始化2MS
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256; //T1初始化50MS
- TR1=0;
- ET1=1;
- EA=1;
- TR0=0;
- ET0=1;
- count0=0; //初始沒有密碼輸入,故為零
- enterflag=0; //沒有確認鍵按下
- mimaflag=0; //密碼正確與否鍵先置零
-
- red=1; //紅燈不亮
- //************密碼存入EPROM中**********************************
- sda=1;
- delay(5);
- scl=1;
- delay(5);
- for(i=0;i<8;i++)
- {
- write_add(i,8);
- delay2(100);
- }
- for(i=0;i<8;i++)
- {
- mima[i]=read_add(i);
- delay(5);
- }
- }
- void main()
- { rw=0;
- init();
- write_com(0x80); //指針?biāo)肝恢?br>
- for(count3=0;count3<16;count3++)
- {
- write_date(table1[count3]); //第一行顯示INPUT THE PASSPORD:
- delay(5);
- }
- write_com(0x80+0x40);
- for(count3=0;count3<16;count3++)
- {
- write_date(table2[count3]); //開機顯示FFFFFFFF
- delay(5);
- }
- while(1)
- {
- key_scan(); //調(diào)用鍵盤掃描函數(shù)
- lcd_display();
- }
-
- }
- //**************************************************鍵盤掃描函數(shù)開始********************************
- void key_scan()
- {
- //**********掃描第一行*********
- P1=0xfe;
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(100);
- if(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xee:
- key_manage1();
- break;
- case 0xde:
- key_manage2();
- break;
- case 0xbe:
- key_manage3();
- break;
- case 0x7e:
- key_manage4();
- break;
- }
- while(temp!=0xf0)
- {
- temp=P1;
- temp=temp&0xf0;
- }
- }
- }
- //**************************************************掃描第二行***********************************
- P1=0xfd;
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(100);
- if(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xed:
- key_manage5();
- break;
- case 0xdd:
- key_manage6();
- break;
- case 0xbd:
- key_manage7();
- break;
- case 0x7d:
- key_manage8();
- break;
- }
- while(temp!=0xf0)
- {
- temp=P1;
- temp=temp&0xf0;
- }
- }
- }
- //*********************************************掃描第三行***********************************
- P1=0xfb;
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(100);
- if(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xeb:
- key_manage9();
- break;
- case 0xdb:
- key_manage10();
- break;
- case 0xbb:
- key_manage11();
- break;
- case 0x7b:
- key_manage12();
- break;
- }
- while(temp!=0xf0)
- {
- temp=P1;
- temp=temp&0xf0;
- }
- }
- }
- //***************************************************掃描第四行****************************************
- P1=0xf7;
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(100);
- if(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xe7:
- key_manage13();
- break;
- case 0xd7:
- key_manage14();
- break;
- case 0xb7:
- key_manage15();
- break;
- case 0x77:
- key_manage16();
- break;
- }
- while(temp!=0xf0)
- {
- temp=P1;
- temp=temp&0xf0;
- }
- }
- }
- }
復(fù)制代碼
|