|
程序功能: 1、開鎖: 下載程序后,直接按六次S6(即代表數(shù)字0),8位LED亮,鎖被打開,輸入密碼時,
六位數(shù)碼管依次顯示小橫杠。
2、更改密碼:
只有當(dāng)開鎖(LED亮)后,該功能方可使用。
首先按下更改密碼鍵S16,然后設(shè)置相應(yīng)密碼,此時六位數(shù)碼管會顯示設(shè)置密碼對應(yīng)
的數(shù)字。最后設(shè)置完六位后,按下S17確認(rèn)密碼更改,此后新密碼即生效。
3、重試密碼:
當(dāng)輸入密碼時,密碼輸錯后按下鍵S18,可重新輸入六位密碼。
當(dāng)設(shè)置密碼時,設(shè)置中途想更改密碼,也可按下此鍵重新設(shè)置。
4、關(guān)閉密碼鎖:
按下S19即可將打開的密碼鎖關(guān)閉。
推薦初級演示步驟:輸入原始密碼000000按6次S6密碼正確后LED全部亮表示鎖已打開---按下更
改密碼按鍵S16---按S6到S15設(shè)置密碼---按S17
確認(rèn)密碼更改---按S19關(guān)閉密碼鎖---輸入新的密碼打開密碼鎖
功能鍵
S6---S15 數(shù)字鍵0-9
S16---更改密碼 S17---更改密碼完畢后確認(rèn)
S18---重試密碼、重新設(shè)定 S19---關(guān)閉密碼鎖
初始密碼:000000 密碼位數(shù):6位
注意:掉電后,所設(shè)密碼會丟失,重新上點時,密碼恢復(fù)為原始的000000
與P1相連的8位發(fā)光LED點亮代表鎖被打開;熄滅代表鎖被鎖上
代碼借鑒了例程,例程沒什么注釋,我基本上很多關(guān)鍵地方都給出了注釋,我覺得已經(jīng)很走心了,代碼這種東西要多看多練,稍微幾天不打就沒啥感覺了,Keil代碼下載:
密碼鎖.rar
(40.82 KB, 下載次數(shù): 41)
2022-1-28 18:25 上傳
點擊文件名下載附件
單片機(jī)源程序如下:
- #include <REGX52.H>
- /******數(shù)據(jù)變量定義*******/
- typedef unsigned char uchar;
- typedef unsigned int uint;
- /******數(shù)據(jù)變量定義*******/
- /******硬件接口定義*******/
- sbit dula = P2^6;
- sbit wela = P2^7;
- sbit beep = P2^3;
- /******硬件接口定義*******/
- /******使用到的變量定義*******/
- uchar old1,old2,old3,old4,old5,old6;//舊密碼,000000
- uchar new1,new2,new3,new4,new5,new6;//單片機(jī)所接受到的新密碼
- uchar wei,temp,keyvalue;//wei的增加可以讓我們?nèi)タ刂茖?yīng)的數(shù)碼管,temp讀取P3口的狀態(tài),keyvalue為矩陣鍵盤的鍵值
- uchar a=16;b=16;c=16;d=16;e=16;f=16;//作用于數(shù)碼管顯示函數(shù)中的變量,剛開始為不亮
- uchar code table[]=
- {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
- 0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};//共陰數(shù)碼管,0x00:關(guān)閉數(shù)碼管 0x40:數(shù)碼管顯示'-'這個字樣
- uchar code we[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//數(shù)碼管對應(yīng)的位碼
- bit finish,ok,close,allow,change,reinput;
- // change表示s16按鍵為修改密碼鍵
- // finish表示密碼全部輸完的標(biāo)志
- // ok表示s17確認(rèn)鍵按下,密碼鎖的密碼已經(jīng)更改完畢
- // close表示密碼鎖關(guān)閉,燈也會跟著數(shù)碼管關(guān)閉,由s19按鍵負(fù)責(zé)
- // allow表示只有密碼鎖密碼正確的情況下,才能進(jìn)行修改密碼的操作
- // reinput表示密碼重新輸入,主要用在密碼輸錯或者中途改密碼時覺得輸錯密碼的情況下
- /******使用到的變量定義*******/
- /******延時函數(shù)*******/
- void delay(unsigned char i)
- {
- uchar j,k;
- for(j=i;j>0;j--)
- for(k=125;k>0;k--);
- }
- /******延時函數(shù)*******/
- /******看起來方便的函數(shù)*******/
- /*我看了很多關(guān)于74HC573級聯(lián)驅(qū)動數(shù)碼管的代碼
- 代碼看起來挺長的,我感覺我這種寫法會方便一點
- 不用寫這么多*/
- void convenience(uchar duan,uchar wei)
- {
- dula = 0;//不懂的可以去看74HC573的芯片手冊或者這個芯片驅(qū)動數(shù)碼管的視頻看一下
- P0 = table[duan];//傳遞段碼
- dula = 1;
- dula = 0;
-
- wela = 0;
- P0 = we[wei];//傳遞位碼
- wela = 1;
- wela = 0;
- delay(5);
- }
- /******看起來方便的函數(shù)*******/
- /******數(shù)碼管顯示函數(shù)*******/
- //此處abcdef為形參與上面的abcdef不同,上面的abcdef為實參,用來讓六位數(shù)碼管顯示想要的符號/數(shù)字
- void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)
- {
- convenience(a,0);
- convenience(b,1);
- convenience(c,2);
- convenience(d,3);
- convenience(e,4);
- convenience(f,5);
- }
- /******數(shù)碼管顯示函數(shù)*******/
- /******按鍵松手檢測函數(shù)******/
- //仿真的我不清楚但是實物的話,松手檢測是必須的
- //感覺矩陣按鍵的寫法不能跟單個按鍵一樣————可以不加松手檢測
- //我就曾經(jīng)因為沒加矩陣按鍵松手檢測導(dǎo)致效果有問題
- //所以我覺得應(yīng)該要加
- void keyRelease()
- {
- while(temp!=0xf0)
- {
- temp = P3;
- temp = temp & 0xf0;
- beep = 0;//按一下蜂鳴器就響
- }
- beep = 1;//蜂鳴器關(guān)掉
- }
- /******按鍵松手檢測函數(shù)******/
- /******按鍵掃描函數(shù)*******/
- void keyscan()
- {
- P3 = 0xfe;temp = P3;temp = temp & 0xf0;//檢測第一行按鍵是否有被按下的
- if(temp!=0xf0)//與獨立按鍵寫法類似
- {
- delay(10);//延時
- if(temp!=0xf0)
- {
- temp = P3;//讀取P3狀態(tài)看看是哪個按鍵被按下
- switch(temp)
- {//wei++是干什么用的呢,我會在下面的函數(shù)中告訴你
- case 0xee:keyvalue=0;wei++;break;//看不懂鍵值的,先去看看矩陣按鍵的知識
- case 0xde:keyvalue=1;wei++;break;
- case 0xbe:keyvalue=2;wei++;break;
- case 0x7e:keyvalue=3;wei++;break;
- default:break;
- }
- keyRelease();//松手檢測
- }
- }
- P3 = 0xfd;temp = P3;temp = temp & 0xf0;//檢測第二行按鍵是否有被按下的
- if(temp!=0xf0)//與獨立按鍵寫法類似
- {
- delay(10);//延時
- if(temp!=0xf0)
- {
- temp = P3;//讀取P3狀態(tài)看看是哪個按鍵被按下
- switch(temp)
- {
- case 0xed:keyvalue=4;wei++;break;//看不懂鍵值的,先去看看矩陣按鍵的知識
- case 0xdd:keyvalue=5;wei++;break;
- case 0xbd:keyvalue=6;wei++;break;
- case 0x7d:keyvalue=7;wei++;break;
- default:break;
- }
- keyRelease();//松手檢測
- }
- }
- P3 = 0xfb;temp = P3;temp = temp & 0xf0;//檢測第三行按鍵是否有被按下的
- if(temp!=0xf0)//與獨立按鍵寫法類似
- {
- delay(10);//延時
- if(temp!=0xf0)
- {
- temp = P3;//讀取P3狀態(tài)看看是哪個按鍵被按下
- switch(temp)
- {
- case 0xeb:keyvalue=8;wei++;break;//看不懂鍵值的,先去看看矩陣按鍵的知識
- case 0xdb:keyvalue=9;wei++;break;
- case 0xbb:change=1;wei=0;break;//s16按鍵,修改密碼
- case 0x7b:
- if(allow)//只有密碼正確,allow才會為1
- {
- ok = 1;//確認(rèn)密碼修改完畢
- }
- break;//s17按鍵 密碼修改完畢確認(rèn)鍵
- default:break;
- }
- keyRelease();//松手檢測
- }
- }
- P3 = 0xf7;temp = P3;temp = temp & 0xf0;//檢測第四行按鍵是否有被按下的
- if(temp!=0xf0)//與獨立按鍵寫法類似
- {
- delay(10);//延時
- if(temp!=0xf0)
- {
- temp = P3;//讀取P3狀態(tài)看看是哪個按鍵被按下
- switch(temp)
- {
- case 0xe7:reinput=1;break;//s18 重新修改或輸入密碼
- case 0xd7:close=1;break;//s19 關(guān)閉密碼鎖和燈
- default:break;
- }
- keyRelease();//松手檢測
- }
- }
- }
- /******按鍵掃描函數(shù)*******/
- /******輸入密碼函數(shù)*******/
- void InputPassword()
- {
- if(!finish)//finish為1表示密碼全部輸入完畢,為0表示密碼沒輸完
- {
- //wei=0,就是不操控數(shù)碼管 wei=1就是操控第一個數(shù)碼管,wei=2就是操控第二個數(shù)碼管,依此類推,這就是wei的作用
- switch(wei)
- {
- case 1:new1=keyvalue;//第一個數(shù)碼管接收矩陣按鍵的密碼信息
- if(!allow)//在密碼沒輸入正確前,每按一次按鍵數(shù)碼管依次顯示'-',相當(dāng)于隱藏密碼吧
- a=17;//如果密碼錯誤,則數(shù)碼管顯示'-'字符
- else//allow為1,一般就是說可以改密碼了,這個時候每按一次按鍵,數(shù)碼管依次顯示對應(yīng)的數(shù)字
- a=keyvalue;//將鍵值賦給a,a再傳遞到數(shù)碼管顯示函數(shù)
- break;
- case 2:new2=keyvalue;//照貓畫虎更上面類似
- if(a==17)
- b=17;//如果第一個數(shù)碼管顯示'-'那么接下來的數(shù)碼管也要顯示'-'
- else
- b=keyvalue;
- break;
- case 3:new3=keyvalue;
- if(a==17)
- c=17;//如果第一個數(shù)碼管顯示'-'那么接下來的數(shù)碼管也要顯示'-'
- else
- c=keyvalue;
- break;
- case 4:new4=keyvalue;
- if(a==17)
- d=17;//如果第一個數(shù)碼管顯示'-'那么接下來的數(shù)碼管也要顯示'-'
- else
- d=keyvalue;
- break;
- case 5:new5=keyvalue;
- if(a==17)
- e=17;//如果第一個數(shù)碼管顯示'-'那么接下來的數(shù)碼管也要顯示'-'
- else
- e=keyvalue;
- break;
- case 6:new6=keyvalue;
- if(a==17)
- f=17;//如果第一個數(shù)碼管顯示'-'那么接下來的數(shù)碼管也要顯示'-'
- else
- f=keyvalue;
- finish = 1;//就此,六位數(shù)碼管密碼全部輸完
- break;
- }
- }
- }
- /******輸入密碼函數(shù)*******/
- /******驗證密碼正確函數(shù)*******/
- void CheckPassword()
- {
- if(finish)
- {
- //新舊密碼對比,正確就allow=1
- if((new1==old1)&(new2==old2)&(new3==old3)&(new4==old4)&(new5==old5)&(new6==old6))
- {
- allow = 1;//只有原始密碼正確才可以進(jìn)行下面的修改密碼的操作
- }
- }
- }
- /******驗證密碼正確函數(shù)*******/
- /******主函數(shù)******/
- void main()
- {
- while(1)
- {
- keyscan();//按鍵掃描
- InputPassword();//輸入密碼
- CheckPassword();//確認(rèn)密碼
- if(allow)
- {
- P1=0x00;//燈全亮
- if(!change)//沒有進(jìn)行修改密碼操作時,應(yīng)把finish置零
- finish = 0;
- }
- if(change)//進(jìn)行修改密碼操作時
- {
- if(allow)//原始密碼正確才能進(jìn)行操作
- {
- while(!finish)//只有密碼全部輸完才能退出循環(huán)
- {
- keyscan();//因為卡在這里的while循環(huán),不能再返回到上面的掃描語句,故要加上去
- InputPassword();//與上同理
- if(reinput|close)//如果重新修改密碼或者關(guān)閉密碼鎖
- {
- finish = 1;//退出循環(huán)
- break;
- }
- display(a,b,c,d,e,f);//顯示修改密碼的數(shù)字
- }
- }
- }
- if(ok)//密碼修改完畢
- {
- ok = 0;//不用多說
- wei = 0;//從頭開始輸密碼啦
- change = 0;//不用再改啦
- old1=new1;old2=new2;old3=new3; //此時,舊的密碼將被代替
- old4=new4;old5=new5;old6=new6;
- a=b=c=e=f=d=16;//數(shù)碼管不亮,你可以理解為視覺效果更好看一點把
- }
- if(reinput)//重新輸入密碼
- {
- reinput = 0;//這個肯定要等于0吧,不然就一直逃不出這個if了
- wei = 0;//這個肯定也要0吧,不然一直wei++就超過了數(shù)碼管的位數(shù)啦
- finish = 0;//你重新輸入密碼,是不是密碼沒輸完,那么這個肯定也要0吧
- new1=new2=new3=new4=new5=new6=0;//把我們之前輸錯的密碼全清零了
- a=b=c=e=f=d=16;//你重新輸入密碼,數(shù)碼管不亮
- }
- if(close)//關(guān)閉密碼鎖
- {
- close = 0;//關(guān)閉數(shù)碼管,萬物皆0
- allow = 0;
- wei = 0;
- finish = 0;
- change = 0;
- P1 = 0xff;//燈要關(guān)啦
- new1=new2=new3=new4=new5=new6=0;//把我們之前輸錯的密碼全清零了
- a=b=c=e=f=d=16;//你重新輸入密碼,數(shù)碼管不亮
- }
- display(a,b,c,d,e,f);//不屬于任何一個if,實時顯示
- }
- }
- /******主函數(shù)******/
復(fù)制代碼 原本想發(fā)一個演示的視頻但是容量有點大,就不發(fā)了
|
評分
-
查看全部評分
|