新聞中心

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

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

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

本文引用地址:http://m.butianyuan.cn/article/201611/316517.htm

序號(hào)

項(xiàng) 目

長度(字節(jié))

說明

1

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

1

常量:0x02

2

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

2

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

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

3

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

不定

長度由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ù)包總長度為: Data_len + 5 字節(jié),最長不能超過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ǔ)幀長度
  73. rxArray.buf[rxArray.index]=num;
  74. rxArray.index++;
  75. }
  76. return;
  77. }
  78. if(0==rxArray.lenHighFlag)//判斷是否接收到幀長度的高字節(jié)信息
  79. {
  80. rxArray.lenHighFlag=1;//標(biāo)志已經(jīng)接收到幀長度的高字節(jié)
  81. rxArray.lenHigh=rxArray.buf[rxArray.index]=num;
  82. rxArray.index++;
  83. return;
  84. }
  85. if(0==rxArray.lenLowFlag)//判斷是否接收到幀長度的低字節(jié)信息
  86. {
  87. rxArray.lenLowFlag=1;//標(biāo)志已經(jī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ù)長度大于12,則說明接收的數(shù)據(jù)長度信息有誤,需要重新接收
  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)//接收lrc
  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,說明數(shù)據(jù)有誤,需要重新接收
  134. {
  135. rxArray.finishFlag=0;
  136. }
  137. if(rxArray.finishFlag)
  138. {
  139. //收到數(shù)據(jù)處理部分
  140. }
  141. }

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

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

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



關(guān)鍵詞: Msp430串口中斷數(shù)

評論


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

關(guān)閉