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