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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 第88節(jié):?jiǎn)纹瑱C(jī)靠關(guān)鍵字快速截取有效數(shù)據(jù)串

          第88節(jié):?jiǎn)纹瑱C(jī)靠關(guān)鍵字快速截取有效數(shù)據(jù)串

          作者: 時(shí)間:2016-11-22 來(lái)源:網(wǎng)絡(luò) 收藏
          開(kāi)場(chǎng)白:
          我前面串口程序大部分都是通過(guò)靠時(shí)間來(lái)識(shí)別每一串?dāng)?shù)據(jù)是否接收完畢,有一些串口項(xiàng)目的協(xié)議是固定不變的,而且也不需要從機(jī)反饋任何應(yīng)答信號(hào),這類項(xiàng)目只需根據(jù)特定關(guān)鍵字來(lái)快速識(shí)別數(shù)據(jù)串是否接收完畢即可。比如現(xiàn)在有一種電子稱,它的測(cè)量范圍是0.00克到500.00克,他是靠串口不斷對(duì)外發(fā)送當(dāng)前重量數(shù)據(jù)的,每串?dāng)?shù)據(jù)固定長(zhǎng)度26個(gè)字節(jié),最后兩個(gè)字節(jié)是回車換行符0x0d 0x0a,倒數(shù)第9,10,11,12,13,14為有效的ASCII碼數(shù)字,其中倒數(shù)第11位為固定的小數(shù)點(diǎn),其它的數(shù)據(jù)可以忽略不計(jì)。這類串口框架的思路是:根據(jù)數(shù)據(jù)尾是否有0x0d 0x0a來(lái)判斷數(shù)據(jù)串是否有效的,一旦發(fā)現(xiàn)有此關(guān)鍵字,再判斷總的數(shù)據(jù)長(zhǎng)度是否等于或者大于一串?dāng)?shù)據(jù)的固定長(zhǎng)度,如果滿足,則把相關(guān)標(biāo)志位置位,通知主函數(shù)中的串口服務(wù)程序進(jìn)行處理。同時(shí)也及時(shí)關(guān)閉串口中斷,避免在處理串口數(shù)據(jù)期間受到串口數(shù)據(jù)的中斷干擾,等串口服務(wù)程序處理完畢再打開(kāi)。
          具體內(nèi)容,請(qǐng)看源代碼講解。
          (1) 硬件平臺(tái):
          基于朱兆祺51單片機(jī)學(xué)習(xí)板。
          (2) 實(shí)現(xiàn)功能:
          波特率是:9600。把當(dāng)前電子稱的重量數(shù)據(jù)顯示在數(shù)碼管上,在電腦上用串口助手軟件來(lái)模擬電子稱發(fā)送以下格式協(xié)議的3串?dāng)?shù)據(jù),它的協(xié)議很簡(jiǎn)單,每串?dāng)?shù)據(jù)固定長(zhǎng)度26個(gè)字節(jié),最后兩個(gè)字節(jié)是回車換行符0x0d 0x0a,倒數(shù)第9,10,11,12,13,14為有效的ASCII碼數(shù)字,其中倒數(shù)第11位為固定的小數(shù)點(diǎn),其它的數(shù)據(jù)可以忽略不計(jì)。
          (a)字符是:
          ST,GS,+ 0.77 g
          轉(zhuǎn)換成16進(jìn)制是:
          20 53 54 2C 47 53 2C 2B 20 20 20 20 20 20 30 2E 37 37 20 2020 20 20 67 0D 0A
          數(shù)碼管顯示:0.77
          (b)
          字符是:
          ST,GS,+ 136.39 g
          轉(zhuǎn)換成16進(jìn)制是:
          20 53 54 2C 47 53 2C 2B 20 20 20 20 31 33 36 2E 33 39 20 2020 20 20 67 0D 0A
          數(shù)碼管顯示:136.39
          (c)
          字符是:
          ST,GS,+ 0.00 g
          轉(zhuǎn)換成16進(jìn)制是:
          20 53 54 2C 47 53 2C 2B 20 20 20 20 20 20 30 2E 30 30 20 2020 20 20 67 0D 0A
          數(shù)碼管顯示:0.00

          (3)源代碼講解如下:
          1. #include "REG52.H"
          2. #define const_rc_size36//接收串口中斷數(shù)據(jù)的緩沖區(qū)數(shù)組大小
          3. #define const_least_size 26 //一串標(biāo)準(zhǔn)數(shù)據(jù)的大小
          4. void initial_myself();
          5. void initial_peripheral();
          6. void delay_short(unsigned int uiDelayShort);
          7. void delay_long(unsigned int uiDelaylong);
          8. //驅(qū)動(dòng)數(shù)碼管的74HC595
          9. void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01);
          10. void display_drive(); //顯示數(shù)碼管字模的驅(qū)動(dòng)函數(shù)
          11. void display_service(); //顯示的窗口菜單服務(wù)程序
          12. //驅(qū)動(dòng)LED的74HC595
          13. void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01);
          14. void usart_service(void);//串口接收服務(wù)程序,在main函數(shù)里
          15. void usart_receive(void); //串口接收中斷函數(shù)
          16. void T0_time();//定時(shí)中斷函數(shù)
          17. sbit dig_hc595_sh_dr=P2^0; //數(shù)碼管的74HC595程序
          18. sbit dig_hc595_st_dr=P2^1;
          19. sbit dig_hc595_ds_dr=P2^2;
          20. sbit hc595_sh_dr=P2^3; //LED燈的74HC595程序
          21. sbit hc595_st_dr=P2^4;
          22. sbit hc595_ds_dr=P2^5;
          23. sbit beep_dr=P2^7; //蜂鳴器的驅(qū)動(dòng)IO口
          24. sbit led_dr=P3^5;//獨(dú)立LED燈
          25. //根據(jù)原理圖得出的共陰數(shù)碼管字模表
          26. code unsigned char dig_table[]=
          27. {
          28. 0x3f,//0 序號(hào)0
          29. 0x06,//1 序號(hào)1
          30. 0x5b,//2 序號(hào)2
          31. 0x4f,//3 序號(hào)3
          32. 0x66,//4 序號(hào)4
          33. 0x6d,//5 序號(hào)5
          34. 0x7d,//6 序號(hào)6
          35. 0x07,//7 序號(hào)7
          36. 0x7f,//8 序號(hào)8
          37. 0x6f,//9 序號(hào)9
          38. 0x00,//無(wú) 序號(hào)10
          39. 0x40,//- 序號(hào)11
          40. 0x73,//P 序號(hào)12
          41. };
          42. unsigned intuiRcregTotal=0;//代表當(dāng)前緩沖區(qū)已經(jīng)接收了多少個(gè)數(shù)據(jù)
          43. unsigned intuiRcregTotalTemp=0;//代表當(dāng)前緩沖區(qū)已經(jīng)接收了多少個(gè)數(shù)據(jù)的中間變量
          44. unsigned char ucRcregBuf[const_rc_size]; //接收串口中斷數(shù)據(jù)的緩沖區(qū)數(shù)組
          45. unsigned char ucReceiveFlag=0; //接收成功標(biāo)志
          46. unsigned char ucDigShow8;//第8位數(shù)碼管要顯示的內(nèi)容
          47. unsigned char ucDigShow7;//第7位數(shù)碼管要顯示的內(nèi)容
          48. unsigned char ucDigShow6;//第6位數(shù)碼管要顯示的內(nèi)容
          49. unsigned char ucDigShow5;//第5位數(shù)碼管要顯示的內(nèi)容
          50. unsigned char ucDigShow4;//第4位數(shù)碼管要顯示的內(nèi)容
          51. unsigned char ucDigShow3;//第3位數(shù)碼管要顯示的內(nèi)容
          52. unsigned char ucDigShow2;//第2位數(shù)碼管要顯示的內(nèi)容
          53. unsigned char ucDigShow1;//第1位數(shù)碼管要顯示的內(nèi)容
          54. unsigned char ucDigDot8;//數(shù)碼管8的小數(shù)點(diǎn)是否顯示的標(biāo)志
          55. unsigned char ucDigDot7;//數(shù)碼管7的小數(shù)點(diǎn)是否顯示的標(biāo)志
          56. unsigned char ucDigDot6;//數(shù)碼管6的小數(shù)點(diǎn)是否顯示的標(biāo)志
          57. unsigned char ucDigDot5;//數(shù)碼管5的小數(shù)點(diǎn)是否顯示的標(biāo)志
          58. unsigned char ucDigDot4;//數(shù)碼管4的小數(shù)點(diǎn)是否顯示的標(biāo)志
          59. unsigned char ucDigDot3;//數(shù)碼管3的小數(shù)點(diǎn)是否顯示的標(biāo)志
          60. unsigned char ucDigDot2;//數(shù)碼管2的小數(shù)點(diǎn)是否顯示的標(biāo)志
          61. unsigned char ucDigDot1;//數(shù)碼管1的小數(shù)點(diǎn)是否顯示的標(biāo)志
          62. unsigned char ucDigShowTemp=0; //臨時(shí)中間變量
          63. unsigned char ucDisplayDriveStep=1;//動(dòng)態(tài)掃描數(shù)碼管的步驟變量
          64. unsigned char ucWd1Part1Update=1; //8位數(shù)碼管更新顯示標(biāo)志
          65. unsigned long ulWeightCurrent=12345; //顯示當(dāng)前實(shí)際的重量
          66. void main()
          67. {
          68. initial_myself();
          69. delay_long(100);
          70. initial_peripheral();
          71. while(1)
          72. {
          73. usart_service();//串口接收服務(wù)程序
          74. display_service(); //顯示的窗口菜單服務(wù)程序
          75. }
          76. }
          77. /* 注釋一:
          78. * 本節(jié)內(nèi)容處理串口數(shù)據(jù)是根據(jù)數(shù)據(jù)尾是否有0x0d 0x0a來(lái)判斷數(shù)據(jù)串是否有效的,一旦發(fā)現(xiàn)有此關(guān)鍵字,
          79. * 再判斷總的數(shù)據(jù)長(zhǎng)度是否等于或者大于一串?dāng)?shù)據(jù)的固定長(zhǎng)度,如果滿足,則把相關(guān)標(biāo)志位置位,通知主函數(shù)中
          80. * 的串口服務(wù)程序進(jìn)行處理。同時(shí)也及時(shí)關(guān)閉串口中斷,避免在處理串口數(shù)據(jù)期間受到串口數(shù)據(jù)的中斷干擾,
          81. * 等串口服務(wù)程序處理完畢再打開(kāi)。
          82. */
          83. void usart_receive(void) interrupt 4 //串口接收數(shù)據(jù)中斷函數(shù)
          84. {
          85. if(RI==1)
          86. {
          87. RI = 0;
          88. ++uiRcregTotal;
          89. ucRcregBuf[uiRcregTotal-1]=SBUF; //將串口接收到的數(shù)據(jù)緩存到接收緩沖區(qū)里
          90. if(uiRcregTotal>=2&&ucRcregBuf[uiRcregTotal-2]==0x0d&&ucRcregBuf[uiRcregTotal-1]==0x0a)//一旦發(fā)現(xiàn)后綴是0x0d 0x0a關(guān)鍵字的就進(jìn)去處理判斷
          91. {
          92. if(uiRcregTotal
          93. {
          94. uiRcregTotal=0;
          95. }
          96. else
          97. {
          98. uiRcregTotalTemp=uiRcregTotal; //把接收到的總數(shù)據(jù)傳遞給一個(gè)中間變量,在主函數(shù)那邊處理這個(gè)中間變量
          99. ucReceiveFlag=1; //通知主程序接收成功
          100. ES=0; // 禁止接收中斷,等主函數(shù)處理完接收的數(shù)據(jù)后再打開(kāi)串口中斷,避免在處理串口數(shù)據(jù)期間受到串口數(shù)據(jù)的中斷干擾。
          101. }
          102. }
          103. else if(uiRcregTotal>=const_rc_size)//超過(guò)緩沖區(qū)
          104. {
          105. uiRcregTotal=0;
          106. }
          107. }
          108. else //如果不是串口接收中斷,那么必然是串口發(fā)送中斷,及時(shí)清除發(fā)送中斷的標(biāo)志,否則一直發(fā)送中斷
          109. {
          110. TI = 0;
          111. }
          112. }
          113. void usart_service(void)//串口接收服務(wù)程序,在main函數(shù)里
          114. {
          115. //加了static關(guān)鍵字后,此局部變量不會(huì)每次進(jìn)來(lái)函數(shù)都初始化一次,這樣有可能減少了一點(diǎn)指令消耗的時(shí)間。
          116. static unsigned long ulReceiveData10000; //定義成long類型,是為了方便后面換算的乘法運(yùn)算,讓它不會(huì)溢出而出錯(cuò)。
          117. static unsigned long ulReceiveData1000;
          118. static unsigned long ulReceiveData100;
          119. static unsigned long ulReceiveData10;
          120. static unsigned long ulReceiveData1;
          121. if(ucReceiveFlag==1)//說(shuō)明有數(shù)據(jù)接收成功,進(jìn)入數(shù)據(jù)處理分析
          122. {
          123. ulReceiveData10000=0;
          124. ulReceiveData1000=0;
          125. ulReceiveData100=0;
          126. ulReceiveData10=0;
          127. ulReceiveData1=0;
          128. /* 注釋二:
          129. * 根據(jù)協(xié)議,倒數(shù)第9,10,11,12,13,14為有效的ASCII碼數(shù)字,其中倒數(shù)第11位為固定的小數(shù)點(diǎn),因此省略不寫(xiě)。
          130. */
          131. if(ucRcregBuf[uiRcregTotalTemp-9]>=0x30)
          132. {
          133. ulReceiveData1=ucRcregBuf[uiRcregTotalTemp-9]-0x30; //接收到的ASCII碼數(shù)字減去0x30變成實(shí)際數(shù)值.
          134. }
          135. if(ucRcregBuf[uiRcregTotalTemp-10]>=0x30)
          136. {
          137. ulReceiveData10=ucRcregBuf[uiRcregTotalTemp-10]-0x30;
          138. ulReceiveData10=ulReceiveData10*10;
          139. }
          140. if(ucRcregBuf[uiRcregTotalTemp-12]>=0x30)
          141. {
          142. ulReceiveData100=ucRcregBuf[uiRcregTotalTemp-12]-0x30;
          143. ulReceiveData100=ulReceiveData100*100;
          144. }
          145. if(ucRcregBuf[uiRcregTotalTemp-13]>=0x30)
          146. {
          147. ulReceiveData1000=ucRcregBuf[uiRcregTotalTemp-13]-0x30;
          148. ulReceiveData1000=ulReceiveData1000*1000;
          149. }
          150. if(ucRcregBuf[uiRcregTotalTemp-14]>=0x30)
          151. {
          152. ulReceiveData10000=ucRcregBuf[uiRcregTotalTemp-14]-0x30;
          153. ulReceiveData10000=ulReceiveData10000*10000;
          154. }
          155. ulWeightCurrent=ulReceiveData10000+ulReceiveData1000+ulReceiveData100+ulReceiveData10+ulReceiveData1;
          156. ucWd1Part1Update=1; //更新顯示
          157. uiRcregTotalTemp=0;//清零實(shí)際接收到的字節(jié)數(shù)的中間變量
          158. uiRcregTotal=0;//清零實(shí)際接收到的字節(jié)數(shù)
          159. ucReceiveFlag=0;//清零完成標(biāo)志
          160. ES = 1; // 允許接收中斷
          161. }
          162. }
          163. void display_service() //顯示的窗口菜單服務(wù)程序
          164. {
          165. //加了static關(guān)鍵字后,此局部變量不會(huì)每次進(jìn)來(lái)函數(shù)都初始化一次,這樣有可能減少了一點(diǎn)指令消耗的時(shí)間。
          166. static unsigned char ucTemp5; //中間過(guò)渡變量
          167. static unsigned char ucTemp4; //中間過(guò)渡變量
          168. static unsigned char ucTemp3; //中間過(guò)渡變量
          169. static unsigned char ucTemp2; //中間過(guò)渡變量
          170. static unsigned char ucTemp1; //中間過(guò)渡變量
          171. if(ucWd1Part1Update==1)//更新顯示
          172. {
          173. ucWd1Part1Update=0;//及時(shí)清零標(biāo)志,避免一直進(jìn)來(lái)掃描
          174. //先分解數(shù)據(jù)用來(lái)顯示每一位
          175. ucTemp5=ulWeightCurrent%100000/10000;
          176. ucTemp4=ulWeightCurrent%10000/1000;
          177. ucTemp3=ulWeightCurrent%1000/100;
          178. ucTemp2=ulWeightCurrent%100/10;
          179. ucTemp1=ulWeightCurrent%10;
          180. ucDigDot3=1;//顯示第3位數(shù)碼管的小數(shù)點(diǎn),實(shí)際數(shù)據(jù)帶2位小數(shù)點(diǎn)。
          181. ucDigShow8=10;//沒(méi)有用到第8位數(shù)碼管,因此顯示無(wú)。10代表顯示空。
          182. ucDigShow7=10;//沒(méi)有用到第7位數(shù)碼管,因此顯示無(wú)。10代表顯示空。
          183. ucDigShow6=10;//沒(méi)有用到第6位數(shù)碼管,因此顯示無(wú)。10代表顯示空。
          184. if(ulWeightCurrent<10000)
          185. {
          186. ucDigShow5=10;//如果小于1000,千位顯示無(wú)
          187. }
          188. else
          189. {
          190. ucDigShow5=ucTemp5;//第5位數(shù)碼管要顯示的內(nèi)容
          191. }
          192. if(ulWeightCurrent<1000)
          193. {
          194. ucDigShow4=10;//如果小于1000,千位顯示無(wú)
          195. }
          196. else
          197. {
          198. ucDigShow4=ucTemp4;//第4位數(shù)碼管要顯示的內(nèi)容
          199. }
          200. //因?yàn)閹?位小數(shù)點(diǎn),因此最前面3位數(shù)據(jù)都是有效數(shù),必然要顯示,不要判斷去0的空顯示處理。
          201. ucDigShow3=ucTemp3;//第3位數(shù)碼管要顯示的內(nèi)容
          202. ucDigShow2=ucTemp2;//第2位數(shù)碼管要顯示的內(nèi)容
          203. ucDigShow1=ucTemp1;//第1位數(shù)碼管要顯示的內(nèi)容
          204. }
          205. }
          206. void display_drive()
          207. {
          208. //以下程序,如果加一些數(shù)組和移位的元素,還可以壓縮容量。但是鴻哥追求的不是容量,而是清晰的講解思路
          209. switch(ucDisplayDriveStep)
          210. {
          211. case 1://顯示第1位
          212. ucDigShowTemp=dig_table[ucDigShow1];
          213. if(ucDigDot1==1)
          214. {
          215. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          216. }
          217. dig_hc595_drive(ucDigShowTemp,0xfe);
          218. break;
          219. case 2://顯示第2位
          220. ucDigShowTemp=dig_table[ucDigShow2];
          221. if(ucDigDot2==1)
          222. {
          223. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          224. }
          225. dig_hc595_drive(ucDigShowTemp,0xfd);
          226. break;
          227. case 3://顯示第3位
          228. ucDigShowTemp=dig_table[ucDigShow3];
          229. if(ucDigDot3==1)
          230. {
          231. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          232. }
          233. dig_hc595_drive(ucDigShowTemp,0xfb);
          234. break;
          235. case 4://顯示第4位
          236. ucDigShowTemp=dig_table[ucDigShow4];
          237. if(ucDigDot4==1)
          238. {
          239. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          240. }
          241. dig_hc595_drive(ucDigShowTemp,0xf7);
          242. break;
          243. case 5://顯示第5位
          244. ucDigShowTemp=dig_table[ucDigShow5];
          245. if(ucDigDot5==1)
          246. {
          247. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          248. }
          249. dig_hc595_drive(ucDigShowTemp,0xef);
          250. break;
          251. case 6://顯示第6位
          252. ucDigShowTemp=dig_table[ucDigShow6];
          253. if(ucDigDot6==1)
          254. {
          255. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          256. }
          257. dig_hc595_drive(ucDigShowTemp,0xdf);
          258. break;
          259. case 7://顯示第7位
          260. ucDigShowTemp=dig_table[ucDigShow7];
          261. if(ucDigDot7==1)
          262. {
          263. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          264. }
          265. dig_hc595_drive(ucDigShowTemp,0xbf);
          266. break;
          267. case 8://顯示第8位
          268. ucDigShowTemp=dig_table[ucDigShow8];
          269. if(ucDigDot8==1)
          270. {
          271. ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)
          272. }
          273. dig_hc595_drive(ucDigShowTemp,0x7f);
          274. break;
          275. }
          276. ucDisplayDriveStep++;
          277. if(ucDisplayDriveStep>8)//掃描完8個(gè)數(shù)碼管后,重新從第一個(gè)開(kāi)始掃描
          278. {
          279. ucDisplayDriveStep=1;
          280. }
          281. }
          282. //數(shù)碼管的74HC595驅(qū)動(dòng)函數(shù)
          283. void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01)
          284. {
          285. unsigned char i;
          286. unsigned char ucTempData;
          287. dig_hc595_sh_dr=0;
          288. dig_hc595_st_dr=0;
          289. ucTempData=ucDigStatusTemp16_09;//先送高8位
          290. for(i=0;i<8;i++)
          291. {
          292. if(ucTempData>=0x80)dig_hc595_ds_dr=1;
          293. else dig_hc595_ds_dr=0;
          294. dig_hc595_sh_dr=0; //SH引腳的上升沿把數(shù)據(jù)送入寄存器
          295. delay_short(1);
          296. dig_hc595_sh_dr=1;
          297. delay_short(1);
          298. ucTempData=ucTempData<<1;
          299. }
          300. ucTempData=ucDigStatusTemp08_01;//再先送低8位
          301. for(i=0;i<8;i++)
          302. {
          303. if(ucTempData>=0x80)dig_hc595_ds_dr=1;
          304. else dig_hc595_ds_dr=0;
          305. dig_hc595_sh_dr=0; //SH引腳的上升沿把數(shù)據(jù)送入寄存器
          306. delay_short(1);
          307. dig_hc595_sh_dr=1;
          308. delay_short(1);
          309. ucTempData=ucTempData<<1;
          310. }
          311. dig_hc595_st_dr=0;//ST引腳把兩個(gè)寄存器的數(shù)據(jù)更新輸出到74HC595的輸出引腳上并且鎖存起來(lái)
          312. delay_short(1);
          313. dig_hc595_st_dr=1;
          314. delay_short(1);
          315. dig_hc595_sh_dr=0; //拉低,抗干擾就增強(qiáng)
          316. dig_hc595_st_dr=0;
          317. dig_hc595_ds_dr=0;
          318. }
          319. //LED燈的74HC595驅(qū)動(dòng)函數(shù)
          320. void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01)
          321. {
          322. unsigned char i;
          323. unsigned char ucTempData;
          324. hc595_sh_dr=0;
          325. hc595_st_dr=0;
          326. ucTempData=ucLedStatusTemp16_09;//先送高8位
          327. for(i=0;i<8;i++)
          328. {
          329. if(ucTempData>=0x80)hc595_ds_dr=1;
          330. else hc595_ds_dr=0;
          331. hc595_sh_dr=0; //SH引腳的上升沿把數(shù)據(jù)送入寄存器
          332. delay_short(1);
          333. hc595_sh_dr=1;
          334. delay_short(1);
          335. ucTempData=ucTempData<<1;
          336. }
          337. ucTempData=ucLedStatusTemp08_01;//再先送低8位
          338. for(i=0;i<8;i++)
          339. {
          340. if(ucTempData>=0x80)hc595_ds_dr=1;
          341. else hc595_ds_dr=0;
          342. hc595_sh_dr=0; //SH引腳的上升沿把數(shù)據(jù)送入寄存器
          343. delay_short(1);
          344. hc595_sh_dr=1;
          345. delay_short(1);
          346. ucTempData=ucTempData<<1;
          347. }
          348. hc595_st_dr=0;//ST引腳把兩個(gè)寄存器的數(shù)據(jù)更新輸出到74HC595的輸出引腳上并且鎖存起來(lái)
          349. delay_short(1);
          350. hc595_st_dr=1;
          351. delay_short(1);
          352. hc595_sh_dr=0; //拉低,抗干擾就增強(qiáng)
          353. hc595_st_dr=0;
          354. hc595_ds_dr=0;
          355. }
          356. void T0_time() interrupt 1
          357. {
          358. TF0=0;//清除中斷標(biāo)志
          359. TR0=0; //關(guān)中斷
          360. display_drive();//數(shù)碼管字模的驅(qū)動(dòng)函數(shù)
          361. TH0=0xfe; //重裝初始值(65535-500)=65035=0xfe0b
          362. TL0=0x0b;
          363. TR0=1;//開(kāi)中斷
          364. }
          365. void delay_short(unsigned int uiDelayShort)
          366. {
          367. unsigned int i;
          368. for(i=0;i
          369. {
          370. ; //一個(gè)分號(hào)相當(dāng)于執(zhí)行一條空語(yǔ)句
          371. }
          372. }
          373. void delay_long(unsigned int uiDelayLong)
          374. {
          375. unsigned int i;
          376. unsigned int j;
          377. for(i=0;i
          378. {
          379. for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量
          380. {
          381. ; //一個(gè)分號(hào)相當(dāng)于執(zhí)行一條空語(yǔ)句
          382. }
          383. }
          384. }
          385. void initial_myself()//第一區(qū) 初始化單片機(jī)
          386. {
          387. beep_dr=1; //用PNP三極管控制蜂鳴器,輸出高電平時(shí)不叫。
          388. led_dr=0;//關(guān)閉獨(dú)立LED燈
          389. hc595_drive(0x00,0x00);//關(guān)閉所有經(jīng)過(guò)另外兩個(gè)74HC595驅(qū)動(dòng)的LED燈
          390. TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1
          391. TH0=0xfe; //重裝初始值(65535-500)=65035=0xfe0b
          392. TL0=0x0b;
          393. //配置串口
          394. SCON=0x50;
          395. TMOD=0X21;
          396. /* 注釋三:
          397. * 為了保證串口中斷接收的數(shù)據(jù)不丟失,必須設(shè)置IP = 0x10,相當(dāng)于把串口中斷設(shè)置為最高優(yōu)先級(jí),
          398. * 這個(gè)時(shí)候,串口中斷可以打斷任何其他的中斷服務(wù)函數(shù)實(shí)現(xiàn)嵌套,
          399. */
          400. IP =0x10;//把串口中斷設(shè)置為最高優(yōu)先級(jí),必須的。
          401. TH1=TL1=-(11059200L/12/32/9600);//串口波特率為9600。
          402. TR1=1;
          403. }
          404. void initial_peripheral() //第二區(qū) 初始化外圍
          405. {
          406. ucDigDot8=0; //初始化小數(shù)點(diǎn)全部不顯示
          407. ucDigDot7=0;
          408. ucDigDot6=0;
          409. ucDigDot5=0;
          410. ucDigDot4=0;
          411. ucDigDot3=0;
          412. ucDigDot2=0;
          413. ucDigDot1=0;
          414. EA=1; //開(kāi)總中斷
          415. ES=1; //允許串口中斷
          416. ET0=1; //允許定時(shí)中斷
          417. TR0=1; //啟動(dòng)定時(shí)中斷
          418. }
          總結(jié)陳詞:
          前面我在第48節(jié)里講過(guò)用ds1302做的時(shí)鐘程序,但是后來(lái)很多網(wǎng)友建議,為了方便初學(xué)者學(xué)習(xí)編程思路,我應(yīng)該用單片機(jī)定時(shí)器做一個(gè)時(shí)鐘程序。因此,我決定下一節(jié)講這方面的內(nèi)容。欲知詳情,請(qǐng)聽(tīng)下回分解----用單片機(jī)內(nèi)部定時(shí)器做一個(gè)時(shí)鐘。


          評(píng)論


          技術(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); })();