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

发布者:dadigt最新更新时间:2016-08-16 来源: eefocus关键字:Msp430  串口中断  数据 手机看文章 扫描二维码
随时随地手机看文章
假设有一数据包,数据格式如表所示:

                                                                                                             

序号

项 目

长度(字节)

说明

1

数据包头(STX)

1

常量:0x02

2

数据单元长度(Data_len)

2

需传输的数据单元Data部分的长度,高字节在前,低字节在后。

例如:0x0010表示Data部分有16个字节。

3

需传输的数据单元(Data)

不定

长度由Data_len指出,数据单元头两个字节是命令码(终端发送命令到读写器)或状态码(读写器返回数据给终端),后面是其它参数。

4

冗余检验值(LRC)

1

Data部分数据各字节异或值。

5

数据包尾(ETX)

1

常量:0x03

数据包总长度为: Data_len + 5 字节,最长不能超过512字节。

 

程序实现如下所示:

  1. #include    
  2.   
  3. typedef struct newStruct  
  4. {            
  5.       unsigned char startFlag;  
  6.       unsigned char finishFlag;  
  7.       unsigned char lenHighFlag;  
  8.       unsigned char lenLowFlag;  
  9.       unsigned char dataFlag;  
  10.       unsigned char lrcFlag;  
  11.       unsigned char buf[512];  
  12.       unsigned char lenHigh;  
  13.       unsigned char lenLow;  
  14.       unsigned char dataStartIndex;  
  15.       unsigned short len;  
  16.       unsigned short index;  
  17.       unsigned short tempLen;  
  18. }rxstruct;  
  19. rxstruct rxArray;  
  20.   
  21. void m430_InitUart()  
  22. {  
  23.       P3SEL |= BIT4|BIT5;           // P3.4, P3.5 = USCI_A0 TXD/RXD   
  24.         
  25.       UCA0CTL1 |= UCSSEL_2;          // SMCLK   
  26.         
  27.       //以下三行为波特率设置使用   
  28.       UCA0BR1  = 0;   
  29.       UCA0BR0  = 104;         // 12MHz:1250->9600,625->19200,312->38400,214->56000,104->115200                
  30.       UCA0MCTL = 0x02;         // Modulation UCBRSx = 1   
  31.      
  32.       UCA0CTL1 &= ~UCSWRST;    // Initialize USCI state machine    
  33.       //IE2 |= UCA0RXIE | UCA0TXIE;  //注意应在初始化USCI之后,设置中断使能,否则不起作用,即若此句放在UCA0CTL1 &= ~UCSWRST;之前,则不会响应中断   
  34.       IE2 |= UCA0RXIE;  
  35. }  
  36.   
  37. unsigned char uart_CalLrc(unsigned char *buf, unsigned short len)  
  38. {  
  39.       unsigned short i;  
  40.       unsigned char lrc;  
  41.       lrc = 0x00;  
  42.         
  43.       for( i=0; i
  44.       {            
  45.           lrc ^= buf[i];  
  46.       }  
  47.         
  48.       return lrc;  
  49. }  
  50.   
  51. void main()  
  52. {     
  53.       WDTCTL = WDTPW + WDTHOLD;  
  54.       BCSCTL1 = CALBC1_12MHZ;  
  55.       DCOCTL  = CALDCO_12MHZ;  
  56.         
  57.       m430_InitUart();  
  58.         
  59.       rxArray.startFlag = 0;              
  60.       rxArray.finishFlag = 0;  
  61.         
  62.       _EINT();                        
  63.       _BIS_SR(LPM4_bits);  
  64.       while(1)  
  65.       {            
  66.       }  
  67. }  
  68.   
  69. #pragma vector = USCIAB0RX_VECTOR   
  70. __interrupt void uartRxHandle()  
  71. {  
  72.       unsigned char num;        
  73.       num = UCA0RXBUF;        
  74.                     
  75.       if( 0==rxArray.startFlag )//判断是否接收到帧头   
  76.       {  
  77.             if( 0x02==num )//判断帧头是否正确   
  78.             {  
  79.                 rxArray.startFlag = 1;//标志已经接收到帧头   
  80.                 rxArray.finishFlag = 0;  
  81.                 rxArray.lenHighFlag = 0;  
  82.                 rxArray.lenLowFlag = 0;  
  83.                 rxArray.dataFlag = 0;  
  84.                 rxArray.lrcFlag = 0;  
  85.                 rxArray.index = 0;  
  86.                 rxArray.len = 0;//存储帧长度   
  87.                 rxArray.buf[rxArray.index] = num;  
  88.                 rxArray.index++;  
  89.             }  
  90.             return;  
  91.       }  
  92.         
  93.       if( 0==rxArray.lenHighFlag )//判断是否接收到帧长度的高字节信息   
  94.       {  
  95.             rxArray.lenHighFlag = 1;//标志已经接收到帧长度的高字节   
  96.             rxArray.lenHigh = rxArray.buf[rxArray.index] = num;  
  97.             rxArray.index++;                            
  98.             return;  
  99.       }  
  100.         
  101.       if( 0==rxArray.lenLowFlag )//判断是否接收到帧长度的低字节信息   
  102.       {  
  103.             rxArray.lenLowFlag = 1;//标志已经接收到帧长度的低字节   
  104.             rxArray.lenLow = rxArray.buf[rxArray.index] = num;  
  105.             rxArray.index++;  
  106.             rxArray.dataStartIndex = rxArray.index;  
  107.               
  108.             rxArray.tempLen = rxArray.len = (rxArray.lenHigh<<8) + rxArray.lenLow;//增加一字节的帧尾   
  109.             if( rxArray.len+5>512 )//如果数据长度大于12,则说明接收的数据长度信息有误,需要重新接收   
  110.             {  
  111.                 rxArray.startFlag = 0;  
  112.                 rxArray.lenHighFlag = 0;  
  113.                 rxArray.lenLowFlag = 0;  
  114.             }       
  115.             return;  
  116.       }  
  117.         
  118.       if( 0==rxArray.dataFlag )  
  119.       {  
  120.             rxArray.buf[rxArray.index] = num;//把数据存放到数组中   
  121.             rxArray.index++;  
  122.             rxArray.tempLen--;  
  123.             if( 0==rxArray.tempLen )  
  124.             {  
  125.                   rxArray.dataFlag = 1;  
  126.             }  
  127.             return;  
  128.       }  
  129.         
  130.       if( 0==rxArray.lrcFlag )//接收lrc   
  131.       {  
  132.             rxArray.buf[rxArray.index] = num;  
  133.             rxArray.index++;  
  134.             rxArray.lrcFlag = 1;  
  135.             if( 0!=uart_CalLrc( &rxArray.buf[rxArray.dataStartIndex], rxArray.len+1 ) )//判断接收数据的lrc是否正确   
  136.             {  
  137.                 rxArray.startFlag = 0;  
  138.                 rxArray.lenHighFlag = 0;  
  139.                 rxArray.lenLowFlag = 0;  
  140.                 rxArray.dataFlag = 0;  
  141.                 rxArray.lrcFlag = 0;  
  142.             }  
  143.             return;  
  144.       }  
  145.         
  146.       rxArray.buf[rxArray.index] = num;       
  147.       rxArray.finishFlag = 1;  
  148.       rxArray.startFlag = 0;  
  149.       rxArray.lenHighFlag = 0;  
  150.       rxArray.lenLowFlag = 0;  
  151.       rxArray.dataFlag = 0;  
  152.       rxArray.lrcFlag = 0;        
  153.       if( rxArray.buf[rxArray.index]!=0x03 )//最后一个字节不是0x03,说明数据有误,需要重新接收   
  154.       {               
  155.             rxArray.finishFlag = 0;               
  156.       }     
  157.         
  158.       if( rxArray.finishFlag )  
  159.       {  
  160.             //收到数据处理部分                                                          
  161.       }  
  162. }  

本程序一个致命的bug就是,如果长度信息那两个字节的数据接收时出现错误,会导致不能正确组成一包数据,后面发送过来的数据包也不能正确接收。

如有一包数据(16进制):02 00 02 11 11 00 03,

如果接收过程出现错误,导致将长度的两个字节00 02在接收端变成了00 05,因此接收端会等待接收完5个字节的数据之后才认为完整的接收完一包数据,从而导致后面发送过来的完整的数据包的一部分会被拆分,周而复始的这样恶性循环下去,暂时还没想到好的解决办法!

关键字:Msp430  串口中断  数据 引用地址:使用Msp430的串口中断接收一包数据

上一篇:MSP430F2131读写DS1991
下一篇:MSP430可通过哪些接口进行烧写程序

推荐阅读最新更新时间:2024-03-16 15:05

MSP430G2转换结果数据类型
以下是程序,软件用的IAR: #include io430.h #include dandao_duocai.h #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) #define dataout P2OUT unsigned int ADC10_Result ; int d,c; void cheek_clock() { BCSCTL3_bit.LFXT1S0 = 0; //配置ACLK为12KHz BCSCT
[单片机]
MMC在便携式数据采集系统中的应用
目前比较常见的数据采集及处理系统是功能完备的微机系统。这种系统虽然能较快地分析和处理监测到的信号,但往往只能在固定的位置使用,在野外和移动的情况下则显得十分笨重和不便。特别是野外数据采集作业,往往需要长时间地采集、记录海量数据,需要体积小、重量轻、存储容量大的数据采集及处理仪器。近几年,随着非易失存储技术的发展以及处理器(如嵌入式系统和DSP)性能的不断提高,使信号采集存储系统的耗电量和体积不断减小,满足了便携式的要求,但其读写速度不及MMC。多媒体卡MMC(Multimedia Card)是由美国SANDISK公司和德国西门子公司在1997年共同开发研制的一种多功能、体积小、容量大的快闪存储卡。MMC的发展目标主要是针对移动电话
[单片机]
MMC在便携式<font color='red'>数据</font>采集系统中的应用
美光升级对云数据中心和企业数据中心的OCP存储支持
Micron Technology Inc.(美光科技股份有限公司)近日宣布为其 7450 NVMe SSD 推出符合“开放计算项目数据中心 NVMe SSD 2.0” (OCP SSD 2.0)规范的全新固件。美光采用最新的 OCP 规范以实现智能管理,从而能够快速、主动地优化和解决常见的数据中心问题,同时为企业数据中心带来云数据中心级别的能力。7450 SSD在升级最新固件后,将继续提供业界最灵活的部署选项(包括 U.2/U.3、E1.S 和M.2 等外形尺寸)、更低的延迟和更高的服务质量。 美光副总裁兼数据中心存储业务部门总经理Alvaro Toledo表示:“数据中心运营商部署高服务质量的固态硬盘能够获得巨大的价
[手机便携]
美光升级对云<font color='red'>数据</font>中心和企业<font color='red'>数据</font>中心的OCP存储支持
MSP430F149单片机对SDRAM控制程序设计
MSP430的内核结构采用具有高透明格式的精简指令集(RISC)设计。指令分为硬件实现的内核指令和利用这一硬件结构的具有更高效率的模拟指令,使用起来非常方便。在本控制系统中,单片机完成初始化任务(设置标志位、看门狗的工作方式)后,就进入低功耗睡眠状态。中断将其唤醒,转而进入相应的子程序。基于MSP430F149单片机的SDRAM控制程序如下。 #include msp430x14x.h void Init(void); void Send(char* Data, unsigned int Length); void SendAddress(unsigned int Address); void SendData(unsign
[单片机]
Diodes Incorporated 的 8 埠 PCIe3.0数据包切换器设计灵活性省电
Diodes Incorporated 的 8 埠 PCIe 3.0 数据包切换器兼具设计灵活性及省电两项特色 【2021 年 4 月 27 日美国德州普拉诺讯】 Diodes 公司 (Nasdaq:DIOD) 推出的 PCIe® 3.0 数据包切换器 PI7C9X3G808GP,能够提供现代数据中心、云端运算、网络附加储存设备 (NAS) 和电信基础设施所要求的高效能参数。这款数据包切换器支持 8 通道操作,支持 2、3、4、5和 8 端口配置。可利用直通 (cut-through) 及储存和转发 (store and forward) 模式,支持小于 150ns (典型值) 的数据包转发延迟。 PI7C9X3G8
[网络通信]
Diodes Incorporated 的 8 埠 PCIe3.0<font color='red'>数据</font>包切换器设计灵活性省电
msp430ADC程序
上图是ADC的内部工作原理图,通过这个图,我们可以知道430有16个转化通道,16个转化结果寄存器和16个控制寄存器 其中ADC12MEMX与ADC12MCTLX是一一对应的,但是要注意的一点是通道Ax并不与ADC12MEMX相对应,也就是说A1的转化结果不一定非得放到ADC12MEM1当中, ADC12MCTLX中的INCHx可以确定ADC12MEMX存放哪个通道的转化结果。 下面附一个单通道单次转化的程序: #include msp430x14x.h #include lcd.h void int2charsLcdshow(int value); void DelayXms(unsigned int i
[单片机]
<font color='red'>msp430</font>ADC程序
云计算数据中心能源管理全方位剖析
广东省电信规划设计院IDC工程设计研究中心主任邓重秋说:“云计算数据中心不一定等于高密度数据中心,但高密度一定是云计算数据中心的发展趋势。” 如果数据中心没有优化效率,那么云计算势必会扩大数据中心的能源问题。 过去,云计算已经蓬勃的发展,预计在未来的四年,收入增长率将达到27%.企业从云计算中看到了众多优点中的二个,它们就是云计算能够降低成本,以及通过限制内部数据中心的运行而减少能耗。 尽管如此,《华尔街日报》仍指出,在相同的时间内,在云应用程序中部署的服务器数量预计是原来的三倍。虽然云计算对企业分享信息有好处,但是数据中心提供给云的动力可能会成为气候变化的主要原因。 为什么呢?因为如果数据中心不是
[网络通信]
单片开关电源设计要点及电子数据表格
1单片开关电源的设计要点 1.1电源效率的选定 开关电源效率(η)是指其输出功率(PO)与输入功率(PI)(即总功率)的百分比。需要指出,单片开关电源的效率随输出电压(UO)的升高而增加。因此,在低压输出时(UO=5V或3.3V),η可取75%;高压输出时(UO≥12V),η可取85%。在中等电压输出时(5V因电源效率η=PO/PI,故开关电源的总功耗PD=PI-PO=-PO=·PO(1) PD中包括次级电路功耗和初级电路功耗。重要的是应知道初、次级功耗是如何分配的。损耗分配系数(Z)即反映出这种关系。 设初级功耗为PP,次级功耗为PS,则PP+PS=PD,Z=PS/PD,而1-Z=PP/PD。需要注意的是,次级功
[电源管理]
单片开关电源设计要点及电子<font color='red'>数据</font>表格
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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