基于51单片机的简易6位密码锁(数码管 led 矩阵)
生活随笔
收集整理的這篇文章主要介紹了
基于51单片机的简易6位密码锁(数码管 led 矩阵)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? 本文章是基于51單片機的簡易密碼鎖,無掉電保護,所以沒有用到I^C總線協議,僅用到數碼管顯示,矩陣鍵盤掃描,led顯示。?
?本例程主要實現功能為:定義一個六位數的初始密碼,用矩陣輸入,輸入正確后led被點亮,錯誤不點亮;摁下任意一個按鍵蜂鳴器發出聲音,松下按鍵蜂鳴器關閉;按下更改按鍵可以改密碼,改密碼時數碼管實時顯示。按下重試鍵可以重新輸入密碼,按下關閉鍵所有數據清零。
? 使用步驟,打開電源,輸入6位數初始密碼,輸入正確鎖打開,led亮起;輸入正確后,按下更改鍵后,可以更改密碼,改密碼時數碼管會顯示所要更改的密碼,更改完成過后按下ok鍵,新密碼被記住,按下close鍵,重新輸入新密碼,輸入正確后會開鎖并且可以重新更改密碼。
(參考自清翔51單片機)
?
?
下面來看一下程序,在程序里有相應的注釋
#include<reg52.h> //定義頭文件 #define uchar unsigned char //定義兩個數據類型 #define uint unsigned int uchar old1=0,old2=1,old3=2,old4=3,old5=4,old6=5; //原始密碼,可以任意設置0~9 uchar new1,new2,new3,new4,new5,new6; //定義new,是每次按鍵按下的數值 uchar a=16,b=16,c=16,d=16,e=16,f=16; //送入數碼管顯示的變量 uchar wei,key,temp; //定義三個變量,在后面引用bit allow,genggai,ok,wanbi,retry,close; //定義六個非零即一的狀態位sbit dula=P2^6; //定義段選端口 sbit wela=P2^7; //定義位選端口 sbit beep=P2^3; //定義蜂鳴器端口unsigned char code table[]= //聲明段選數據 {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f, 0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};void delay(unsigned char i) //定義延時函數,以便后面直接引用 {uchar j,k;for(j=i;j>0;j--)for(k=125;k>0;k--); }void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f) //數碼管顯示函數,對數碼管進行賦值 {dula=0;P0=table[a];dula=1;dula=0;wela=0;P0=0xfe;wela=1;wela=0;delay(5);P0=table[b];dula=1;dula=0;P0=0xfd;wela=1;wela=0;delay(5);P0=table[c];dula=1;dula=0;P0=0xfb;wela=1;wela=0;delay(5);P0=table[d];dula=1;dula=0;P0=0xf7;wela=1;wela=0;delay(5);P0=table[e];dula=1;dula=0;P0=0xef;wela=1;wela=0;delay(5);P0=table[f];dula=1;dula=0;P0=0xdf;wela=1;wela=0;delay(5); }void keyscan() //矩陣鍵盤掃描函數 {{ P3=0xfe; //對第一行賦0,即低電平temp=P3; //定義P3口即矩陣口為temptemp=temp&0xf0; //將temp和0xf0進行“與”運算后再次賦予tempif(temp!=0xf0) /*如果temp不等于0xf0時,說明第一行有按鍵被按下,下面的檢測第一行哪一個被按下的檢測函數*/{ delay(10); //按鍵消抖if(temp!=0xf0) //再次檢測,確保第一行確實有被摁下的按鍵{ temp=P3; //將P3口的狀態賦值給tempswitch(temp) //把temp和下面case后的數值進行比較,如果相同執行相應操作{case 0xee: //如果temp=0xee,那么key=0; //那木key=0,wei++; //wei加一break; //退出,再次掃描case 0xde:key=1;wei++;break;case 0xbe:key=2; //同上wei++;break;case 0x7e:key=3;wei++;break;}while(temp!=0xf0) //松手檢測,只有當temp不等于0xf0時進入,持續掃描{temp=P3;temp=temp&0xf0;beep=0; //在不松手時蜂鳴器響起}beep=1; //松手后蜂鳴器關閉}}P3=0xfd; //對矩陣掃描第二行,方法同第一行temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);if(temp!=0xf0){temp=P3;switch(temp){case 0xed:key=4;wei++;break;case 0xdd:key=5;wei++;break;case 0xbd:key=6;wei++;break;case 0x7d:key=7;wei++;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;beep=0;}beep=1;}}P3=0xfb; //對矩陣掃描第三行,方法同第一行temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);if(temp!=0xf0){temp=P3;switch(temp){case 0xeb:key=8;wei++;break;case 0xdb:key=9;wei++;break;到現在為止0~9十個鍵已經掃描完成,接下來配置四個功能按鍵 case 0xbb: //如果第三行第3個鍵被按下,genggai=1; //genggai=1wei=0; //將wei歸零break;case 0x7b: //如果第三行第四個鍵被按下if(allow) //并且allow等于1時ok=1; //將ok=1break;}while(temp!=0xf0) //松手檢測{temp=P3;temp=temp&0xf0; beep=0;}beep=1;}}P3=0xf7; //對第四行進行掃描temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);if(temp!=0xf0){temp=P3;switch(temp){case 0xe7: //如果第四行第一個按鍵被按下retry=1; //那木retry=1break;case 0xd7: //如果第四行第二個按鍵被按下,close=1; //那么close=1break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;beep=0;}beep=1;}} } }void shumima() //對按鍵采集來的數據進行分配 { //這個子函數分析密碼是否輸入完成,并且讓數碼管逐漸亮起來if(!wanbi) //如果wanbi不等于一,進入這個if循環{switch(wei) //將wei和下面的數值比較,完成相應程序{case 1:new1=key; //如果等于一,將key賦值new1,即剛剛按下的值,if(!allow) a=17; //如果密碼沒有輸入完成且正確,那么將a賦值17else a=key; break; //如果沒有完成上面的操作,那木讓a=key,這一步是改密碼的操作case 2:new2=key; //同上if(a==17) b=17;else b=key; break;case 3:new3=key; if(a==17) c=17;else c=key; break;case 4:new4=key;if(a==17) d=17;else d=key; break;case 5:new5=key; if(a==17) e=17;else e=key; break;case 6:new6=key; if(a==17) f=17;else f=key;wanbi=1; break; //完成后wanbi=1,所以可以跳出這個while循環}} }void yanzheng() //驗證密碼是否正確 {if(wanbi) //只有當六位密碼均輸入完畢后方進行驗證{if((new1==old1)&(new2==old2)&(new3==old3)&(new4==old4)&(new5==old5)&(new6==old6))allow=1; //當上面全部成立,證明輸入的密碼正確,會得到allowe=1} }void main() //主函數 {while(1) //大循環{keyscan(); //不停的掃描矩陣鍵盤shumima(); //數碼管顯示子函數yanzheng(); //驗證密碼是否輸入正確if(allow) //驗證完后,若allow為1,則開鎖{P1=0x00; //開鎖后的指令,讓所有led都亮起來if(!genggai) //如果沒有按下更改鍵,wanbi會被置0wanbi=0; }if(genggai) //當更改密碼鍵被按下,genggai會被置一{if(allow) //判斷密碼鎖是否打開,如果打開,才有更改密碼的權限{while(!wanbi) //當新的六位密碼沒有設定完,則一直在這里循環{keyscan(); //持續掃描shumima();if(retry|close) //當檢測到retry或close任意一個被按下,那木會讓wanbi=1,即跳出數碼管顯示子函數{ wanbi=1;break;}display(a,b,c,d,e,f); //更改密碼時數碼管顯示要更改的密碼}}}if(ok) ///更改完成后,按下ok,結束并保存{ //其他時間按下此鍵無效ok=0; wei=0;genggai=0;old1=new1;old2=new2;old3=new3; //此時,舊的密碼將被代替old4=new4;old5=new5;old6=new6;a=16;b=16;c=16;d=16;e=16;f=16;}if(retry) //當retry被按下,相當于重新輸入密碼,無論是在改密碼還是輸密碼時{retry=0; wei=0;wanbi=0;a=16;b=16;c=16;d=16;e=16;f=16;new1=0;new2=0;new3=0;new4=0;new5=0;new6=0; }if(close) //當close被摁下時,所有密碼清零{close=0;genggai=0;//所有變量均被清零。wei=0; wanbi=0;allow=0;P1=0xff;a=16;b=16;c=16;d=16;e=16;f=16;new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;}display(a,b,c,d,e,f); //實時顯示} }總結
以上是生活随笔為你收集整理的基于51单片机的简易6位密码锁(数码管 led 矩阵)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ADAMS基础到测量 后处理 参数优化设
- 下一篇: eeglab教程系列(3)-绘制脑电头皮