|
本帖最后由 凌凈清河 于 2018-12-11 12:04 編輯
重新編輯說(shuō)明:取消了回復(fù)才能下載的限制,取消了下載付黑幣的設(shè)置。
另外我建立了一個(gè)STC 51單片機(jī)初學(xué)者提升qq群,如果你想在單片機(jī)的道路上從菜鳥走到入門,歡迎加群和大家共同成長(zhǎng)。群剛開始建立,人數(shù)尚少,內(nèi)有資料不斷完善中。群聊號(hào)碼:873434536
特注:群不盈利、無(wú)廣告、沒有強(qiáng)制活動(dòng)、沒有潛規(guī)則,僅為個(gè)人興趣和專業(yè)方向使然。
聲明:
0.基本版代碼相對(duì)冗余,但仍然請(qǐng)大家在轉(zhuǎn)載、分享時(shí)提及原作者,非常感謝
1.設(shè)計(jì)使用STC15W4K48S4制作,在無(wú)需修改管理員密碼的版本中可以使用IAP的單片機(jī)代替
2.本程序和設(shè)計(jì)為最基本版,只有簡(jiǎn)單的密碼開鎖和管理功能,更多更完善功能的版本請(qǐng)期待本人的后續(xù)帖子(雖然已經(jīng)設(shè)計(jì)完成,但還是預(yù)計(jì)2019年1月份,考完研之后才能夠整理發(fā)出)
3.由于是初稿,所以程序的結(jié)構(gòu)上比較混亂,本人只保證其可以運(yùn)行并且沒有明顯的BUG、不保證程序可讀性,但是大家可以自取所需功能
4.本版本只是一個(gè)“預(yù)熱”,請(qǐng)高手勿噴,至少也請(qǐng)看完1、2個(gè)月后的第二版之后再說(shuō);
請(qǐng)初學(xué)者不要仿制,畢竟這個(gè)版本還非常非常LOW,遠(yuǎn)遠(yuǎn)沒有達(dá)到使用標(biāo)準(zhǔn),也沒有進(jìn)行功能的優(yōu)化、邏輯的論證、程序的精簡(jiǎn),這些將在第二版中體現(xiàn)出來(lái)。
設(shè)計(jì)亮點(diǎn):
1.使用OLED12864屏幕顯示,具有用戶菜單和管理員菜單,直觀明了的設(shè)置使用流程(菜單未使用結(jié)構(gòu)體或鏈表)
2.用戶密碼存儲(chǔ)加密,使用BKDR哈希值計(jì)算并存儲(chǔ),防止從24C02中竊取密碼
3.放棄傳統(tǒng)的矩陣鍵盤,使用ADC鍵盤,連接上更加方便
4.如3項(xiàng)所示,密碼為16進(jìn)制,最大輸入16位
5.對(duì)于添加了管理員密碼的版本,使用內(nèi)部EEPROM存儲(chǔ)管理員密碼(在本版本中,管理員密碼明文存儲(chǔ))
簡(jiǎn)易操作說(shuō)明:
上電進(jìn)入用戶模式鎖定狀態(tài),在鎖定狀態(tài)下輸入密碼后,使用KEY1鍵確認(rèn),KEY2鍵取消,若密碼正確,在按下確認(rèn)鍵的時(shí)候會(huì)顯示正確提示信息,松開按鍵進(jìn)入用戶菜單
如果用戶模式下密碼連續(xù)輸入錯(cuò)誤5次則自動(dòng)鎖死,此時(shí)可以重新上電清空錯(cuò)誤計(jì)數(shù)或者進(jìn)入管理員模式立即解鎖,這種鎖定不會(huì)自動(dòng)解鎖
在用戶菜單下不進(jìn)行任何操作5秒則自動(dòng)上鎖,使用KEY3、KEY4鍵進(jìn)行選項(xiàng)的上下選擇,KEY1鍵執(zhí)行,KEY2鍵取消,在用戶模式下按KEY2鍵取消會(huì)返回上鎖狀態(tài)
在用戶模式鎖定狀態(tài)下,若硬件開關(guān)Hardware_Switch(P4^5)置0,按下KEY1鍵進(jìn)入管理員認(rèn)證,管理員密碼輸入流程與用戶相同,密碼正確則進(jìn)入管理菜單
在管理員菜單下可以進(jìn)行各樣高權(quán)限操作,這些操作在程序上對(duì)用戶模式屏蔽。
在管理模式菜單中各項(xiàng)選項(xiàng)的功能和操作說(shuō)明如下:
1.立即解除鎖定
該選項(xiàng)將用戶模式錯(cuò)誤計(jì)數(shù)變量清零,沒有提示信息,按下確認(rèn)鍵即可
2.修改用戶密碼
在管理員狀態(tài)下修改用戶密碼不需要確認(rèn),直接輸入新密碼確定即立即生效,在輸入密碼時(shí)按下取消鍵原密碼不改變
3.修改管理密碼
修改管理密碼需要兩步:身份認(rèn)證和輸入新密碼。在任何一步按下取消鍵原密碼不改變
4.常開常關(guān)選項(xiàng)
當(dāng)停用密碼鎖時(shí)返回用戶狀態(tài)時(shí)繼電器常開
當(dāng)啟用密碼鎖時(shí)用戶模式正常
5.版本信息
用于記錄或顯示某些信息,這些信息允許在編程階段修改
6.退出管理模式
選擇此項(xiàng)按確定鍵和在任意項(xiàng)上按返回鍵效果一致,均回到管理員身份驗(yàn)證狀態(tài),希望回到用戶模式時(shí)可以在管理員非密碼修改模式下拔除Hardware_Switch(P4^5)跳帽或?qū)⑵渲酶?br />
考慮到的意外情況:
如果在關(guān)機(jī)時(shí)將AT24C02替換,且沒有存儲(chǔ)準(zhǔn)確的信息,開機(jī)上電用戶模式會(huì)自動(dòng)鎖死,需要管理員重置用戶密碼
實(shí)現(xiàn)機(jī)制:在AT24C02中不僅存放了用戶密碼的HASH值,也存入了4個(gè)字節(jié)的用戶ID信息,這信息與燒錄在程序中的用戶ID信息必須一致,才能夠通過(guò)上電檢測(cè),否則使用戶鎖定標(biāo)志位有效
版本缺陷:
由于本版本是最初學(xué)習(xí)時(shí)嘗試設(shè)計(jì)的,所以有一些問(wèn)題和缺陷,隨著后續(xù)的修改和測(cè)試逐漸發(fā)現(xiàn)的,但是已經(jīng)無(wú)心更改,F(xiàn)列出所有問(wèn)題如下所示:
1.繼電器控制引腳的位定義未在包含文件語(yǔ)句(#include)之前,使得其他文件中對(duì)繼電器的操作是直接給P00賦值,而非使用JDQ這個(gè)位定義名稱,修改時(shí)需要注意;
2.繼電器的控制三極管采用了NPN型,但是后來(lái)發(fā)現(xiàn)這樣會(huì)導(dǎo)致上電吸合一次,在第二版中修正了這個(gè)錯(cuò)誤但是本版本仍然保留;
3.本版本中設(shè)定密碼開鎖后5秒自動(dòng)關(guān)鎖,這個(gè)在程序中可以修改,需要注意一下;
4.按鍵按下會(huì)導(dǎo)致程序死循環(huán),原因是僅僅使用了最簡(jiǎn)單的按鍵判斷:即假設(shè)每個(gè)獨(dú)立按鍵按下之后都會(huì)立即松開;
5.本版本中未添加時(shí)間修改函數(shù),程序的時(shí)間是在下載程序的時(shí)候掐點(diǎn)矯正的,第二版會(huì)添加該功能。
IMG_20181205_100715.jpg (2.99 MB, 下載次數(shù): 132)
下載附件
2018-12-5 10:15 上傳
IMG_20181205_100731.jpg (3.34 MB, 下載次數(shù): 163)
下載附件
2018-12-5 10:15 上傳
IMG_20181205_100905.jpg (1.52 MB, 下載次數(shù): 159)
下載附件
2018-12-5 10:15 上傳
IMG_20181205_100918.jpg (1.61 MB, 下載次數(shù): 152)
下載附件
2018-12-5 10:15 上傳
1543975978866.jpg (3.64 MB, 下載次數(shù): 151)
下載附件
2018-12-5 10:15 上傳
1543976026767.jpg (4.48 MB, 下載次數(shù): 144)
下載附件
2018-12-5 10:15 上傳
單片機(jī)源程序如下:
- #include<STC15.H>
- #include<intrins.h>
- sbit LED1=P3^0;
- sbit LED2=P3^1;
- sbit KEY1=P3^2;
- sbit KEY2=P3^3;
- sbit KEY3=P2^1;
- sbit KEY4=P2^2;
- //由于后續(xù)包含的文件中可能用到上述位定義故將這部分位定義放在包含文件的語(yǔ)句之前
- #include"OLED_Display.c"
- #include"DS1302_Driver.c"
- #include"AT24C02_Driver.c"
- #include"BKDR_HASH_Fuction.c"
- sbit JDQ=P0^0;//繼電器引腳
- sbit Hardware_Switch=P4^5;//管理員/用戶硬件開關(guān) 用戶:1 管理員:0
- //擴(kuò)展作用域
- extern unsigned char hash_result[4];
- //運(yùn)行數(shù)組
- unsigned char user_ID[4]={0x92,0x5A,0xA0,0xC1};
- unsigned char version[4]={0,9,0,8};//版本信息(自定義)
- unsigned char Administrator_Password[16]={0,1,0,15,0,0,0,0,0,0,0,0,0,0,0,0};//管理員密碼存放數(shù)組
- unsigned char User_Password_Putin[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//用戶密碼輸入臨時(shí)存放數(shù)組
- unsigned char Admin_Password_Putin[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//管理員密碼輸入臨時(shí)存放數(shù)組
- unsigned char Admin_Password_New_Temp[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//管理員密碼修改時(shí),新密碼臨時(shí)存放數(shù)組,可以考慮與輸入臨時(shí)存放數(shù)組復(fù)用
- //運(yùn)行變量
- unsigned int ADC_DATA;//讀取到的ADC轉(zhuǎn)換值
- unsigned char ADC_value=0;//設(shè)置一個(gè)讀取到的按鍵位置值。位置值由電路連接確定,各個(gè)按鍵位置值由所連電阻分壓大小依次順序排列
- unsigned char ADC_keyvalue=0;//讀取到的ADC按鍵設(shè)定值。按鍵位置由電路而定可能并不規(guī)整,設(shè)定值為自定的各按鍵數(shù)值
- unsigned char first_num=1;//管理模式第一項(xiàng)菜單標(biāo)號(hào)
- //運(yùn)行計(jì)數(shù)
- unsigned char choose=1;//用戶菜單選擇號(hào),用于記錄當(dāng)前選中的菜單項(xiàng)目序號(hào),默認(rèn)在第一項(xiàng)位置
- unsigned char cnt_user_putin_wrong=0;//用戶輸入錯(cuò)誤計(jì)數(shù)
- unsigned char t1_cnt=0;//定時(shí)器1運(yùn)行計(jì)數(shù)
- //運(yùn)行標(biāo)志位
- bit flag_Identity=1;//身份標(biāo)志位,表明當(dāng)前所處身份狀態(tài) 用戶:1 管理員:0
- bit En_Standby=1;//待機(jī)狀態(tài)有效標(biāo)志位(使能) 有效:1 無(wú)效:0
- bit En_Admin=0;//管理員模式下管理有效標(biāo)志位(使能) 有效:1 無(wú)效:0
- bit User_Locker=0;//用戶輸入錯(cuò)誤導(dǎo)致的鎖定有效 有效:1 無(wú)效:0
- bit Admin_Info=0;//管理員提示開關(guān),在用戶待機(jī)狀態(tài)下顯示某些信息 有效:1 無(wú)效:0
- bit _ReLock=0;//自動(dòng)鎖定標(biāo)志位,顯示定時(shí)器是否已經(jīng)到達(dá)計(jì)時(shí)時(shí)間 是:1 否:0
- /*##############################################################################################
- 設(shè)計(jì)名稱:電子鎖設(shè)計(jì)
- 設(shè)計(jì)者:清河
- 版本:9.8.1
- 詳情:已經(jīng)初步完成功能設(shè)定,添加自動(dòng)鎖定功能,并排除BUG。豐富了注釋內(nèi)容。
- 添加用戶的斷電密碼記憶功能和密碼加密存儲(chǔ)功能,添加開機(jī)AT24C02判斷
- 掉電存儲(chǔ)構(gòu)想:
- 在每一次更新用戶密碼時(shí)將新密碼hash值存放進(jìn)存儲(chǔ)器中,管理員密碼明文存儲(chǔ)
- 加密存儲(chǔ)構(gòu)想:
- 使用加密函數(shù)將用戶密碼加密后存儲(chǔ),核對(duì)密碼時(shí)通過(guò)加密函數(shù)求出特征值和存儲(chǔ)器中的比對(duì)
- 存儲(chǔ)安全性保證:為防止換用AT24C02導(dǎo)致使用不便或達(dá)到非法開鎖的目的,分別使用AT24C02存儲(chǔ)用戶的密碼HASH值
- 片外EEPROM:存放用戶密碼的HASH值,并存入檢測(cè)字節(jié),在系統(tǒng)啟動(dòng)時(shí)檢測(cè)AT24C02是否有被改動(dòng)過(guò)以提高系統(tǒng)安全性
- 擴(kuò)展:如果有用戶個(gè)性化的設(shè)置,也可以如此存放,便于管理
- 平臺(tái):STC15W4K48S4
- 硬件部分
- 獨(dú)立按鍵:共4個(gè),用于進(jìn)行各項(xiàng)調(diào)整
- ADC鍵盤:用于輸入密碼,本作品中可以輸入16進(jìn)制的密碼,較平常10位密碼更加安全,只要程序和電路做相應(yīng)的修改,也可以實(shí)現(xiàn)在AD可分辨的情況下上百的按鍵鍵位
- DS1302:配電池,實(shí)現(xiàn)斷電走時(shí),用于待機(jī)顯示,如果在關(guān)機(jī)時(shí)取下電池或者替換DS1302則會(huì)出錯(cuò),需要重新燒錄程序初始化DS1302
- LED指示燈:指示所處狀態(tài),本作品中進(jìn)入用戶模式則LED1亮,進(jìn)入管理員模式則LED2亮
- AT24C02:實(shí)現(xiàn)斷電密碼記憶功能,用于記錄用戶密碼的HASH值
- 軟件部分
- 使用定時(shí)器0實(shí)現(xiàn)對(duì)DS1302數(shù)據(jù)的定時(shí)讀取,間隔50ms,以便更新當(dāng)前的顯示值
- 使用定時(shí)器1在用戶解鎖成功時(shí)定時(shí)上鎖,設(shè)置的超時(shí)時(shí)間為5秒
- 操作說(shuō)明:
- 上電進(jìn)入用戶模式鎖定狀態(tài),在鎖定狀態(tài)下輸入密碼后,使用KEY1鍵確認(rèn),KEY2鍵取消,若密碼正確,在按下確認(rèn)鍵的時(shí)候會(huì)顯示正確提示信息,松開按鍵進(jìn)入用戶菜單
- 如果用戶模式下密碼連續(xù)輸入錯(cuò)誤5次則自動(dòng)鎖死,此時(shí)可以重新上電清空錯(cuò)誤計(jì)數(shù)或者進(jìn)入管理員模式立即解鎖,這種鎖定不會(huì)自動(dòng)解鎖
- 在用戶菜單下不進(jìn)行任何操作5秒則自動(dòng)上鎖,使用KEY3、KEY4鍵進(jìn)行選項(xiàng)的上下選擇,KEY1鍵執(zhí)行,KEY2鍵取消,在用戶模式下按KEY2鍵取消會(huì)返回上鎖狀態(tài)
- 在用戶模式鎖定狀態(tài)下,若硬件開關(guān)Hardware_Switch(P4^5)置0,按下KEY1鍵進(jìn)入管理員認(rèn)證,管理員密碼輸入流程與用戶相同,密碼正確則進(jìn)入管理菜單
- 在管理員菜單下可以進(jìn)行各樣高權(quán)限操作,這些操作在程序上對(duì)用戶模式屏蔽。
- 在管理模式菜單中各項(xiàng)選項(xiàng)的功能和操作說(shuō)明如下:
- 1.立即解除鎖定
- 該選項(xiàng)將用戶模式錯(cuò)誤計(jì)數(shù)變量清零,沒有提示信息,按下確認(rèn)鍵即可
- 2.修改用戶密碼
- 在管理員狀態(tài)下修改用戶密碼不需要確認(rèn),直接輸入新密碼確定即立即生效,在輸入密碼時(shí)按下取消鍵原密碼不改變
- 3.修改管理密碼
- 修改管理密碼需要兩步:身份認(rèn)證和輸入新密碼。在任何一步按下取消鍵原密碼不改變
- 4.常開常關(guān)選項(xiàng)
- 當(dāng)停用密碼鎖時(shí)返回用戶狀態(tài)時(shí)繼電器常開
- 當(dāng)啟用密碼鎖時(shí)用戶模式正常
- 5.版本信息
- 用于記錄或顯示某些信息,這些信息允許在編程階段修改
- 6.退出管理模式
- 選擇此項(xiàng)按確定鍵和在任意項(xiàng)上按返回鍵效果一致,均回到管理員身份驗(yàn)證狀態(tài),希望回到用戶模式時(shí)可以在管理員非密碼修改模式下拔除Hardware_Switch(P4^5)跳帽或?qū)⑵渲酶?br />
- 考慮到的意外情況:
- 如果在關(guān)機(jī)時(shí)將AT24C02替換,且沒有存儲(chǔ)準(zhǔn)確的信息,開機(jī)上電用戶模式會(huì)自動(dòng)鎖死,需要管理員重置用戶密碼
- 實(shí)現(xiàn)機(jī)制:在AT24C02中不僅存放了用戶密碼的HASH值,也存入了4個(gè)字節(jié)的用戶ID信息,這信息與燒錄在程序中的用戶ID信息必須一致,才能夠通過(guò)上電檢測(cè),否則使用戶鎖定標(biāo)志位有效
- 特別注意:繼電器部分在本版本程序中沒有考慮到上電初始控制電平的問(wèn)題,上電瞬間會(huì)吸合一次,建議將所有JDQ位反向控制,并將OLED_Display.c中對(duì)P00的控制相應(yīng)更改。
- 更改后外圍電路上應(yīng)采用PNP典型控制電路即P口低電平時(shí)繼電器打開,否則關(guān)閉
- 經(jīng)過(guò)再三考慮,不添加密碼重置功能,即在添加掉電存儲(chǔ)的程序版本中,一旦忘記用戶密碼和管理密碼則無(wú)法找回,只能通過(guò)刷固件的方式重置密碼以提高整體安全性
- 但是后期若能夠添加指紋識(shí)別等模塊,通過(guò)該個(gè)人生物識(shí)別的機(jī)制更改管理密碼會(huì)使安全性得到很大的提升
- ##############################################################################################*/
- void delay(unsigned int cnt)//調(diào)用該函數(shù)進(jìn)行一段時(shí)間的延時(shí)
- {
- while(cnt--);
- }
- unsigned char KeyScan()
- {
- unsigned char ADC_keyvalue=0;//讀取到的ADC按鍵設(shè)定值
- ADC_CONTR=0xea;//開始轉(zhuǎn)換
- delay(1000);//這段暫停的時(shí)間用于等待AD轉(zhuǎn)換完成
- switch(ADC_value)
- {
- case 0:ADC_keyvalue=12;break;
- case 1:ADC_keyvalue=13;break;
- case 2:ADC_keyvalue=14;break;
- case 3:ADC_keyvalue=15;break;
- case 4:ADC_keyvalue=11;break;
- case 5:ADC_keyvalue=10;break;
- case 6:ADC_keyvalue=9;break;
- case 7:ADC_keyvalue=8;break;
- case 8:ADC_keyvalue=4;break;
- case 9:ADC_keyvalue=5;break;
- case 10:ADC_keyvalue=6;break;
- case 11:ADC_keyvalue=7;break;
- case 12:ADC_keyvalue=3;break;
- case 13:ADC_keyvalue=2;break;
- case 14:ADC_keyvalue=1;break;
- case 15:ADC_keyvalue=0;break;
- default:ADC_keyvalue=16;break;
- }
- return ADC_keyvalue;
- }
- unsigned char Modify_User_Password()//用戶密碼更改函數(shù),用于獲取新值賦給用戶密碼數(shù)組
- {
- unsigned char i;
- OLED_Clear();
- OLED_Show_CHinese(0,CCTitle7,1);//顯示標(biāo)題:修改密碼
- for(i=0;i<16;i++)
- {
- OLED_Show_sChar(i*8,2,sChar3,1);//顯示橫線
- }
- OLED_Show_CHinese(4,CCInfo5,1);//顯示說(shuō)明文字:請(qǐng)輸入新密碼:
-
- for(i=0;i<16;)//進(jìn)入輸密碼的環(huán)節(jié)
- {
- OLED_Show_Number(0,6,User_Password_Putin,i,1);//顯示輸入的值
- if(KeyScan()!=16)
- {
- delay(5000);
- if(KeyScan()!=16)
- {
- User_Password_Putin[i]=KeyScan();//記錄每一次輸入的值
- i++;
- }
- while(KeyScan()!=16);//等待按鍵松開
- }
-
- if(KEY1==0||i==16)//如果確定鍵按下或輸滿16位
- {
- delay(5000);
- if(KEY1==0||i==16)
- {
- unsigned char k=0;
- Password_BKDRHASH_Calculation(User_Password_Putin,16);//對(duì)輸入的值求HASH值,保存在hash_result數(shù)組中
- Save_User_Password();//保存新數(shù)據(jù)
- for(k=0;k<16;k++)
- {
- User_Password_Putin[k]=0;//清空用戶輸入
- }
- }
- while(!KEY1);
- OLED_Clear();//清屏,清屏放在此處可以使密碼正確的提示信息在按鍵松開前一直顯示
- break;//立即退出輸入密碼的環(huán)節(jié)
- }
-
- if(KEY2==0)//如果取消鍵按下
- {
- delay(5000);
- if(KEY2==0)
- {
- unsigned char j;
- for(j=0;j<16;j++)
- {
- User_Password_Putin[j]=0;//清空用戶輸入
- }
- OLED_Clear();//清屏
- }
- while(!KEY2);
- break;//立即退出輸入密碼的環(huán)節(jié)
- }
- }
- return 0;
- }
- unsigned char Modify_Admin_Password()//管理員密碼修改,包括2個(gè)步驟:身份認(rèn)證、密碼修改,其中任何一步都可以由取消鍵退出
- {
- unsigned char i;
- OLED_Clear();
- OLED_Display_Administrator_Onload();
-
- for(i=0;i<16;)//進(jìn)入輸密碼的環(huán)節(jié)
- {
- if(KeyScan()!=16)
- {
- delay(5000);
- if(KeyScan()!=16)
- {
- Admin_Password_Putin[i]=KeyScan();//記錄每一次輸入的值
- OLED_Show_sChar(i*8,6,sChar1,1);//顯示*
- i++;
- }
- while(KeyScan()!=16);//等待按鍵松開
- }
-
- if(KEY1==0||i==16)//如果確定鍵按下或輸入位數(shù)滿
- {
- delay(5000);
- if(KEY1==0||i==16)
- {
- unsigned char k=0,t=0;
- for(k=0;k<16;k++)
- {
- if(Admin_Password_Putin[k]==Administrator_Password[k])//核對(duì)明文密碼
- {
- t++;//每有一個(gè)位置同,則t自增
- }
- }
-
- if(t==16)//密碼正確,可以進(jìn)行修改密碼的操作
- {
- OLED_Clear();
- OLED_Show_CHinese(0,CCTitle7,1);//顯示標(biāo)題:修改密碼
- for(i=0;i<16;i++)
- {
- OLED_Show_sChar(i*8,2,sChar3,1);//顯示橫線
- }
- OLED_Show_CHinese(4,CCInfo5,1);//顯示說(shuō)明文字:請(qǐng)輸入新密碼:
- while(!KEY1);
-
- for(i=0;i<16;)//進(jìn)入輸密碼的環(huán)節(jié)
- {
- OLED_Show_Number(0,6,Admin_Password_New_Temp,i,1);//顯示輸入的值
- if(KeyScan()!=16)
- {
- delay(5000);
- if(KeyScan()!=16)
- {
- Admin_Password_New_Temp[i]=KeyScan();//記錄每一次輸入的值
- i++;
- }
- while(KeyScan()!=16);//等待按鍵松開
- }
-
- if(KEY1==0||i==16)//如果確定鍵按下或輸滿16位
- {
- delay(5000);
- if(KEY1==0||i==16)
- {
- unsigned char k=0,t=0;
- for(k=0;k<16;k++)
- {
- Administrator_Password[k]=Admin_Password_New_Temp[k];//存入新密碼
- Admin_Password_New_Temp[k]=0;//清空輸入
- }
- }
- while(!KEY1);
- OLED_Clear();//清屏,清屏放在此處可以使密碼正確的提示信息在按鍵松開前一直顯示
- break;//立即退出輸入密碼的環(huán)節(jié)
- }
-
- if(KEY2==0)//如果取消鍵按下
- {
- delay(5000);
- if(KEY2==0)
- {
- unsigned char j;
- for(j=0;j<16;j++)
- {
- Admin_Password_New_Temp[j]=0;//清空用戶輸入
- }
- OLED_Clear();//清屏
- }
- while(!KEY2);
- break;//立即退出輸入密碼的環(huán)節(jié)
- }
- }
- }
- else//密碼錯(cuò)誤
- {
- for(k=0;k<16;k++)
- {
- Admin_Password_Putin[k]=0;//清空管理員輸入
- }
- OLED_Clear();
- }
- }
- while(!KEY1);
- goto END;//結(jié)束輸入
- }
-
- if(KEY2==0)//如果取消鍵按下
- {
- delay(5000);
- if(KEY2==0)
- {
- unsigned char j;
- for(j=0;j<16;j++)
- {
- Admin_Password_Putin[j]=0;//清空管理員輸入
- }
- OLED_Clear();
- }
- while(!KEY2);
- goto END;//結(jié)束輸入
- }
- }
- END:return 0;
- }
- void sys_init()//系統(tǒng)初始化
- {
- P1M1=0x00;
- P1M0=0x00;
- P3M1=0x00;
- P3M0=0x00;
- P2M1=0x00;
- P2M0=0x00;
- P4M1=0x00;
- P4M0=0x00;
- P5M0=0x00;
- P5M1=0x00;
- P0M1=0x00;
- P0M0=0x00;//對(duì)于STC15W4K32S4系列的單片機(jī),對(duì)IO的初始化操作必須要有
-
- TMOD=0x11;//設(shè)置定時(shí)器模式
- EA=1;//開啟總中斷
- TL0=0x00;//設(shè)置定時(shí)初值
- TH0=0x28;//設(shè)置定時(shí)初值
- ET0=1;//允許定時(shí)器0中斷
- TR0=1;//定時(shí)器0開始計(jì)時(shí)
-
- TL1=0x00;//設(shè)置定時(shí)初值
- TH1=0x28;//設(shè)置定時(shí)初值
- ET1=1;//允許定時(shí)器1中斷
- TR1=0;//定時(shí)器1開始計(jì)時(shí)
-
- P1ASF=0x04;//將P1^2設(shè)置為模擬輸入
- ADC_CONTR=0xe7;//開啟ADC電源,設(shè)置為最快轉(zhuǎn)換速度,停止轉(zhuǎn)換,選取P1^2作為ADC輸入
- ADC_RES=0;//清除結(jié)果寄存器
- /*ADRJ=0;//ADC_RES[7:0]存放高8位ADC結(jié)果,ADC_RES[1:0]存放低2位ADC結(jié)果 EADC=1;//A/D轉(zhuǎn)換中斷允許 PADC=1;//設(shè)置A/D轉(zhuǎn)換中斷優(yōu)先級(jí)為最高*/
- //CLK_DIV=0X20;
- EADC=1;
- PADC=1;
- }
- void sys_Pretreat()//系統(tǒng)預(yù)處理
- {
- //Ds1302Init();//首次上電對(duì)DS1302做初始化
- OLED_Init();//初始化OLED
- OLED_Clear();//OLED清屏
- JDQ=0;//繼電器給低電平
-
- /*在此處添加上電AT24C02檢測(cè)*/
- for(t1_cnt=0;t1_cnt<8;t1_cnt++)//將t1_cnt作為臨時(shí)計(jì)時(shí)變量
- {
- AT24C02_Read_Array[t1_cnt]=AT24C02_Read(0xA0,t1_cnt+1);
- Delay1ms();
- }
- for(t1_cnt=0;t1_cnt<4;t1_cnt++)//將t1_cnt作為臨時(shí)計(jì)時(shí)變量
- {
- if(AT24C02_Read_Array[t1_cnt]!=user_ID[t1_cnt])//如果從AT24C02中讀出的用戶ID和程序中設(shè)定值不同說(shuō)明器件被更替,用戶鎖定,需要重新設(shè)置密碼
- {
- User_Locker=1;
- }
- }
- t1_cnt=0;//使用后重置t1_cnt
- }
- void main()
- {
- sys_init();
- sys_Pretreat();
- while(1)
- {
- if(flag_Identity)//身份狀態(tài)
- {//用戶模式
- if(En_Standby)
- {//上鎖的待機(jī)狀態(tài)
- LED1=1;LED2=1;
- if(Admin_Info)
- {
- unsigned char i;
- OLED_Show_CHinese(0,CCInfo6,1);//顯示說(shuō)明文字:繼電器已啟用
- for(i=0;i<16;i++)
- {
- OLED_Show_sChar(i*8,2,sChar4,1);//顯示橫線
- }
- OLED_Show_CHinese(4,CCText1,1);//顯示說(shuō)明文字:解鎖由管理員初始
- }
- else
- {
- OLED_Display_Standby();//用戶模式下,上鎖時(shí)的待機(jī)顯示
- }
-
- if(KeyScan()!=16&&En_Standby&&(!User_Locker))//如果在某一時(shí)刻ADC鍵盤有了輸入并且用戶沒有鎖定則繼續(xù)探測(cè)
- {
- delay(5000);
- if(KeyScan()!=16&&En_Standby)
- {
- unsigned char i;
- User_Password_Putin[0]=KeyScan();//那么重新捕獲這個(gè)值
- while(KeyScan()!=16);//等待按鍵松開
- OLED_Clear();//OLED清屏
- OLED_Display_Put_In_Password();//顯示密碼輸入界面
- OLED_Show_sChar(0,6,sChar1,1);//顯示*
- for(i=1;i<16;)//進(jìn)入輸密碼的環(huán)節(jié)
- {
- if(KeyScan()!=16)
- {
- delay(5000);
- if(KeyScan()!=16)
- {
- User_Password_Putin[i]=KeyScan();//記錄每一次輸入的值
- OLED_Show_sChar(i*8,6,sChar1,1);//顯示*
- i++;
- }
- while(KeyScan()!=16);//等待按鍵松開
- }
-
- if(KEY1==0||i==16)//如果確定鍵按下或輸滿16位
- {
- delay(5000);
- if(KEY1==0||i==16)
- {
- unsigned char k=0,t=0;
- Password_BKDRHASH_Calculation(User_Password_Putin,16);//對(duì)輸入的值求HASH值,保存在hash_result數(shù)組中
-
- if(HASH_Compare())//密碼正確
- {
- En_Standby=0;//不再是待機(jī)狀態(tài)
- JDQ=1;//開啟繼電器
- OLED_Clear();
- OLED_Display_Right_Password();
- t1_cnt=0;
- TR1=1;//定時(shí)器1開始計(jì)時(shí)
- }
- else//密碼錯(cuò)誤
- {
- En_Standby=1;//仍在待機(jī)狀態(tài)
- cnt_user_putin_wrong++;//錯(cuò)誤計(jì)數(shù)增加一次
- if(cnt_user_putin_wrong==5)
- {
- User_Locker=1;//用戶鎖定有效
- cnt_user_putin_wrong=0;//但錯(cuò)誤計(jì)數(shù)置0,這樣一來(lái)在管理員模式下只需要關(guān)心用戶鎖定標(biāo)志位即可
- }
- }
-
- for(k=0;k<16;k++)
- {
- User_Password_Putin[k]=0;//清空用戶輸入
- }
-
- HASH_Result_Clear();//清空哈希計(jì)算結(jié)果
- }
- while(!KEY1);
- OLED_Clear();//清屏,清屏放在此處可以使密碼正確的提示信息在按鍵松開前一直顯示
- goto A;//立即退出輸入密碼的環(huán)節(jié)
- }
-
- if(KEY2==0)//如果取消鍵按下
- {
- delay(5000);
- if(KEY2==0)
- {
- unsigned char j;
- for(j=0;j<16;j++)
- {
- User_Password_Putin[j]=0;//清空用戶輸入
- }
- OLED_Clear();//清屏
- HASH_Result_Clear();//清空哈希計(jì)算結(jié)果
- }
- while(!KEY2);
- goto A;//立即退出輸入密碼的環(huán)節(jié)
- }
- }
- A: _nop_();
- }
- }
-
- if(KEY1==0)//待機(jī)狀態(tài)下KEY1是管理員入口開關(guān)
- {
- delay(8000);
- if(KEY1==0)
- {
- if(Hardware_Switch==0)
- {
- OLED_Clear();
- flag_Identity=0;
- }
- }
- while(!KEY1);
- }
- }
- else
- {//解鎖的待機(jī)狀態(tài)
- OLED_User_Mode();//用戶模式菜單動(dòng)態(tài)顯示
- LED1=0;LED2=1;
- if(KEY1==0)//確定按鍵
- {
- delay(5000);
- if(KEY1==0)
- {
- switch(choose)
- {
- case 1:
- JDQ=0;//關(guān)閉繼電器
- TR1=0;//定時(shí)器1停止計(jì)時(shí)
- TL1=0x00;//設(shè)置定時(shí)初值
- TH1=0x28;//設(shè)置定時(shí)初值
- t1_cnt=0;
- En_Standby=1;//重新回到上鎖狀態(tài)
- break;
- case 2:
- while(!KEY1);//等待按鍵松開,若不加此句可能導(dǎo)致Modify_User_Password()瞬間運(yùn)行完,用戶密碼變?yōu)?
- choose=1;//重置菜單選擇位
- TR1=0;//定時(shí)器1停止計(jì)時(shí)
- TL1=0x00;//設(shè)置定時(shí)初值
- TH1=0x28;//設(shè)置定時(shí)初值
- t1_cnt=0;
- Modify_User_Password();
- TR1=1;//定時(shí)器1開始計(jì)時(shí)
- break;
- }
- }
- while(!KEY1);
- OLED_Clear();
- }
-
- if(KEY2==0)//取消按鍵
- {
- delay(5000);
- if(KEY2==0)
- {
- choose=1;//重置菜單選擇位
- JDQ=0;//關(guān)閉繼電器
- TR1=0;//定時(shí)器1停止計(jì)時(shí)
- TL1=0x00;//設(shè)置定時(shí)初值
- TH1=0x28;//設(shè)置定時(shí)初值
- t1_cnt=0;
- En_Standby=1;//重新回到上鎖狀態(tài)
- }
- while(!KEY2);
- OLED_Clear();
- }
-
- if(_ReLock)//自動(dòng)上鎖判斷
- {
- En_Standby=1;//重新回到上鎖狀態(tài)
- _ReLock=0;//重置標(biāo)志位
- TR1=0;//關(guān)閉定時(shí)器1
- TL1=0x00;//設(shè)置定時(shí)初值
- TH1=0x28;//設(shè)置定時(shí)初值
- t1_cnt=0;//重置定時(shí)器1運(yùn)行計(jì)數(shù)
- OLED_Clear();//此處的清屏使用戶菜單在待機(jī)界面沒有殘留
- }
- }
- }
- else
- {//管理員狀態(tài)確認(rèn)
- if(Hardware_Switch==0)
- {//管理員模式
- if(En_Admin)//管理有效
- {
- OLED_Admin_Mode();//管理模式菜單動(dòng)態(tài)顯示
- LED1=1;LED2=0;
- if(KEY1==0)//確定按鍵
- {
- delay(5000);
- if(KEY1==0)
- {
- switch(choose)
- {
- case 1:
- User_Locker=0;//解除用戶鎖定
- break;
- case 2:
- while(!KEY1);//等待按鍵松開,若不加此句可能導(dǎo)致Modify_User_Password()瞬間運(yùn)行完,用戶密碼變?yōu)?
- Modify_User_Password();
- break;
- case 3:
- while(!KEY1);//等待按鍵松開,若不加此句可能導(dǎo)致Modify_Admin_Password()瞬間運(yùn)行完,管理密碼變?yōu)?
- Modify_Admin_Password();
- break;
- case 4:
- OLED_Admin_onoff_Mode();//常開常關(guān)選項(xiàng)
- break;
- case 5:
- OLED_Display_System_Information();//顯示版本信息
- break;
- case 6:
- En_Admin=0;//管理無(wú)效
- break;
- }
- }
- while(!KEY1);
- OLED_Clear();
- }
-
- if(KEY2==0)//取消按鍵
- {
- delay(5000);
- if(KEY2==0)
- {
- En_Admin=0;//管理無(wú)效
- }
- while(!KEY2);
- OLED_Clear();
- }
- }
- else//管理無(wú)效
- {
- OLED_Display_Administrator_Onload();
- LED1=1;LED2=1;
- if(KeyScan()!=16&&(!En_Admin))//如果在某一時(shí)刻ADC鍵盤有了輸入
- {
- delay(5000);
- if(KeyScan()!=16&&(!En_Admin))
- {
- unsigned char i;
- Admin_Password_Putin[0]=KeyScan();//那么重新捕獲這個(gè)值
- while(KeyScan()!=16);//等待按鍵松開
- OLED_Show_sChar(0,6,sChar1,1);//顯示*
-
- for(i=1;i<16;)//進(jìn)入輸密碼的環(huán)節(jié),如果前面有對(duì)第一位密碼的捕獲操作,則此處的循環(huán)從1開始15次
- {
- if(KeyScan()!=16)
- {
- delay(5000);
- if(KeyScan()!=16)
- {
- Admin_Password_Putin[i]=KeyScan();//記錄每一次輸入的值
- OLED_Show_sChar(i*8,6,sChar1,1);//顯示*
- i++;
- }
- while(KeyScan()!=16);//等待按鍵松開
- }
-
- if(KEY1==0||i==16)//如果確定鍵按下或輸入位數(shù)滿
- {
- delay(5000);
- if(KEY1==0||i==16)
- {
- unsigned char k=0,t=0;
- for(k=0;k<16;k++)
- {
- if(Admin_Password_Putin[k]==Administrator_Password[k])//核對(duì)明文密碼
- {
- t++;//每有一個(gè)位置同,則t自增
- }
- }
-
- if(t==16)//密碼正確
- {
- En_Admin=1;//管理有效
- }
- else//密碼錯(cuò)誤
- {
- En_Admin=0;//管理無(wú)效
- }
-
- for(k=0;k<16;k++)
- {
- Admin_Password_Putin[k]=0;//清空管理員輸入
- }
- OLED_Clear();
- }
- while(!KEY1);
- goto B;//立即退出輸入密碼的環(huán)節(jié)
- }
-
- if(KEY2==0||Hardware_Switch==1)//如果取消鍵按下或硬件標(biāo)志位被置1
- {
- delay(5000);
- if(KEY2==0||Hardware_Switch==1)
- {
- unsigned char j;
- for(j=0;j<16;j++)
- {
- Admin_Password_Putin[j]=0;//清空管理員輸入
- }
- OLED_Clear();
- }
- while(!KEY2);
- goto B;//立即退出輸入密碼的環(huán)節(jié)
- }
- }
- }
- }
- B: _nop_();
- }
- }
- else//如果硬件標(biāo)志位被置1
- {
- OLED_Clear();
- En_Admin=0;//管理無(wú)效
- choose=1;//由于管理模式菜單和用戶模式共用一個(gè)選擇項(xiàng),并且菜單顯示和choose有關(guān),所以如果不重置菜單選中位,菜單長(zhǎng)度的不同會(huì)導(dǎo)致用戶顯示的失敗
- first_num=1;/*如果第一項(xiàng)菜單標(biāo)號(hào)first_num改為全局變量,那么在此處將它置1可以保證每一次進(jìn)入管理菜單是默認(rèn)選中第一項(xiàng)*/
- flag_Identity=1;//返回用戶狀態(tài)
- }
- }
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
密碼鎖基本版 凌凈清河.zip
(260.4 KB, 下載次數(shù): 233)
2018-12-5 10:16 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|