在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            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),這類(lèi)項(xiàng)目只需根據(jù)特定關(guān)鍵字來(lái)快速識(shí)別數(shù)據(jù)串是否接收完畢即可。比如現(xiàn)在有一種電子稱(chēng),它的測(cè)量范圍是0.00克到500.00克,他是靠串口不斷對(duì)外發(fā)送當(dāng)前重量數(shù)據(jù)的,每串?dāng)?shù)據(jù)固定長(zhǎng)度26個(gè)字節(jié),最后兩個(gè)字節(jié)是回車(chē)換行符0x0d 0x0a,倒數(shù)第9,10,11,12,13,14為有效的ASCII碼數(shù)字,其中倒數(shù)第11位為固定的小數(shù)點(diǎn),其它的數(shù)據(jù)可以忽略不計(jì)。這類(lèi)串口框架的思路是:根據(jù)數(shù)據(jù)尾是否有0x0d 0x0a來(lái)判斷數(shù)據(jù)串是否有效的,一旦發(fā)現(xiàn)有此關(guān)鍵字,再判斷總的數(shù)據(jù)長(zhǎng)度是否等于或者大于一串?dāng)?shù)據(jù)的固定長(zhǎng)度,如果滿(mǎn)足,則把相關(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)前電子稱(chēng)的重量數(shù)據(jù)顯示在數(shù)碼管上,在電腦上用串口助手軟件來(lái)模擬電子稱(chēng)發(fā)送以下格式協(xié)議的3串?dāng)?shù)據(jù),它的協(xié)議很簡(jiǎn)單,每串?dāng)?shù)據(jù)固定長(zhǎng)度26個(gè)字節(jié),最后兩個(gè)字節(jié)是回車(chē)換行符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)度,如果滿(mǎn)足,則把相關(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類(lèi)型,是為了方便后面換算的乘法運(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ù)專(zhuān)區(qū)

            關(guān)閉