使用Msp430的串口中断接收一包数据

2020-03-23来源: eefocus关键字:Msp430  串口  中断接收  一包数据

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

image.png

数据包总长度为: 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  串口  中断接收  一包数据 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic492341.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:MSP430 串口接收指令控制LED亮灭
下一篇:MSP430F247串口发送字符串并接受PC机发来的并送回电脑显示

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

MSP432E401Y单片机智能小车PID调速代码
 * MSP432E401Y * Description:PID处理函数 * 引脚: *        * Author: Robin.J***************************************************************************/#include <PID.h>#include "ti/devices/msp432e4/driverlib/driverlib.h"float iError_l , iIncpid_l; //当前误差float
发表于 2020-04-06
MSP432E401Y电机编码器QEI模块
/* DriverLib Includes */#include <ti/devices/msp432e4/driverlib/driverlib.h>/* Standard Includes */#include <stdint.h>#include <stdio.h>#include <stdbool.h>unsigned long  COUNT = 0;unsigned long  POS = 0;int  s;int d
发表于 2020-04-06
MSP430应用技巧4:创建MSP430Ware工程项目的方法
此软件架构指TI公司的MSP430Ware有别于日志介绍的MSP430Ware++,大家在阅读的时候要注意。我们在使用MSP430Ware的时候,首先应从TI官方网站上下载,然后安装即可,本文介绍基于MSP430Ware的工程项目的创建方法。1、启动CCS,可以见到如下画面,在硬盘上建立工程文件目录,然后将CCS的workspace直接指向该文件家即可,该文件夹应该为空,点击OK即可。 2、进入CCS主界面后,选择File-New-CCS Project项目,如下图所示。 3、在下图中对项目进行设置,设置后点击Finish。 4、工程建立后,就可以查看MSP430Ware的TI官方文档,进行使用了。
发表于 2020-04-06
MSP430应用技巧4:创建MSP430Ware工程项目的方法
(基于TI-RSLK)MSP432学习-03-使用VS进行代码库函数编写
!!!!!(这是后边操作的基础)完成后点击工程名,右键,选择属性在选项卡中按下图选择:若没有C/C++这一项,则是工程中没有任何.c文件!!点击添加图标,输入./点击确定即可四、使用方法用CCS打开或创建一个工程,在 CCS 工程目录会有C文件(.c),用VS打开刚刚创建的VS工程,将CCS工程目录中的C文件添加到VS工程的USER目录,即可实现使用VS编写代码,完成后保存,用CCS编译和调试代码。五、成品VS工程模版下载雨燕云百度云分享 提取码:ngm7github下载六、github地址https://github.com/843862803/MSP432所有MSP432的demo将在github上开源供大家学习和下载!
发表于 2020-04-06
(基于TI-RSLK)MSP432学习-03-使用VS进行代码库函数编写
MSP430Ware使用笔记 初始化XT1
1.平台说明 MSP430F54382.为什么使用MSPWare。由于工作原因,学校中多使用STM32,STM32的DriverLib比较方便使用。初学MSP430重新回到了操作寄存器的时代,稍稍有点不适应。后来发现MSP也有DriverLib只是使用的人不多,就这范例文档一点一点摸索,并和寄存器操作相比较。经过了一段时间的努力也就熟悉了。3.嵌入式系统编程趋势个人认为,DriverLib会成为主流,这样可以缩短MCU使用的难度,在Flash和RAM容量不断提高的今天,不必去死抠每一个函数,如何更快上手MCU解决实际问题才是王道。刚刚推出市场的新MCU也具备DriverLib,缩短上手时间,更快占领市场。4.示例代码,启动XT1
发表于 2020-04-06
用IAR新建TexasInstruments MSP432E401Y工程
新建一个工作空间。在工作空间里面新建文件夹,命名为BlinkyForMSP432。打开IAR for ARM 的IDE,新建工程。点击File--->New Workspace新建工作空间。点击Project--->Creat New Project...新建工程。弹出如下界面:3.3点击Empty project新建一个空工程,保存在workspace for msp432目录下。3.4点击File--->Save将新建工程保存在BlinkyForMSP432根目录下。输入工程名字,点击保存,结果如下图:添加“.c”和“.h”文件,点击File--->New File,或者快键键Ctrl+N。新建完成
发表于 2020-04-06
用IAR新建TexasInstruments MSP432E401Y工程
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved