用數碼管和矩陣按鍵實現密碼鎖功能,我的理解是實現輸入數據并判斷數據是否和密碼一致,并且更改密碼。矩陣按鍵是4×4的,圖在下面。先說功能,初始密碼值4321。第一部分:當數碼管未進行閃爍的時候,按下S11是進行數據和密碼的比較,當正確時數碼管顯示1111,錯誤顯示2222。按下S12進行數據移位(口誤了,應該是數據選擇而不是數據移位,但意思大家一定要理解,因為下面的我都口誤了),這時數碼管閃爍,你按下S1到S10可以進行設定,當按四次S12的時候或者按下S13可以不閃爍了,這時按下S11才能進行數據比較(意思是只有不閃爍才能進行數據比較)。這是數據和密碼的比較。第二部分:當數碼管不進行閃爍的時候才能進行密碼的更改,按下S14顯示密碼值。按下S15時進行密碼值的選擇,也就是閃爍,按下S1到S10可以進行數碼值的改變,按四次S15或者按一次S16可以將數碼管閃爍消除,再按一次S14可以退出密碼設置,問題在于你如果按了S11到S13會改變數據數值嗎?同理在數據和密碼比較的時候你要是按了S14到S16會對密碼造成影響嗎?這是標志位的設定問題大家思考一下。自己寫一遍是最好的,會發現很多問題考慮。
我們還按照從小到大,從淺入深的方法解決這個問題。
步驟一、考慮一下你的數據如何從矩陣按鍵輸送給數碼管,這里面大家可以想一下如何解決這個問題,我用了函數封裝以及調用。(這里有一個很有意思的東西,大家好好考慮一下,超有意思)
步驟二、考慮如何實現輸入數據,數據的輸入方式是從右向左依次輸入,舉個例子就是輸入4321,顯示就是4321,,這是規則。
步驟三、實現數據輸入后,再進行輸入數據和密碼的比較,當正確的時候顯示1111,錯誤顯示2222。
這是這個程序的骨架,以后的程序都是在上面的添加。
步驟四、當按下S12的時候(也就是輸入數據11,我程序中用的都是數據),進行移位操作,數碼管會進行閃爍。這是可以更改數據,當你按四次S12或者按下S13的時候數碼管不會閃爍了,這時再按一下S11,就是數據和密碼的比較,這也是規則。當你在數碼管閃爍的時候按S11是不會進行比較的(規則)。這時程序已經開始豐滿了。
步驟五、進行改變密碼操作,這個操作和改變數據操作很相似,但由于太相似了,所以會有所沖突,這時就需要條件才能保證程序的正常運行。具體操作手法就是用數據和密碼的移位的標志位來限制數據和密碼的比較(按下S11)和更改密碼的按鍵(S14),這樣避免了在你按錯鍵又看不到現象的情況下,程序自己在兩者之間不斷運行。
總結:沒必要太過糾結于別人程序怎么寫,先看現象理解那個程序的功能,想好思路,自己寫一遍(由淺入深一步步來,不要一步成,寫程序大忌)。出了問題自己找解決辦法,沒法解決參考別人的也可以。記住一定要保證基層骨架的完美,才可進行復雜功能的添加。大家只需要找到自己需要的一部分就行了。
程序我覺得最重要的部分:矩陣函數的封裝,移位時數碼管的閃爍,如何將大于9的數不顯示在數碼管上,進行密碼改變時的標志位設定,數據和密碼的比較與密碼改變的互鎖關系,定時器開關的設定(TR0=1或0)
電路原理圖如下:
單片機源程序如下:
- #include "digdisplay.h" //矩陣按鍵輸入10(鍵表面為S11,程序中默認都是數值)為密碼確認,矩陣按鍵輸入11為移位操作按鈕,輸入12為移位后閃爍的確認鍵,按下之后便會不閃爍;
- #include "key.h" //矩陣按鍵輸入13將進行密碼的設定,輸入14為密碼的移位,輸入15為結束閃爍
- u8 digdate[4]={0,0,0,0}; //存放輸入數值
- u8 digcode[4]={1,2,3,4}; //存放密碼值
- u8 knum=0,flag0,flag1=1,knum1=0; //knum代表數據的移動位置,flag0代表移位閃爍標志位,flag1代表更改密碼操作的標志位,knum1是進行密碼移位的操作數
- u8 time; //定時器中斷時間計時,
- void keyprogress() //檢測密碼的輸入并進行判斷
- {
- u8 keynum;
- keynum=KeyDown(); //if的判斷語句里應該不要加含有return的語句,我把KeyDown()放到if()里面程序錯誤了。
- if(keynum!=0xff) //檢測按鍵是否按下,如果矩陣按鍵程序返回值不是0xff,說明是在輸入密碼值
- {
- if(keynum==13&&knum==0&&knum1==0) //13代表著是否密碼需要更改,默認不需要更改,不在閃爍的時候進行更改,程序一步步走
- {
- flag1=!flag1; //改變輸入數據和密碼的標志位變化
- }
- if(flag1)
- {
- if(keynum==11) //代表開始移位,定時器中斷開始
- {
- knum++; //代表4個數碼管的某一位改變
- if(knum==5) //代表移位四次了,
- {
- knum=0; //變為初始狀態,為確認做準備
- }
- if(knum!=0) //有按鍵按下
- {
- if(TR0!=1) //如果定時器沒開啟
- {
- TR0=1; //開啟定時器
- }
- }
- else //按鍵按了五次回到knum=0時,
- {
- if(TR0!=0) //如果定時器開啟
- {
- TR0=0; //關閉定時器
- }
- }
- }
- if(knum==0) //代表沒有進行移位時可以進行密碼輸入操作
- {
- if(keynum<=9)
- {
- digdate[3]=digdate[2];
- digdate[2]=digdate[1];
- digdate[1]=digdate[0];
- digdate[0]=keynum;
- }
- }
- else if(knum==1) //代表第零位數碼管需要改變數值
- {
- if(keynum<=9) //防止按下移位按鈕的時候顯示b
- {
- digdate[0]=keynum; //結合顯示函數寫
- }
- else if(keynum==12)
- {
- knum=0;
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- else if(knum==2)
- {
- if(keynum<=9)
- {
- digdate[1]=keynum; //結合顯示函數寫
- }
- else if(keynum==12)
- {
- knum=0;
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- else if(knum==3)
- {
- if(keynum<=9)
- {
- digdate[2]=keynum; //結合顯示函數寫
- }
- else if(keynum==12)
- {
- knum=0;
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- else if(knum==4)
- {
- if(keynum<=9)
- {
- digdate[3]=keynum; //結合顯示函數寫
- }
- else if(keynum==12)
- {
- knum=0;
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- if(keynum==10&&knum==0&&knum1==0) //當矩陣按鍵值為10,且沒有移位的時候才能判斷
- {
- if(digdate[3]==digcode[3]&&digdate[2]==digcode[2]&&digdate[1]==digcode[1]&&digdate[0]==digcode[0])
- {
- digdate[3]=1;
- digdate[2]=1;
- digdate[1]=1;
- digdate[0]=1;
- }
- else
- {
- digdate[3]=2;
- digdate[2]=2;
- digdate[1]=2;
- digdate[0]=2;
- }
- }
- }
- else //如果密碼進行更改
- {
- if(keynum==14) //密碼開始移位的按鍵
- {
- knum1++;
- if(knum1==5)
- {
- knum1=0;
- }
- if(knum1!=0)
- {
- if(TR0!=1)
- {
- TR0=1;
- }
- }
- else
- {
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- if(knum1==0)
- {
- if(keynum<=9)
- {
- digcode[3]=digcode[2];
- digcode[2]=digcode[1];
- digcode[1]=digcode[0];
- digcode[0]=keynum;
- }
- }
- else if(knum1==1)
- {
- if(keynum<=9)
- {
- digcode[0]=keynum;
- }
- else if(keynum==15)
- {
- knum1=0;
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- else if(knum1==2)
- {
- if(keynum<=9)
- {
- digcode[1]=keynum;
- }
- else if(keynum==15)
- {
- knum1=0;
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- else if(knum1==3)
- {
- if(keynum<=9)
- {
- digcode[2]=keynum;
- }
- else if(keynum==15)
- {
- knum1=0;
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- else if(knum1==4)
- {
- if(keynum<=9)
- {
- digcode[3]=keynum;
- }
- else if(keynum==15)
- {
- knum1=0;
- if(TR0!=0)
- {
- TR0=0;
- }
- }
- }
- }
- }
- }
- void display() //顯示函數的實現
- {
- if(flag1)
- {
- if(knum==0)
- {
- digdisplay(3,digdate[3]);
- digdisplay(2,digdate[2]);
- digdisplay(1,digdate[1]);
- digdisplay(0,digdate[0]);
- }
- else if(knum==1)
- {
- if(flag0)
- {
- digdisplay(3,digdate[3]);
- digdisplay(2,digdate[2]);
- digdisplay(1,digdate[1]);
- digdisplay(0,digdate[0]);
- }
- else
- {
- digdisplay(3,digdate[3]);
- digdisplay(2,digdate[2]);
- digdisplay(1,digdate[1]);
- digdisplay(0,17); //顯示空白
- }
- }
- else if(knum==2)
- {
- if(flag0)
- {
- digdisplay(3,digdate[3]);
- digdisplay(2,digdate[2]);
- digdisplay(1,digdate[1]);
- digdisplay(0,digdate[0]);
- }
- else
- {
- digdisplay(3,digdate[3]);
- digdisplay(2,digdate[2]);
- digdisplay(1,17);
- digdisplay(0,digdate[0]);
- }
- }
- else if(knum==3)
- {
- if(flag0)
- {
- digdisplay(3,digdate[3]);
- digdisplay(2,digdate[2]);
- digdisplay(1,digdate[1]);
- digdisplay(0,digdate[0]);
- }
- else
- {
- digdisplay(3,digdate[3]);
- digdisplay(2,17);
- digdisplay(1,digdate[1]);
- digdisplay(0,digdate[0]);
- }
- }
- else if(knum==4)
- {
- if(flag0)
- {
- digdisplay(3,digdate[3]);
- digdisplay(2,digdate[2]);
- digdisplay(1,digdate[1]);
- digdisplay(0,digdate[0]);
- }
- else
- {
- digdisplay(3,17);
- digdisplay(2,digdate[2]);
- digdisplay(1,digdate[1]);
- digdisplay(0,digdate[0]);
- }
- }
- }
- else
- {
- if(knum1==0) //開始顯示密碼
- {
- digdisplay(3,digcode[3]);
- digdisplay(2,digcode[2]);
- digdisplay(1,digcode[1]);
- digdisplay(0,digcode[0]);
- }
- else if(knum1==1)
- {
- if(flag0)
- {
- digdisplay(3,digcode[3]);
- digdisplay(2,digcode[2]);
- digdisplay(1,digcode[1]);
- digdisplay(0,digcode[0]);
- }
- else
- {
- digdisplay(3,digcode[3]);
- digdisplay(2,digcode[2]);
- digdisplay(1,digcode[1]);
- digdisplay(0,17);
- }
- }
- else if(knum1==2)
- {
- if(flag0)
- {
- digdisplay(3,digcode[3]);
- digdisplay(2,digcode[2]);
- digdisplay(1,digcode[1]);
- digdisplay(0,digcode[0]);
- }
- else
- {
- digdisplay(3,digcode[3]);
- digdisplay(2,digcode[2]);
- digdisplay(1,17);
- digdisplay(0,digcode[0]);
- }
- }
- else if(knum1==3)
- {
- if(flag0)
- {
- digdisplay(3,digcode[3]);
- digdisplay(2,digcode[2]);
- digdisplay(1,digcode[1]);
- digdisplay(0,digcode[0]);
- }
- else
- {
- digdisplay(3,digcode[3]);
- digdisplay(2,17);
- digdisplay(1,digcode[1]);
- digdisplay(0,digcode[0]);
- }
- }
- else if(knum1==4)
- {
- if(flag0)
- {
- digdisplay(3,digcode[3]);
- digdisplay(2,digcode[2]);
- digdisplay(1,digcode[1]);
- digdisplay(0,digcode[0]);
- }
- else
- {
- digdisplay(3,17);
- digdisplay(2,digcode[2]);
- digdisplay(1,digcode[1]);
- digdisplay(0,digcode[0]);
- }
- }
- }
- }
-
- void main()
- {
- TMOD &= 0xF0; //設置定時器模式 10毫秒定時中斷
- TMOD |= 0x01; //設置定時器模式
- TL0 = 0xF0; //設置定時初值
- TH0 = 0xD8; //設置定時初值
- TF0 = 0; //清除TF0標志
- ET0=1;
- EA=1;
- while(1)
- {
- keyprogress();
- display();
- }
- }
- void Timer0() interrupt 1
- {
- TL0 = 0xF0; //設置定時初值
- TH0 = 0xD8; //設置定時初值
- if(knum!=0||knum1!=0) //數碼管顯示所需的條件,二合一。
- {
- time++;
- if(time==50) //進行0.5秒的計時
- {
- time=0;
- flag0=!flag0;
- }
- }
- }
復制代碼
全部資料51hei下載地址:
用數碼管以及矩陣按鍵實現密碼鎖功能.rar
(38.4 KB, 下載次數: 38)
2020-2-18 17:30 上傳
點擊文件名下載附件
|