使用Msp430的串口中断接收一包数据
时间:11-13
来源:互联网
点击:
假设有一数据包,数据格式如表所示:
数据包总长度为: Data_len + 5 字节,最长不能超过512字节。
序号 | 项 目 | 长度(字节) | 说明 |
1 | 数据包头(STX) | 1 | 常量:0x02 |
2 | 数据单元长度(Data_len) | 2 | 需传输的数据单元Data部分的长度,高字节在前,低字节在后。 例如:0x0010表示Data部分有16个字节。 |
3 | 需传输的数据单元(Data) | 不定 | 长度由Data_len指出,数据单元头两个字节是命令码(终端发送命令到读写器)或状态码(读写器返回数据给终端),后面是其它参数。 |
4 | 冗余检验值(LRC) | 1 | Data部分数据各字节异或值。 |
5 | 数据包尾(ETX) | 1 | 常量:0x03 |
程序实现如下所示:
[cpp]view plaincopyprint?
- #include
- typedefstructnewStruct
- {
- unsignedcharstartFlag;
- unsignedcharfinishFlag;
- unsignedcharlenHighFlag;
- unsignedcharlenLowFlag;
- unsignedchardataFlag;
- unsignedcharlrcFlag;
- unsignedcharbuf[512];
- unsignedcharlenHigh;
- unsignedcharlenLow;
- unsignedchardataStartIndex;
- unsignedshortlen;
- unsignedshortindex;
- unsignedshorttempLen;
- }rxstruct;
- rxstructrxArray;
- voidm430_InitUart()
- {
- P3SEL|=BIT4|BIT5;//P3.4,P3.5=USCI_A0TXD/RXD
- UCA0CTL1|=UCSSEL_2;//SMCLK
- //以下三行为波特率设置使用
- UCA0BR1=0;
- UCA0BR0=104;//12MHz:1250->9600,625->19200,312->38400,214->56000,104->115200
- UCA0MCTL=0x02;//ModulationUCBRSx=1
- UCA0CTL1&=~UCSWRST;//InitializeUSCIstatemachine
- //IE2|=UCA0RXIE|UCA0TXIE;//注意应在初始化USCI之后,设置中断使能,否则不起作用,即若此句放在UCA0CTL1&=~UCSWRST;之前,则不会响应中断
- IE2|=UCA0RXIE;
- }
- unsignedcharuart_CalLrc(unsignedchar*buf,unsignedshortlen)
- {
- unsignedshorti;
- unsignedcharlrc;
- lrc=0x00;
- for(i=0;i
- {
- lrc^=buf[i];
- }
- returnlrc;
- }
- voidmain()
- {
- WDTCTL=WDTPW+WDTHOLD;
- BCSCTL1=CALBC1_12MHZ;
- DCOCTL=CALDCO_12MHZ;
- m430_InitUart();
- rxArray.startFlag=0;
- rxArray.finishFlag=0;
- _EINT();
- _BIS_SR(LPM4_bits);
- while(1)
- {
- }
- }
- #pragmavector=USCIAB0RX_VECTOR
- __interruptvoiduartRxHandle()
- {
- unsignedcharnum;
- 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,
如果接收过程出现错误,导致将长度的两
Msp430串口中断数 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)