<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 第34節(jié):在數(shù)碼管中實(shí)現(xiàn)iphone4S開機(jī)密碼鎖的程序

          第34節(jié):在數(shù)碼管中實(shí)現(xiàn)iphone4S開機(jī)密碼鎖的程序

          作者: 時(shí)間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
          開場白:
          這一節(jié)要教會(huì)大家四個(gè)知識(shí)點(diǎn):
          第一個(gè):類似手機(jī)上10秒鐘內(nèi)無按鍵操作將自動(dòng)進(jìn)入鎖屏的程序。
          第二個(gè):如何用一個(gè)數(shù)組來接收按鍵的一串?dāng)?shù)字輸入。
          第三個(gè):矩陣鍵盤中,數(shù)字按鍵的輸入,由于這部分按鍵的代碼相似度非常高,因此把它封裝在一個(gè)函數(shù)里可以非常簡潔方便。
          第四個(gè):繼續(xù)加深熟悉鴻哥首次提出的“一二級菜單顯示理論”:凡是人機(jī)界面顯示,不管是數(shù)碼管還是液晶屏,都可以把顯示的內(nèi)容分成不同的窗口來顯示,每個(gè)顯示的窗口中又可以分成不同的局部顯示。其中窗口就是一級菜單,用ucWd變量表示。局部就是二級菜單,用ucPart來表示。不同的窗口,會(huì)有不同的更新顯示變量ucWdXUpdate來對應(yīng),表示整屏全部更新顯示。不同的局部,也會(huì)有不同的更新顯示變量ucWdXPartYUpdate來對應(yīng),表示局部更新顯示。

          具體內(nèi)容,請看源代碼講解。

          (1)硬件平臺(tái):基于朱兆祺51單片機(jī)學(xué)習(xí)板。數(shù)字1鍵對應(yīng)S1鍵,數(shù)字2鍵對應(yīng)S2鍵,數(shù)字3鍵對應(yīng)S3鍵…. 數(shù)字9鍵對應(yīng)S9鍵, 數(shù)字0鍵對應(yīng)S10鍵。其他的按鍵不用。

          (2)實(shí)現(xiàn)功能:
          本程序有3個(gè)窗口。
          開機(jī)顯示第1個(gè)密碼登錄框窗口“----”,在這個(gè)窗口下輸入密碼,如果密碼等于”9922”表示密碼正確,將會(huì)切換到第2個(gè)顯示按鍵值的窗口。在窗口2下,按不同的按鍵會(huì)顯示不同的按鍵值,如果10秒內(nèi)沒有按鍵操作,將會(huì)自動(dòng)切換到第1個(gè)密碼登錄窗口,類似手機(jī)上的自動(dòng)鎖屏操作。在密碼登錄窗口1下,如果密碼不正確,會(huì)自動(dòng)清除密碼的數(shù)字,繼續(xù)在窗口1下顯示”----”。
          窗口3是用來停留0.5秒顯示全部密碼的信息,然后根據(jù)密碼的正確與否自動(dòng)切換到對應(yīng)的窗口。

          (3)源代碼講解如下:
          1. #include "REG52.H"
          2. #define const_no_key_push 4400 //大概10秒內(nèi)無按鍵按下的時(shí)間
          3. #define const_0_1s220 //大概0.5秒的時(shí)間
          4. #define const_voice_short40 //蜂鳴器短叫的持續(xù)時(shí)間
          5. #define const_key_time20 //按鍵去抖動(dòng)延時(shí)的時(shí)間
          6. void initial_myself();
          7. void initial_peripheral();
          8. void delay_short(unsigned int uiDelayShort);
          9. void delay_long(unsigned int uiDelaylong);
          10. //驅(qū)動(dòng)數(shù)碼管的74HC595
          11. void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01);
          12. void display_drive(); //顯示數(shù)碼管字模的驅(qū)動(dòng)函數(shù)
          13. void display_service(); //顯示的窗口菜單服務(wù)程序
          14. //驅(qū)動(dòng)LED的74HC595
          15. void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01);
          16. void T0_time();//定時(shí)中斷函數(shù)
          17. void number_key_input(unsigned char ucWhichKey);//由于數(shù)字按鍵的代碼相似度高,因此封裝在這個(gè)函數(shù)里
          18. void key_service(); //按鍵服務(wù)的應(yīng)用程序
          19. void key_scan();//按鍵掃描函數(shù) 放在定時(shí)中斷里
          20. sbit key_sr1=P0^0; //第一行輸入
          21. sbit key_sr2=P0^1; //第二行輸入
          22. sbit key_sr3=P0^2; //第三行輸入
          23. sbit key_sr4=P0^3; //第四行輸入
          24. sbit key_dr1=P0^4; //第一列輸出
          25. sbit key_dr2=P0^5; //第二列輸出
          26. sbit key_dr3=P0^6; //第三列輸出
          27. sbit key_dr4=P0^7; //第四列輸出
          28. sbit beep_dr=P2^7; //蜂鳴器的驅(qū)動(dòng)IO口
          29. sbit led_dr=P3^5;//作為中途暫停指示燈 亮的時(shí)候表示中途暫停
          30. sbit dig_hc595_sh_dr=P2^0; //數(shù)碼管的74HC595程序
          31. sbit dig_hc595_st_dr=P2^1;
          32. sbit dig_hc595_ds_dr=P2^2;
          33. sbit hc595_sh_dr=P2^3; //LED燈的74HC595程序
          34. sbit hc595_st_dr=P2^4;
          35. sbit hc595_ds_dr=P2^5;
          36. unsigned char ucKeyStep=1;//按鍵掃描步驟變量
          37. unsigned intuiKeyTimeCnt=0; //按鍵去抖動(dòng)延時(shí)計(jì)數(shù)器
          38. unsigned char ucKeyLock=0; //按鍵觸發(fā)后自鎖的變量標(biāo)志
          39. unsigned char ucRowRecord=1; //記錄當(dāng)前掃描到第幾列了
          40. unsigned char ucKeySec=0; //被觸發(fā)的按鍵編號
          41. unsigned intuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時(shí)間計(jì)數(shù)器
          42. unsigned char ucDigShow8;//第8位數(shù)碼管要顯示的內(nèi)容
          43. unsigned char ucDigShow7;//第7位數(shù)碼管要顯示的內(nèi)容
          44. unsigned char ucDigShow6;//第6位數(shù)碼管要顯示的內(nèi)容
          45. unsigned char ucDigShow5;//第5位數(shù)碼管要顯示的內(nèi)容
          46. unsigned char ucDigShow4;//第4位數(shù)碼管要顯示的內(nèi)容
          47. unsigned char ucDigShow3;//第3位數(shù)碼管要顯示的內(nèi)容
          48. unsigned char ucDigShow2;//第2位數(shù)碼管要顯示的內(nèi)容
          49. unsigned char ucDigShow1;//第1位數(shù)碼管要顯示的內(nèi)容
          50. unsigned char ucDigDot8;//數(shù)碼管8的小數(shù)點(diǎn)是否顯示的標(biāo)志
          51. unsigned char ucDigDot7;//數(shù)碼管7的小數(shù)點(diǎn)是否顯示的標(biāo)志
          52. unsigned char ucDigDot6;//數(shù)碼管6的小數(shù)點(diǎn)是否顯示的標(biāo)志
          53. unsigned char ucDigDot5;//數(shù)碼管5的小數(shù)點(diǎn)是否顯示的標(biāo)志
          54. unsigned char ucDigDot4;//數(shù)碼管4的小數(shù)點(diǎn)是否顯示的標(biāo)志
          55. unsigned char ucDigDot3;//數(shù)碼管3的小數(shù)點(diǎn)是否顯示的標(biāo)志
          56. unsigned char ucDigDot2;//數(shù)碼管2的小數(shù)點(diǎn)是否顯示的標(biāo)志
          57. unsigned char ucDigDot1;//數(shù)碼管1的小數(shù)點(diǎn)是否顯示的標(biāo)志
          58. unsigned char ucDigShowTemp=0; //臨時(shí)中間變量
          59. unsigned char ucDisplayDriveStep=1;//動(dòng)態(tài)掃描數(shù)碼管的步驟變量
          60. unsigned char ucWd1Update=1; //窗口1更新顯示標(biāo)志
          61. unsigned char ucWd2Update=0; //窗口2更新顯示標(biāo)志
          62. unsigned char ucWd3Update=0; //窗口3更新顯示標(biāo)志
          63. unsigned char ucWd=1;//本程序的核心變量,窗口顯示變量。類似于一級菜單的變量。代表顯示不同的窗口。
          64. unsigned char ucInputPassword[4];//在第1個(gè)窗口下,顯示輸入的4個(gè)密碼
          65. unsigned char ucPasswordCnt=0; //記錄當(dāng)前已經(jīng)輸入到哪一位密碼了
          66. unsigned char ucKeyNumber=1;//在第2個(gè)窗口下,顯示當(dāng)前被按下的按鍵
          67. unsigned intuiNoKeyPushTimer=const_no_key_push;//10秒內(nèi)無按鍵按下的計(jì)時(shí)器
          68. unsigned intuiPasswordTimer=const_0_1s;//顯示0.5秒鐘全部密碼的計(jì)時(shí)器,讓窗口3停留顯示0.5秒鐘之后自動(dòng)消失
          69. unsigned char ucTemp1=0;//中間過渡變量
          70. unsigned char ucTemp2=0;//中間過渡變量
          71. unsigned char ucTemp3=0;//中間過渡變量
          72. unsigned char ucTemp4=0;//中間過渡變量
          73. //根據(jù)原理圖得出的共陰數(shù)碼管字模表
          74. code unsigned char dig_table[]=
          75. {
          76. 0x3f,//0 序號0
          77. 0x06,//1 序號1
          78. 0x5b,//2 序號2
          79. 0x4f,//3 序號3
          80. 0x66,//4 序號4
          81. 0x6d,//5 序號5
          82. 0x7d,//6 序號6
          83. 0x07,//7 序號7
          84. 0x7f,//8 序號8
          85. 0x6f,//9 序號9
          86. 0x00,//無 序號10
          87. 0x40,//- 序號11
          88. 0x73,//P 序號12
          89. };
          90. void main()
          91. {
          92. initial_myself();
          93. delay_long(100);
          94. initial_peripheral();
          95. while(1)
          96. {
          97. key_service(); //按鍵服務(wù)的應(yīng)用程序
          98. display_service(); //顯示的窗口菜單服務(wù)程序
          99. }
          100. }
          101. /* 注釋一:
          102. *鴻哥首次提出的"一二級菜單顯示理論":
          103. *凡是人機(jī)界面顯示,不管是數(shù)碼管還是液晶屏,都可以把顯示的內(nèi)容分成不同的窗口來顯示,
          104. *每個(gè)顯示的窗口中又可以分成不同的局部顯示。其中窗口就是一級菜單,用ucWd變量表示。
          105. *局部就是二級菜單,用ucPart來表示。不同的窗口,會(huì)有不同的更新顯示變量ucWdXUpdate來對應(yīng),
          106. *表示整屏全部更新顯示。不同的局部,也會(huì)有不同的更新顯示變量ucWdXPartYUpdate來對應(yīng),表示局部更新顯示。
          107. */
          108. void display_service() //顯示的窗口菜單服務(wù)程序
          109. {
          110. switch(ucWd)//本程序的核心變量,窗口顯示變量。類似于一級菜單的變量。代表顯示不同的窗口。
          111. {
          112. case 1: //顯示輸入密碼的登錄框
          113. if(ucWd1Update==1)//窗口1要全部更新顯示
          114. {
          115. ucWd1Update=0;//及時(shí)清零標(biāo)志,避免一直進(jìn)來掃描
          116. ucDigShow8=10;//第8位數(shù)碼管顯示無
          117. ucDigShow7=10;//第7位數(shù)碼管顯示無
          118. ucDigShow6=10;//第6位數(shù)碼管顯示無
          119. ucDigShow5=10;//第5位數(shù)碼管顯示無
          120. ucDigShow4=ucInputPassword[0];//第4位數(shù)碼管顯示輸入的密碼
          121. ucDigShow3=ucInputPassword[1];//第3位數(shù)碼管顯示輸入的密碼
          122. ucDigShow2=ucInputPassword[2];//第2位數(shù)碼管顯示輸入的密碼
          123. ucDigShow1=ucInputPassword[3];//第1位數(shù)碼管顯示輸入的密碼
          124. }
          125. break;
          126. case 2://顯示被按下的鍵值
          127. if(ucWd2Update==1)//窗口2要全部更新顯示
          128. {
          129. ucWd2Update=0;//及時(shí)清零標(biāo)志,避免一直進(jìn)來掃描
          130. ucDigShow8=10;//第8位數(shù)碼管顯示無
          131. ucDigShow7=10;//第7位數(shù)碼管顯示無
          132. ucDigShow6=10;//第6位數(shù)碼管顯示無
          133. ucDigShow5=10;//第5位數(shù)碼管顯示無
          134. ucDigShow4=10;//第4位數(shù)碼管顯示無
          135. ucDigShow3=10;//第3位數(shù)碼管顯示無
          136. ucDigShow2=10;//第2位數(shù)碼管顯示無
          137. ucDigShow1=ucKeyNumber; //第1位數(shù)碼管顯示被按下的鍵值
          138. }
          139. break;
          140. case 3: //當(dāng)輸入完4個(gè)密碼后,顯示1秒鐘的密碼登錄框,
          141. if(ucWd3Update==1)//窗口3要全部更新顯示
          142. {
          143. ucWd3Update=0;//及時(shí)清零標(biāo)志,避免一直進(jìn)來掃描
          144. ucDigShow8=10;//第8位數(shù)碼管顯示無
          145. ucDigShow7=10;//第7位數(shù)碼管顯示無
          146. ucDigShow6=10;//第6位數(shù)碼管顯示無
          147. ucDigShow5=10;//第5位數(shù)碼管顯示無
          148. ucDigShow4=ucInputPassword[0];//第4位數(shù)碼管顯示輸入的密碼
          149. ucDigShow3=ucInputPassword[1];//第3位數(shù)碼管顯示輸入的密碼
          150. ucDigShow2=ucInputPassword[2];//第2位數(shù)碼管顯示輸入的密碼
          151. ucDigShow1=ucInputPassword[3];//第1位數(shù)碼管顯示輸入的密碼
          152. }
          153. break;
          154. }
          155. }
          156. void key_scan()//按鍵掃描函數(shù) 放在定時(shí)中斷里
          157. {
          158. switch(ucKeyStep)
          159. {
          160. case 1: //按鍵掃描輸出第ucRowRecord列低電平
          161. if(ucRowRecord==1)//第一列輸出低電平
          162. {
          163. key_dr1=0;
          164. key_dr2=1;
          165. key_dr3=1;
          166. key_dr4=1;
          167. }
          168. else if(ucRowRecord==2)//第二列輸出低電平
          169. {
          170. key_dr1=1;
          171. key_dr2=0;
          172. key_dr3=1;
          173. key_dr4=1;
          174. }
          175. else if(ucRowRecord==3)//第三列輸出低電平
          176. {
          177. key_dr1=1;
          178. key_dr2=1;
          179. key_dr3=0;
          180. key_dr4=1;
          181. }
          182. else //第四列輸出低電平
          183. {
          184. key_dr1=1;
          185. key_dr2=1;
          186. key_dr3=1;
          187. key_dr4=0;
          188. }
          189. uiKeyTimeCnt=0;//延時(shí)計(jì)數(shù)器清零
          190. ucKeyStep++; //切換到下一個(gè)運(yùn)行步驟
          191. break;
          192. case 2: //此處的小延時(shí)用來等待剛才列輸出信號穩(wěn)定,再判斷輸入信號。不是去抖動(dòng)延時(shí)。
          193. uiKeyTimeCnt++;
          194. if(uiKeyTimeCnt>1)
          195. {
          196. uiKeyTimeCnt=0;
          197. ucKeyStep++; //切換到下一個(gè)運(yùn)行步驟
          198. }
          199. break;
          200. case 3:
          201. if(key_sr1==1&&key_sr2==1&&key_sr3==1&&key_sr4==1)
          202. {
          203. ucKeyStep=1;//如果沒有按鍵按下,返回到第一個(gè)運(yùn)行步驟重新開始掃描
          204. ucKeyLock=0;//按鍵自鎖標(biāo)志清零
          205. uiKeyTimeCnt=0; //按鍵去抖動(dòng)延時(shí)計(jì)數(shù)器清零,此行非常巧妙
          206. ucRowRecord++;//輸出下一列
          207. if(ucRowRecord>4)
          208. {
          209. ucRowRecord=1; //依次輸出完四列之后,繼續(xù)從第一列開始輸出低電平
          210. }
          211. }
          212. else if(ucKeyLock==0)//有按鍵按下,且是第一次觸發(fā)
          213. {
          214. if(key_sr1==0&&key_sr2==1&&key_sr3==1&&key_sr4==1)
          215. {
          216. uiKeyTimeCnt++;//去抖動(dòng)延時(shí)計(jì)數(shù)器
          217. if(uiKeyTimeCnt>const_key_time)
          218. {
          219. uiKeyTimeCnt=0;
          220. ucKeyLock=1;//自鎖按鍵置位,避免一直觸發(fā),只有松開按鍵,此標(biāo)志位才會(huì)被清零
          221. if(ucRowRecord==1)//第一列輸出低電平
          222. {
          223. ucKeySec=1;//觸發(fā)1號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S1鍵
          224. }
          225. else if(ucRowRecord==2)//第二列輸出低電平
          226. {
          227. ucKeySec=2;//觸發(fā)2號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S2鍵
          228. }
          229. else if(ucRowRecord==3)//第三列輸出低電平
          230. {
          231. ucKeySec=3;//觸發(fā)3號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S3鍵
          232. }
          233. else //第四列輸出低電平
          234. {
          235. ucKeySec=4;//觸發(fā)4號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S4鍵
          236. }
          237. }
          238. }
          239. else if(key_sr1==1&&key_sr2==0&&key_sr3==1&&key_sr4==1)
          240. {
          241. uiKeyTimeCnt++;//去抖動(dòng)延時(shí)計(jì)數(shù)器
          242. if(uiKeyTimeCnt>const_key_time)
          243. {
          244. uiKeyTimeCnt=0;
          245. ucKeyLock=1;//自鎖按鍵置位,避免一直觸發(fā),只有松開按鍵,此標(biāo)志位才會(huì)被清零
          246. if(ucRowRecord==1)//第一列輸出低電平
          247. {
          248. ucKeySec=5;//觸發(fā)5號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S5鍵
          249. }
          250. else if(ucRowRecord==2)//第二列輸出低電平
          251. {
          252. ucKeySec=6;//觸發(fā)6號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S6鍵
          253. }
          254. else if(ucRowRecord==3)//第三列輸出低電平
          255. {
          256. ucKeySec=7;//觸發(fā)7號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S7鍵
          257. }
          258. else //第四列輸出低電平
          259. {
          260. ucKeySec=8;//觸發(fā)8號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S8鍵
          261. }
          262. }
          263. }
          264. else if(key_sr1==1&&key_sr2==1&&key_sr3==0&&key_sr4==1)
          265. {
          266. uiKeyTimeCnt++;//去抖動(dòng)延時(shí)計(jì)數(shù)器
          267. if(uiKeyTimeCnt>const_key_time)
          268. {
          269. uiKeyTimeCnt=0;
          270. ucKeyLock=1;//自鎖按鍵置位,避免一直觸發(fā),只有松開按鍵,此標(biāo)志位才會(huì)被清零
          271. if(ucRowRecord==1)//第一列輸出低電平
          272. {
          273. ucKeySec=9;//觸發(fā)9號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S9鍵
          274. }
          275. else if(ucRowRecord==2)//第二列輸出低電平
          276. {
          277. ucKeySec=10;//觸發(fā)10號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S10鍵
          278. }
          279. else if(ucRowRecord==3)//第三列輸出低電平
          280. {
          281. ucKeySec=11;//觸發(fā)11號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S11鍵
          282. }
          283. else //第四列輸出低電平
          284. {
          285. ucKeySec=12;//觸發(fā)12號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S12鍵
          286. }
          287. }
          288. }
          289. else if(key_sr1==1&&key_sr2==1&&key_sr3==1&&key_sr4==0)
          290. {
          291. uiKeyTimeCnt++;//去抖動(dòng)延時(shí)計(jì)數(shù)器
          292. if(uiKeyTimeCnt>const_key_time)
          293. {
          294. uiKeyTimeCnt=0;
          295. ucKeyLock=1;//自鎖按鍵置位,避免一直觸發(fā),只有松開按鍵,此標(biāo)志位才會(huì)被清零
          296. if(ucRowRecord==1)//第一列輸出低電平
          297. {
          298. ucKeySec=13;//觸發(fā)13號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S13鍵
          299. }
          300. else if(ucRowRecord==2)//第二列輸出低電平
          301. {
          302. ucKeySec=14;//觸發(fā)14號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S14鍵
          303. }
          304. else if(ucRowRecord==3)//第三列輸出低電平
          305. {
          306. ucKeySec=15;//觸發(fā)15號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S15鍵
          307. }
          308. else //第四列輸出低電平
          309. {
          310. ucKeySec=16;//觸發(fā)16號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S16鍵
          311. }
          312. }
          313. }
          314. }
          315. break;
          316. }
          317. }
          318. void key_service() //第三區(qū) 按鍵服務(wù)的應(yīng)用程序
          319. {
          320. switch(ucKeySec) //按鍵服務(wù)狀態(tài)切換
          321. {
          322. case 1:// 1號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S1鍵
          323. number_key_input(1);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          324. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          325. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          326. break;
          327. case 2:// 2號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S2鍵
          328. number_key_input(2);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          329. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          330. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          331. break;
          332. case 3:// 3號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S3鍵
          333. number_key_input(3);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          334. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          335. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          336. break;
          337. case 4:// 4號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S4鍵
          338. number_key_input(4);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          339. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          340. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          341. break;
          342. case 5:// 5號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S5鍵
          343. number_key_input(5);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          344. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          345. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          346. break;
          347. case 6:// 6號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S6鍵
          348. number_key_input(6);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          349. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          350. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          351. break;
          352. case 7:// 7號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S7鍵
          353. number_key_input(7);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          354. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          355. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          356. break;
          357. case 8:// 8號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S8鍵
          358. number_key_input(8);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          359. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          360. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          361. break;
          362. case 9:// 9號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S9鍵
          363. number_key_input(9);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          364. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          365. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          366. break;
          367. case 10:// 把這個(gè)按鍵專門用來輸入數(shù)字0 對應(yīng)朱兆祺學(xué)習(xí)板的S10鍵
          368. number_key_input(0);//由于數(shù)字按鍵的代碼相似度高,因此把具體代碼封裝在這個(gè)函數(shù)里
          369. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          370. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          371. break;
          372. case 11:// 11號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S11鍵
          373. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          374. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          375. break;
          376. case 12:// 12號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S12鍵
          377. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          378. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          379. break;
          380. case 13:// 13號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S13鍵
          381. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          382. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          383. break;
          384. case 14:// 14號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S14鍵
          385. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          386. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          387. break;
          388. case 15:// 15號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S15鍵
          389. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          390. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          391. break;
          392. case 16:// 16號鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S16鍵
          393. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          394. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          395. break;
          396. }
          397. }
          398. void number_key_input(unsigned char ucWhichKey)//由于數(shù)字按鍵的代碼相似度高,因此封裝在這個(gè)函數(shù)里
          399. {
          400. switch(ucWd)
          401. {
          402. case 1: //在顯示密碼登錄框的窗口下
          403. ucInputPassword[ucPasswordCnt]=ucWhichKey; //輸入的密碼值顯示
          404. ucPasswordCnt++;
          405. if(ucPasswordCnt>=4)
          406. {
          407. ucPasswordCnt=0;
          408. ucWd=3;//切換到第3個(gè)的窗口,停留顯示1秒鐘全部密碼
          409. ucWd3Update=1;//更新顯示窗口3
          410. uiPasswordTimer=const_0_1s;//顯示0.5秒鐘全部密碼的計(jì)時(shí)器,讓窗口3停留顯示0.5秒鐘之后自動(dòng)消失
          411. }
          412. ucWd1Update=1; //更新顯示窗口1
          413. uiNoKeyPushTimer=const_no_key_push;//10秒內(nèi)無按鍵按下的計(jì)時(shí)器賦新值
          414. break;
          415. case 2: //在顯示按鍵值的窗口下
          416. ucKeyNumber=ucWhichKey; //輸入的按鍵數(shù)值顯示
          417. ucWd2Update=1;//更新顯示窗口2
          418. uiNoKeyPushTimer=const_no_key_push;//10秒內(nèi)無按鍵按下的計(jì)時(shí)器賦新值
          419. break;
          420. }
          421. }
          422. void display_drive()
          423. {
          424. //以下程序,如果加一些數(shù)組和移位的元素,還可以壓縮容量。但是鴻哥追求的不是容量,而是清晰的講解思路
          425. switch(ucDisplayDriveStep)
          426. {
          427. case 1://顯示第1位
          428. ucDigShowTemp=dig_table[ucDigShow1];
          429. if(ucDigDot1==1)
          430. {
          431. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          432. }
          433. dig_hc595_drive(ucDigShowTemp,0xfe);
          434. break;
          435. case 2://顯示第2位
          436. ucDigShowTemp=dig_table[ucDigShow2];
          437. if(ucDigDot2==1)
          438. {
          439. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          440. }
          441. dig_hc595_drive(ucDigShowTemp,0xfd);
          442. break;
          443. case 3://顯示第3位
          444. ucDigShowTemp=dig_table[ucDigShow3];
          445. if(ucDigDot3==1)
          446. {
          447. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          448. }
          449. dig_hc595_drive(ucDigShowTemp,0xfb);
          450. break;
          451. case 4://顯示第4位
          452. ucDigShowTemp=dig_table[ucDigShow4];
          453. if(ucDigDot4==1)
          454. {
          455. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          456. }
          457. dig_hc595_drive(ucDigShowTemp,0xf7);
          458. break;
          459. case 5://顯示第5位
          460. ucDigShowTemp=dig_table[ucDigShow5];
          461. if(ucDigDot5==1)
          462. {
          463. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          464. }
          465. dig_hc595_drive(ucDigShowTemp,0xef);
          466. break;
          467. case 6://顯示第6位
          468. ucDigShowTemp=dig_table[ucDigShow6];
          469. if(ucDigDot6==1)
          470. {
          471. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          472. }
          473. dig_hc595_drive(ucDigShowTemp,0xdf);
          474. break;
          475. case 7://顯示第7位
          476. ucDigShowTemp=dig_table[ucDigShow7];
          477. if(ucDigDot7==1)
          478. {
          479. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          480. }
          481. dig_hc595_drive(ucDigShowTemp,0xbf);
          482. break;
          483. case 8://顯示第8位
          484. ucDigShowTemp=dig_table[ucDigShow8];
          485. if(ucDigDot8==1)
          486. {
          487. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          488. }
          489. dig_hc595_drive(ucDigShowTemp,0x7f);
          490. break;
          491. }
          492. ucDisplayDriveStep++;
          493. if(ucDisplayDriveStep>8)//掃描完8個(gè)數(shù)碼管后,重新從第一個(gè)開始掃描
          494. {
          495. ucDisplayDriveStep=1;
          496. }
          497. }
          498. //數(shù)碼管的74HC595驅(qū)動(dòng)函數(shù)
          499. void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01)
          500. {
          501. unsigned char i;
          502. unsigned char ucTempData;
          503. dig_hc595_sh_dr=0;
          504. dig_hc595_st_dr=0;
          505. ucTempData=ucDigStatusTemp16_09;//先送高8位
          506. for(i=0;i<8;i++)
          507. {
          508. if(ucTempData>=0x80)dig_hc595_ds_dr=1;
          509. else dig_hc595_ds_dr=0;
          510. dig_hc595_sh_dr=0; //SH引腳的上升沿把數(shù)據(jù)送入寄存器
          511. delay_short(1);
          512. dig_hc595_sh_dr=1;
          513. delay_short(1);
          514. ucTempData=ucTempData<<1;
          515. }
          516. ucTempData=ucDigStatusTemp08_01;//再先送低8位
          517. for(i=0;i<8;i++)
          518. {
          519. if(ucTempData>=0x80)dig_hc595_ds_dr=1;
          520. else dig_hc595_ds_dr=0;
          521. dig_hc595_sh_dr=0; //SH引腳的上升沿把數(shù)據(jù)送入寄存器
          522. delay_short(1);
          523. dig_hc595_sh_dr=1;
          524. delay_short(1);
          525. ucTempData=ucTempData<<1;
          526. }
          527. dig_hc595_st_dr=0;//ST引腳把兩個(gè)寄存器的數(shù)據(jù)更新輸出到74HC595的輸出引腳上并且鎖存起來
          528. delay_short(1);
          529. dig_hc595_st_dr=1;
          530. delay_short(1);
          531. dig_hc595_sh_dr=0; //拉低,抗干擾就增強(qiáng)
          532. dig_hc595_st_dr=0;
          533. dig_hc595_ds_dr=0;
          534. }
          535. //LED燈的74HC595驅(qū)動(dòng)函數(shù)
          536. void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01)
          537. {
          538. unsigned char i;
          539. unsigned char ucTempData;
          540. hc595_sh_dr=0;
          541. hc595_st_dr=0;
          542. ucTempData=ucLedStatusTemp16_09;//先送高8位
          543. for(i=0;i<8;i++)
          544. {
          545. if(ucTempData>=0x80)hc595_ds_dr=1;
          546. else hc595_ds_dr=0;
          547. hc595_sh_dr=0; //SH引腳的上升沿把數(shù)據(jù)送入寄存器
          548. delay_short(1);
          549. hc595_sh_dr=1;
          550. delay_short(1);
          551. ucTempData=ucTempData<<1;
          552. }
          553. ucTempData=ucLedStatusTemp08_01;//再先送低8位
          554. for(i=0;i<8;i++)
          555. {
          556. if(ucTempData>=0x80)hc595_ds_dr=1;
          557. else hc595_ds_dr=0;
          558. hc595_sh_dr=0; //SH引腳的上升沿把數(shù)據(jù)送入寄存器
          559. delay_short(1);
          560. hc595_sh_dr=1;
          561. delay_short(1);
          562. ucTempData=ucTempData<<1;
          563. }
          564. hc595_st_dr=0;//ST引腳把兩個(gè)寄存器的數(shù)據(jù)更新輸出到74HC595的輸出引腳上并且鎖存起來
          565. delay_short(1);
          566. hc595_st_dr=1;
          567. delay_short(1);
          568. hc595_sh_dr=0; //拉低,抗干擾就增強(qiáng)
          569. hc595_st_dr=0;
          570. hc595_ds_dr=0;
          571. }
          572. void T0_time() interrupt 1
          573. {
          574. unsigned int i;
          575. TF0=0;//清除中斷標(biāo)志
          576. TR0=0; //關(guān)中斷
          577. if(ucWd==3)//在窗口3下
          578. {
          579. if(uiPasswordTimer>0)
          580. {
          581. uiPasswordTimer--;
          582. }
          583. if(uiPasswordTimer==0)
          584. {
          585. if(ucInputPassword[0]==9&&ucInputPassword[1]==9&&ucInputPassword[2]==2&&ucInputPassword[3]==2)
          586. { //如果密碼等于9922,則正確
          587. ucWd=2;//切換到第2個(gè)顯示按鍵的窗口
          588. ucWd2Update=1;//更新顯示窗口2
          589. }
          590. else //如果密碼不正確,則繼續(xù)顯示----
          591. {
          592. for(i=0;i<4;i++)
          593. {
          594. ucInputPassword[i]=11;//開機(jī)默認(rèn)密碼全部顯示"----"
          595. }
          596. ucWd=1;
          597. ucWd1Update=1; //更新顯示窗口1
          598. }
          599. }
          600. }
          601. if(ucWd==2)//在窗口2下
          602. {
          603. if(uiNoKeyPushTimer>0)
          604. {
          605. uiNoKeyPushTimer--;
          606. }
          607. if(uiNoKeyPushTimer==0)//如果10秒內(nèi)無按鍵按下,則自動(dòng)切換到顯示密碼登錄框的界面
          608. {
          609. for(i=0;i<4;i++)
          610. {
          611. ucInputPassword[i]=11;//開機(jī)默認(rèn)密碼全部顯示"----"
          612. }
          613. ucWd=1;
          614. ucWd1Update=1; //更新顯示窗口1
          615. }
          616. }
          617. key_scan(); //按鍵掃描函數(shù)
          618. if(uiVoiceCnt!=0)
          619. {
          620. uiVoiceCnt--; //每次進(jìn)入定時(shí)中斷都自減1,直到等于零為止。才停止鳴叫
          621. beep_dr=0;//蜂鳴器是PNP三極管控制,低電平就開始鳴叫。
          622. // beep_dr=1;//蜂鳴器是PNP三極管控制,低電平就開始鳴叫。
          623. }
          624. else
          625. {
          626. ; //此處多加一個(gè)空指令,想維持跟if括號語句的數(shù)量對稱,都是兩條指令。不加也可以。
          627. beep_dr=1;//蜂鳴器是PNP三極管控制,高電平就停止鳴叫。
          628. // beep_dr=0;//蜂鳴器是PNP三極管控制,高電平就停止鳴叫。
          629. }
          630. display_drive();//數(shù)碼管字模的驅(qū)動(dòng)函數(shù)
          631. TH0=0xfe; //重裝初始值(65535-500)=65035=0xfe0b
          632. TL0=0x0b;
          633. TR0=1;//開中斷
          634. }
          635. void delay_short(unsigned int uiDelayShort)
          636. {
          637. unsigned int i;
          638. for(i=0;i
          639. {
          640. ; //一個(gè)分號相當(dāng)于執(zhí)行一條空語句
          641. }
          642. }
          643. void delay_long(unsigned int uiDelayLong)
          644. {
          645. unsigned int i;
          646. unsigned int j;
          647. for(i=0;i
          648. {
          649. for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量
          650. {
          651. ; //一個(gè)分號相當(dāng)于執(zhí)行一條空語句
          652. }
          653. }
          654. }
          655. void initial_myself()//第一區(qū) 初始化單片機(jī)
          656. {
          657. led_dr=0;//關(guān)閉獨(dú)立LED燈
          658. beep_dr=1; //用PNP三極管控制蜂鳴器,輸出高電平時(shí)不叫。
          659. hc595_drive(0x00,0x00);//關(guān)閉所有經(jīng)過另外兩個(gè)74HC595驅(qū)動(dòng)的LED燈
          660. TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1
          661. TH0=0xfe; //重裝初始值(65535-500)=65035=0xfe0b
          662. TL0=0x0b;
          663. }
          664. void initial_peripheral() //第二區(qū) 初始化外圍
          665. {
          666. unsigned int i; //個(gè)人的變量命名習(xí)慣,i,j,k等單個(gè)字母的變量名只用在for循環(huán)里
          667. for(i=0;i<4;i++)
          668. {
          669. ucInputPassword[i]=11;//開機(jī)默認(rèn)密碼全部顯示"----"
          670. }
          671. ucDigDot8=0; //小數(shù)點(diǎn)全部不顯示
          672. ucDigDot7=0;
          673. ucDigDot6=0;
          674. ucDigDot5=0;
          675. ucDigDot4=0;
          676. ucDigDot3=0;
          677. ucDigDot2=0;
          678. ucDigDot1=0;
          679. EA=1; //開總中斷
          680. ET0=1; //允許定時(shí)中斷
          681. TR0=1; //啟動(dòng)定時(shí)中斷
          682. }
          復(fù)制代碼


          總結(jié)陳詞:
          這節(jié)講了iphone4S開機(jī)密碼鎖的程序。2014年春節(jié)的時(shí)候,一幫朋友舉行小規(guī)模的象棋比賽,有一些朋友下棋的速度實(shí)在是太慢了,為了限制比賽時(shí)間,我專門用朱兆祺的51學(xué)習(xí)板做了一個(gè)棋類比賽專用計(jì)時(shí)器給他們用,這個(gè)程序該怎么編寫?欲知詳情,請聽下回分解-----帶數(shù)碼管顯示的象棋比賽專用計(jì)時(shí)器。


          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();