假设有一数据包,数据格式如表所示:
数据包总长度为: Data_len + 5 字节,最长不能超过512字节。
#include typedef struct newStruct { unsigned char startFlag; unsigned char finishFlag; unsigned char lenHighFlag; unsigned char lenLowFlag; unsigned char dataFlag; unsigned char lrcFlag; unsigned char buf[512]; unsigned char lenHigh; unsigned char lenLow; unsigned char dataStartIndex; unsigned short len; unsigned short index; unsigned short tempLen; }rxstruct; rxstruct rxArray; void m430_InitUart() { P3SEL |= BIT4|BIT5; // P3.4, P3.5 = USCI_A0 TXD/RXD UCA0CTL1 |= UCSSEL_2; // SMCLK //以下三行为波特率设置使用 UCA0BR1 = 0; UCA0BR0 = 104; // 12MHz:1250->9600,625->19200,312->38400,214->56000,104->115200 UCA0MCTL = 0x02; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine //IE2 |= UCA0RXIE | UCA0TXIE; //注意应在初始化USCI之后,设置中断使能,否则不起作用,即若此句放在UCA0CTL1 &= ~UCSWRST;之前,则不会响应中断 IE2 |= UCA0RXIE; } unsigned char uart_CalLrc(unsigned char *buf, unsigned short len) { unsigned short i; unsigned char lrc; lrc = 0x00; for( i=0; i lrc ^= buf[i]; } return lrc; } void main() { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_12MHZ; DCOCTL = CALDCO_12MHZ; m430_InitUart(); rxArray.startFlag = 0; rxArray.finishFlag = 0; _EINT(); _BIS_SR(LPM4_bits); while(1) { } } #pragma vector = USCIAB0RX_VECTOR __interrupt void uartRxHandle() { unsigned char num; num = UCA0RXBUF; if( 0==rxArray.startFlag )//判断是否接收到帧头 { if( 0x02==num )//判断帧头是否正确 { rxArray.startFlag = 1;//标志已经接收到帧头 rxArray.finishFlag = 0; rxArray.lenHighFlag = 0; rxArray.lenLowFlag = 0; rxArray.dataFlag = 0; rxArray.lrcFlag = 0; rxArray.index = 0; rxArray.len = 0;//存储帧长度 rxArray.buf[rxArray.index] = num; rxArray.index++; } return; } if( 0==rxArray.lenHighFlag )//判断是否接收到帧长度的高字节信息 { rxArray.lenHighFlag = 1;//标志已经接收到帧长度的高字节 rxArray.lenHigh = rxArray.buf[rxArray.index] = num; rxArray.index++; return; } if( 0==rxArray.lenLowFlag )//判断是否接收到帧长度的低字节信息 { rxArray.lenLowFlag = 1;//标志已经接收到帧长度的低字节 rxArray.lenLow = rxArray.buf[rxArray.index] = num; rxArray.index++; rxArray.dataStartIndex = rxArray.index; rxArray.tempLen = rxArray.len = (rxArray.lenHigh<<8) + rxArray.lenLow;//增加一字节的帧尾 if( rxArray.len+5>512 )//如果数据长度大于12,则说明接收的数据长度信息有误,需要重新接收 { rxArray.startFlag = 0; rxArray.lenHighFlag = 0; rxArray.lenLowFlag = 0; } return; } if( 0==rxArray.dataFlag ) { rxArray.buf[rxArray.index] = num;//把数据存放到数组中 rxArray.index++; rxArray.tempLen--; if( 0==rxArray.tempLen ) { rxArray.dataFlag = 1; } return; } if( 0==rxArray.lrcFlag )//接收lrc { rxArray.buf[rxArray.index] = num; rxArray.index++; rxArray.lrcFlag = 1; if( 0!=uart_CalLrc( &rxArray.buf[rxArray.dataStartIndex], rxArray.len+1 ) )//判断接收数据的lrc是否正确 { rxArray.startFlag = 0; rxArray.lenHighFlag = 0; rxArray.lenLowFlag = 0; rxArray.dataFlag = 0; rxArray.lrcFlag = 0; } return; } rxArray.buf[rxArray.index] = num; rxArray.finishFlag = 1; rxArray.startFlag = 0; rxArray.lenHighFlag = 0; rxArray.lenLowFlag = 0; rxArray.dataFlag = 0; rxArray.lrcFlag = 0; if( rxArray.buf[rxArray.index]!=0x03 )//最后一个字节不是0x03,说明数据有误,需要重新接收 { rxArray.finishFlag = 0; } if( rxArray.finishFlag ) { //收到数据处理部分 } } 本程序一个致命的bug就是,如果长度信息那两个字节的数据接收时出现错误,会导致不能正确组成一包数据,后面发送过来的数据包也不能正确接收。 如有一包数据(16进制):02 00 02 11 11 00 03, 如果接收过程出现错误,导致将长度的两个字节00 02在接收端变成了00 05,因此接收端会等待接收完5个字节的数据之后才认为完整的接收完一包数据,从而导致后面发送过来的完整的数据包的一部分会被拆分,周而复始的这样恶性循环下去,暂时还没想到好的解决办法!
上一篇:MSP430 串口接收指令控制LED亮灭
下一篇:MSP430F247串口发送字符串并接受PC机发来的并送回电脑显示
推荐阅读最新更新时间:2024-11-10 05:56