使用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  串口  中断接收  一包数据 引用地址:使用Msp430的串口中断接收一包数据

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

推荐阅读最新更新时间:2024-11-10 05:56

AT89C51的串口和电脑的串口进行通信
串口通讯对单片机而言意义重大,不但可以实现将单片机的数据传输到电脑端,而且也能实现电脑对单片机的控制,比如你可以把写入单片机的数据码显示在电脑上,如可以使用一个按键,当按下它时使某一个字母如:AA,通过单片机的串口将它发送到电脑上显示,起到仿真器的某些功效,站长在开发数据采集设备时就是通过串口来检查数据正确与否的。 51单片机有一个全双工的串行通讯口,所以单片机和电脑之间可以方便地进行串口通讯。进行串行通讯时要满足一定的条件,比如电脑的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换,虽然也可以用几个三极管进行模拟转换,但是还是用专用芯片更简单可靠。我
[单片机]
AT89C51的<font color='red'>串口</font>和电脑的<font color='red'>串口</font>进行通信
MSP430F149单片机智能火灾报警系统设计
以单片机MSP430F149 为主控芯片,设计出一款高精度、高集成度、超低功耗的智能火灾报警系统。以环境温度、烟雾浓度作为判断火灾的依据,完成了对火灾的预警。主要由单片机控制模块、时钟模块、烟雾浓度测量模块、DS18B20 温度测量模块、声光报警模块、1602液晶显示模块和电源构成。并且该系统以MSP430F149 为下位机,完成数据采集、预处理以及对现场装置的控制,以 PC 机为上位机,完成各种复杂的数据处理和对单片机的控制。设计的智能火灾报警系统具有较高的可靠性、稳定性、准确度高,对不同类型的火灾都具有较高的灵敏度,达到了降低误报率的目的。 温度测量模块:设计中采用支持“一线总线”接口、抗干扰性强、外部电路简单、精确度高的
[单片机]
<font color='red'>MSP430</font>F149单片机智能火灾报警系统设计
MSP430主系统时钟以及430的低功耗设置
如何将系统时钟设置到外部高频晶体振荡器,430的MCLK默认的是DCO的,如何安全的从DCO切换到外部晶体振荡器,这是一个很重要的步骤,因为经过此步骤,可以极大地提高430的处理能力,DCO在内部,可以为cpu提供强劲稳定的时钟 #include msp430x14x.h void main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; volatile unsigned int i; P5DIR |=BIT4;//设置P5.4为输出 P5SEL |=BIT4;//设置片内主系统时钟的
[单片机]
<font color='red'>MSP430</font>主系统时钟以及430的低功耗设置
MSP430仿真器使用常见问题
一、 主要是驱动安装问题 有用户反应驱动安装不上,按照用户手册操作一直不能安装成功。 可以尝试如下步骤进行安装。 1. 双击设备管理器中无法安装或者提示有错误的430仿真器设备 选择驱动程序——更新驱动程序 选择手动安装 选择从电脑设备驱动列表中安装 弹出下面对话框 找到端口选项,因为 MSP430 仿真器安装的是默认为一个串口的 点下一步 找到 te xas instuments厂商 在右侧选中msp-FET430U IF -VCP 点击下一步 自动安装成功 二、 另外一个就是MSP430仿真器给核心板供电问题,在MSP430核心板中有说明,这里再说一下 一、 关于MS
[单片机]
<font color='red'>MSP430</font>仿真器使用常见问题
MSP430开发工具的介绍及其特性
  在MCU项目开发过程中,始终有两个设备紧密的联系在一起,一个是仿真器,一个是编程器。仿真器,顾名思义就是模仿单片机的功能;编程器就是把程序编写到单片机内部。   目前公司在MSP430开发工具方面主要有仿真器、编程器、各类学习板、转接板、适配器等。   一:仿真器、编程器   IAR和JTAG无法连接,是怎么回事?这是客户问的问题,在论坛中也很常见,FAE也有在问。我们就从这个问题开始讲解吧。   MSP430无论是仿真还是烧写程序,一般可以通过:JTAG、SBW、BSL接口进行。   1、JTAG是利用边界扫描技术,在430内部有逻辑接口给JTAG使用,内部有若干个寄存器连接到了430内部数据地址总线上,所以可以
[单片机]
<font color='red'>MSP430</font>开发工具的介绍及其特性
采用MSP430系列设计的移动信用卡读取器
您是否曾有看似超越现有技术好几年的想法?是否因为无法找到可满足需求的 MCU 而将草稿设计遗忘?请拂去设计方案上的尘土。MSP430FR5739 器件在这里可帮助您重新构思不可能的设计。 MSP430FR5739 器件是 MSP430 系列中的首款 FRAM 嵌入式 MCU,于 2011 年发布至今已应用在大量独特应用设计中,其可帮助解决系统级问题、优化设计,充分满足低能耗的需求。 今天我们将讨论移动信用卡读取器应用,在该应用中 MSP430FR5739 的独特差异化价值可帮助解决多种挑战。MSP430FR5739 器件配有 16K 嵌入式 FRAM、5 个独立定时器、硬件乘法器、DMA、ADC 以及串行通信端口。说到移动
[单片机]
基于MSP430F5438A的ESP8266模块STA模式程序调试成功
ESP8266模块STA模式程序,主控芯片为MSP430F5438A,开发环境为IAR MSP430F5438A通过串口,以115200的波特率与ESP8266通信,对ESP8266进行配置, 主要完成室内WiFi的连接配置,和连接远端服务器的配置,远端服务器采用USR-TCP232-Test软件 进行模拟,USR-TCP232-Test软件打开时自动显示你的电脑IP和所用的端口号,将其直接写入程序中的 需要连接的IP和端口号即可。 配置完成后可以实现以STA方式与远端服务器进行双向数据传输。 在串口发送数据时,以字符型(“AT”)发送出去,指令发送之后,马上发送rn,表示回车换行,完成一条 指令的发送
[单片机]
基于<font color='red'>MSP430</font>F5438A的ESP8266模块STA模式程序调试成功
12864(ST7902)串口C51程序
/********************************************************************************  *program name:st7920.c  *function: TEST TO st7920(drive)  *Design: qinhao  *Date:2009-01-07  *********************************************************************************/ #include reg52.h   #include stdlib.h   #include intrins.h  
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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