历史上的今天
返回首页

历史上的今天

今天是:2025年03月23日(星期日)

正在发生

2020年03月23日 | 使用Msp430的串口中断接收一包数据

2020-03-23 来源:eefocus

假设有一数据包,数据格式如表所示:

image.png?imageView2/2/w/550

数据包总长度为: 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个字节的数据之后才认为完整的接收完一包数据,从而导致后面发送过来的完整的数据包的一部分会被拆分,周而复始的这样恶性循环下去,暂时还没想到好的解决办法!

推荐阅读

史海拾趣

北京人民电器厂公司的发展小趣事

近年来,随着新能源产业的快速发展,北京人民电器紧跟时代步伐,在新能源领域取得了重要突破。公司推出的真安型零飞弧直流断路器,解决了直流低压系统中长期存在的外喷电弧问题,为新能源行业的发展提供了重要的技术支持。这一创新成果不仅得到了行业的广泛认可,也为公司在新能源领域的发展打开了新的局面。

这五个故事只是北京人民电器在电子行业发展历程中的一部分,但它们足以展现出公司在技术创新、产品应用、生产自动化、人才队伍建设以及新能源领域发展等方面的努力和成就。这些故事不仅记录了北京人民电器的成长轨迹,也见证了中国电子行业的蓬勃发展。

晨晶电子(Chenjing Electronics)公司的发展小趣事

晨晶电子始终将品质放在首位,坚持以客户为中心的服务理念。公司建立了严格的质量管理体系,从原材料采购到生产过程控制,再到产品出厂检验,每一个环节都严格把关,确保产品的品质稳定可靠。正是凭借这种对品质的执着追求,晨晶电子赢得了客户的广泛认可和好评,也为企业赢得了良好的口碑。

Excelitas公司的发展小趣事

为了进一步提升竞争力,Excelitas公司积极寻求与其他企业的战略合作。在一次重要的合作中,Excelitas与一家知名的半导体公司达成合作协议,共同开发新型光电传感器。通过资源整合和优势互补,双方成功推出了多款具有竞争力的产品,实现了互利共赢。这次合作不仅增强了公司的技术实力,还为公司带来了新的市场机遇。

Hi-Light Electronic Co Ltd公司的发展小趣事

为了进一步提升竞争力,Excelitas公司积极寻求与其他企业的战略合作。在一次重要的合作中,Excelitas与一家知名的半导体公司达成合作协议,共同开发新型光电传感器。通过资源整合和优势互补,双方成功推出了多款具有竞争力的产品,实现了互利共赢。这次合作不仅增强了公司的技术实力,还为公司带来了新的市场机遇。

Easy Magnet Corp公司的发展小趣事

Easy Magnet Corp公司深知人才是企业发展的核心动力。因此,公司注重人才培养和引进,建立了一支高素质、专业化的研发团队。同时,公司还为员工提供了良好的工作环境和福利待遇,激发了员工的工作热情和创造力。这些举措为公司的发展提供了坚实的人才保障。

BALLUFF公司的发展小趣事

BALLUFF公司的历史可以追溯到1921年,由格布哈德·巴鲁夫(Gebhard Balluff)创建的一家机械修理厂开始。这家修理厂起初规模较小,但巴鲁夫凭借其对机械技术的精湛理解和不懈追求,逐渐将业务发展壮大。他通过不断的技术创新和产品升级,使得修理厂逐渐转型为一家专注于生产精密部件、车件和铣件的企业。这一转变不仅奠定了BALLUFF公司的工业基础,也为其日后在传感器领域的崛起打下了坚实基础。

问答坊 | AI 解惑

自己动手制作机器人,看起来很好玩

来源:窗户纸  http://www.getproject.com.cn/post/98.html 机器人,听起来挺神秘的,在大多数科幻电影和文学作品中,机器人通常无所不知,无所不能,跟人类相比起来,简直就是完美无瑕了。因此,作品中的机器人,要么是人类的好朋友, ...…

查看全部问答>

用DSP产生的FSK调制信号发射

本帖最后由 paulhyde 于 2014-9-15 09:23 编辑 我产生的调制信号频率150K,在不混频的情况下可以直接通过功率放大器进行电感耦合吗???两个电感线圈的距离为5CM 具体功率放大器怎样设计???  …

查看全部问答>

产品使用报告格式

如题,哪位大侠有产品使用报告的格式呀??借来用用…

查看全部问答>

VC++关于directshow图像旋转90度输出花屏的问题

VC++关于directshow图像旋转90度输出花屏的问题 我在transfilter对图像做了一个90度的旋转,再传给第三个filter,发现图像是花屏,解析度为176x144 如果解析度为高,宽相等就是正常的(如:240x240) 请问是什么原因?…

查看全部问答>

单片机考试 答案 请帮忙,急急急!!! 在线等答案!!!!

高手帮做一下,谢谢了,否则考试要挂了:(题在附件中…

查看全部问答>

招驱动工程师

岗位名称:驱动工程师 岗位要求: 1.电子、通信、计算机、自控类相关专业本科以上学历; 2.1年以上嵌入式产品开发经验,熟悉各种常用的外围扩展芯片的驱动。 比如SCI,SPI,I2C总线,smartcard,tuner。 3.精通C语言、汇编,有嵌入式系统和实时 ...…

查看全部问答>

香版!STM8S208的BEEP功能是不是不能用?

我问ST工程师的邮件:~~:    你好!    我需要用到BEEP功能,可是设定寄存器后跑程序,发现BEEP寄存器并没有改变.OPTION里面我有把PD4设成BEEP功能,OPTION里的PRSC设成(16MHZ TO 128KHZ P ...…

查看全部问答>

LPC11C14 IAP与CAN API问题

我在用LPC11C14写IAP在线升级程序时,将用户程序的向量表复制到RAM的0地址,再通过重映射寄存器重映射到FLASH的0地址,实现了用户程序调用中断,但现在要把CAN API的程序加上去,而CAN API要占用RAM的0x1000 0050-0x1000 00B8 ...…

查看全部问答>

学习FPGA过程中的困惑

现在刚开始接触FPGA不久,看了很长时间论坛了,也学习了Verilog,试着学习应用quartusii和modelsim,现在依旧感觉没有多大进步,好像根本还没有入门,简单的仿真还能进行,遇到复杂点的,比如几个模块联合编译仿真就总是仿真失败,也没有找到原因! ...…

查看全部问答>