历史上的今天
今天是:2025年03月23日(星期日)
2020年03月23日 | 使用Msp430的串口中断接收一包数据
2020-03-23 来源:eefocus
假设有一数据包,数据格式如表所示:

数据包总长度为: 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个字节的数据之后才认为完整的接收完一包数据,从而导致后面发送过来的完整的数据包的一部分会被拆分,周而复始的这样恶性循环下去,暂时还没想到好的解决办法!
史海拾趣
|
来源:窗户纸 http://www.getproject.com.cn/post/98.html 机器人,听起来挺神秘的,在大多数科幻电影和文学作品中,机器人通常无所不知,无所不能,跟人类相比起来,简直就是完美无瑕了。因此,作品中的机器人,要么是人类的好朋友, ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 09:23 编辑 我产生的调制信号频率150K,在不混频的情况下可以直接通过功率放大器进行电感耦合吗???两个电感线圈的距离为5CM 具体功率放大器怎样设计??? … 查看全部问答> |
|
VC++关于directshow图像旋转90度输出花屏的问题 VC++关于directshow图像旋转90度输出花屏的问题 我在transfilter对图像做了一个90度的旋转,再传给第三个filter,发现图像是花屏,解析度为176x144 如果解析度为高,宽相等就是正常的(如:240x240) 请问是什么原因?… 查看全部问答> |
|
我问ST工程师的邮件:~~: 你好! 我需要用到BEEP功能,可是设定寄存器后跑程序,发现BEEP寄存器并没有改变.OPTION里面我有把PD4设成BEEP功能,OPTION里的PRSC设成(16MHZ TO 128KHZ P ...… 查看全部问答> |
|
我在用LPC11C14写IAP在线升级程序时,将用户程序的向量表复制到RAM的0地址,再通过重映射寄存器重映射到FLASH的0地址,实现了用户程序调用中断,但现在要把CAN API的程序加上去,而CAN API要占用RAM的0x1000 0050-0x1000 00B8 ...… 查看全部问答> |
|
现在刚开始接触FPGA不久,看了很长时间论坛了,也学习了Verilog,试着学习应用quartusii和modelsim,现在依旧感觉没有多大进步,好像根本还没有入门,简单的仿真还能进行,遇到复杂点的,比如几个模块联合编译仿真就总是仿真失败,也没有找到原因! ...… 查看全部问答> |




