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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 使用Msp430的串口中斷接收一包數(shù)據(jù)

          使用Msp430的串口中斷接收一包數(shù)據(jù)

          作者: 時(shí)間:2016-11-13 來(lái)源:網(wǎng)絡(luò) 收藏
          假設(shè)有一數(shù)據(jù)包,數(shù)據(jù)格式如表所示:

          本文引用地址:http://www.ex-cimer.com/article/201611/316517.htm

          序號(hào)

          項(xiàng) 目

          長(zhǎng)度(字節(jié))

          說(shuō)明

          1

          數(shù)據(jù)包頭(STX)

          1

          常量:0x02

          2

          數(shù)據(jù)單元長(zhǎng)度(Data_len)

          2

          需傳輸?shù)臄?shù)據(jù)單元Data部分的長(zhǎng)度,高字節(jié)在前,低字節(jié)在后。

          例如:0x0010表示Data部分有16個(gè)字節(jié)。

          3

          需傳輸?shù)臄?shù)據(jù)單元(Data)

          不定

          長(zhǎng)度由Data_len指出,數(shù)據(jù)單元頭兩個(gè)字節(jié)是命令碼(終端發(fā)送命令到讀寫器)或狀態(tài)碼(讀寫器返回?cái)?shù)據(jù)給終端),后面是其它參數(shù)。

          4

          冗余檢驗(yàn)值(LRC)

          1

          Data部分?jǐn)?shù)據(jù)各字節(jié)異或值。

          5

          數(shù)據(jù)包尾(ETX)

          1

          常量:0x03

          數(shù)據(jù)包總長(zhǎng)度為: Data_len + 5 字節(jié),最長(zhǎng)不能超過(guò)512字節(jié)。

          程序?qū)崿F(xiàn)如下所示:

          [cpp]view plaincopyprint?
          1. #include
          2. typedefstructnewStruct
          3. {
          4. unsignedcharstartFlag;
          5. unsignedcharfinishFlag;
          6. unsignedcharlenHighFlag;
          7. unsignedcharlenLowFlag;
          8. unsignedchardataFlag;
          9. unsignedcharlrcFlag;
          10. unsignedcharbuf[512];
          11. unsignedcharlenHigh;
          12. unsignedcharlenLow;
          13. unsignedchardataStartIndex;
          14. unsignedshortlen;
          15. unsignedshortindex;
          16. unsignedshorttempLen;
          17. }rxstruct;
          18. rxstructrxArray;
          19. voidm430_InitUart()
          20. {
          21. P3SEL|=BIT4|BIT5;//P3.4,P3.5=USCI_A0TXD/RXD
          22. UCA0CTL1|=UCSSEL_2;//SMCLK
          23. //以下三行為波特率設(shè)置使用
          24. UCA0BR1=0;
          25. UCA0BR0=104;//12MHz:1250->9600,625->19200,312->38400,214->56000,104->115200
          26. UCA0MCTL=0x02;//ModulationUCBRSx=1
          27. UCA0CTL1&=~UCSWRST;//InitializeUSCIstatemachine
          28. //IE2|=UCA0RXIE|UCA0TXIE;//注意應(yīng)在初始化USCI之后,設(shè)置中斷使能,否則不起作用,即若此句放在UCA0CTL1&=~UCSWRST;之前,則不會(huì)響應(yīng)中斷
          29. IE2|=UCA0RXIE;
          30. }
          31. unsignedcharuart_CalLrc(unsignedchar*buf,unsignedshortlen)
          32. {
          33. unsignedshorti;
          34. unsignedcharlrc;
          35. lrc=0x00;
          36. for(i=0;i
          37. {
          38. lrc^=buf[i];
          39. }
          40. returnlrc;
          41. }
          42. voidmain()
          43. {
          44. WDTCTL=WDTPW+WDTHOLD;
          45. BCSCTL1=CALBC1_12MHZ;
          46. DCOCTL=CALDCO_12MHZ;
          47. m430_InitUart();
          48. rxArray.startFlag=0;
          49. rxArray.finishFlag=0;
          50. _EINT();
          51. _BIS_SR(LPM4_bits);
          52. while(1)
          53. {
          54. }
          55. }
          56. #pragmavector=USCIAB0RX_VECTOR
          57. __interruptvoiduartRxHandle()
          58. {
          59. unsignedcharnum;
          60. num=UCA0RXBUF;
          61. if(0==rxArray.startFlag)//判斷是否接收到幀頭
          62. {
          63. if(0x02==num)//判斷幀頭是否正確
          64. {
          65. rxArray.startFlag=1;//標(biāo)志已經(jīng)接收到幀頭
          66. rxArray.finishFlag=0;
          67. rxArray.lenHighFlag=0;
          68. rxArray.lenLowFlag=0;
          69. rxArray.dataFlag=0;
          70. rxArray.lrcFlag=0;
          71. rxArray.index=0;
          72. rxArray.len=0;//存儲(chǔ)幀長(zhǎng)度
          73. rxArray.buf[rxArray.index]=num;
          74. rxArray.index++;
          75. }
          76. return;
          77. }
          78. if(0==rxArray.lenHighFlag)//判斷是否接收到幀長(zhǎng)度的高字節(jié)信息
          79. {
          80. rxArray.lenHighFlag=1;//標(biāo)志已經(jīng)接收到幀長(zhǎng)度的高字節(jié)
          81. rxArray.lenHigh=rxArray.buf[rxArray.index]=num;
          82. rxArray.index++;
          83. return;
          84. }
          85. if(0==rxArray.lenLowFlag)//判斷是否接收到幀長(zhǎng)度的低字節(jié)信息
          86. {
          87. rxArray.lenLowFlag=1;//標(biāo)志已經(jīng)接收到幀長(zhǎng)度的低字節(jié)
          88. rxArray.lenLow=rxArray.buf[rxArray.index]=num;
          89. rxArray.index++;
          90. rxArray.dataStartIndex=rxArray.index;
          91. rxArray.tempLen=rxArray.len=(rxArray.lenHigh<<8)+rxArray.lenLow;//增加一字節(jié)的幀尾
          92. if(rxArray.len+5>512)//如果數(shù)據(jù)長(zhǎng)度大于12,則說(shuō)明接收的數(shù)據(jù)長(zhǎng)度信息有誤,需要重新接收
          93. {
          94. rxArray.startFlag=0;
          95. rxArray.lenHighFlag=0;
          96. rxArray.lenLowFlag=0;
          97. }
          98. return;
          99. }
          100. if(0==rxArray.dataFlag)
          101. {
          102. rxArray.buf[rxArray.index]=num;//把數(shù)據(jù)存放到數(shù)組中
          103. rxArray.index++;
          104. rxArray.tempLen--;
          105. if(0==rxArray.tempLen)
          106. {
          107. rxArray.dataFlag=1;
          108. }
          109. return;
          110. }
          111. if(0==rxArray.lrcFlag)//接收l(shuí)rc
          112. {
          113. rxArray.buf[rxArray.index]=num;
          114. rxArray.index++;
          115. rxArray.lrcFlag=1;
          116. if(0!=uart_CalLrc(&rxArray.buf[rxArray.dataStartIndex],rxArray.len+1))//判斷接收數(shù)據(jù)的lrc是否正確
          117. {
          118. rxArray.startFlag=0;
          119. rxArray.lenHighFlag=0;
          120. rxArray.lenLowFlag=0;
          121. rxArray.dataFlag=0;
          122. rxArray.lrcFlag=0;
          123. }
          124. return;
          125. }
          126. rxArray.buf[rxArray.index]=num;
          127. rxArray.finishFlag=1;
          128. rxArray.startFlag=0;
          129. rxArray.lenHighFlag=0;
          130. rxArray.lenLowFlag=0;
          131. rxArray.dataFlag=0;
          132. rxArray.lrcFlag=0;
          133. if(rxArray.buf[rxArray.index]!=0x03)//最后一個(gè)字節(jié)不是0x03,說(shuō)明數(shù)據(jù)有誤,需要重新接收
          134. {
          135. rxArray.finishFlag=0;
          136. }
          137. if(rxArray.finishFlag)
          138. {
          139. //收到數(shù)據(jù)處理部分
          140. }
          141. }

          本程序一個(gè)致命的bug就是,如果長(zhǎng)度信息那兩個(gè)字節(jié)的數(shù)據(jù)接收時(shí)出現(xiàn)錯(cuò)誤,會(huì)導(dǎo)致不能正確組成一包數(shù)據(jù),后面發(fā)送過(guò)來(lái)的數(shù)據(jù)包也不能正確接收。

          如有一包數(shù)據(jù)(16進(jìn)制):02 00 02 11 11 00 03,

          如果接收過(guò)程出現(xiàn)錯(cuò)誤,導(dǎo)致將長(zhǎng)度的兩個(gè)字節(jié)00 02在接收端變成了00 05,因此接收端會(huì)等待接收完5個(gè)字節(jié)的數(shù)據(jù)之后才認(rèn)為完整的接收完一包數(shù)據(jù),從而導(dǎo)致后面發(fā)送過(guò)來(lái)的完整的數(shù)據(jù)包的一部分會(huì)被拆分,周而復(fù)始的這樣惡性循環(huán)下去,暫時(shí)還沒(méi)想到好的解決辦法!



          關(guān)鍵詞: Msp430串口中斷數(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); })();