单片机-串口通讯变长协议编写

2023-05-16

转载自:https://www.eefocus.com/luo_xinli/blog/14-04/302987_2bbdf.html

单片机-串口通讯变长协议编写

2014-04-20 18:35:53

分享到:

        上一节我们简单的介绍了一种定长通讯协议编写,这种协议有其优点,就是实现方法简单。因为只要接收到一个包头,只需节后到n个字节即可判断一帧数据接收完成。但是这种协议的缺点很明显,就是不能容纳太多的数据。所以这一节我来讨论一个变长协议的编写。

     报文格式:68 len 功能码  数据0 数据1 数据n......校验  16,

    根据这个报文格式,我们来分析一下怎样判断一帧数据是否接收完成。可以根据以下以下几个判据来判断。

   1,首先收到的第一字节个的数据必须是0x68,如果是0X68那么表明一帧接收开始。否则则认为接收到一个错误数据。抛弃该数据。

   2,接收第二个字节,验证条件必须是len<MAX_RXBUF-2. 否则则认为接收的数据错误。因为如果len>MAX_RXBUF-2会使接收的缓冲区溢出。造成系统错误,甚至系统崩溃。

    3,是否接收到len个数据?如果是检查校验位是否正确,否则接收该数据。并且检查该数据是否是0X16,判断数据正确性。如果正确置接收数据成功标志。一帧数据接收完成。

  串口接收数据结构如下:

    #define MAX_RXBUF  100      //接收缓冲区长度

   #define MAX_TXBUF   100     //发送缓冲区长度

   #define  REC_FRAME         1   //一帧数据接收完成

  #define  NO_REC_FRAME   0 //没有数据接收完成

    typedef  struct   UART

    {

        unsigned char RX_buf[MAX_RXBUF];

        unsigned char TX_buf[MAX_TXBUF];

       unsigned char flag;       //数据接收完成标志

       unsigned  char  RX_count;

 }

   有了以上数据结构我们来编写一下接收数据函数流程图:

  如果编写该函数代码如下:

UART   UART0={{0},{0},NO_REC_FRAME,0}       

void  recive_dat(unsigned char dat)

{

     if(UART0.RX_count==0)

    {

         if(dat==0x68)

        {

            UART0.RX_count=1;

            UART0.RX_buf[0] =0x68;

           } 

         return;

    }

       if(UART0.RX_count==1)

      {

           if(dat>MAX_RXBUF-2)

          {

                  UART0.RX_count=0;

          }

          else

        {

                 UART0.RX_count=2;

                UART0.RX_buf[1] =0xdat;

        }

         

           return;

       }

      if(UART0.RX_buf[1]== UART0.RX_count-2)

     {

          if(dat==0x16)

         {

               UART0.RX_buf[ UART0.RX_count] =0x16  ;

               UART0.flag = REC_FRAME ;        

         }

         else

         {

            UART0.flag =NO_ REC_FRAME ;   

          }

    }

  else

  {

               UART0.RX_buf[ UART0.RX_count] =dat  ;

               UART0.RX_count++ ;   

  } 

}

主函数:

  void  main(  )

  {

     //初始化函数

   ------

   -----

   while(1)

   {

        if(UART0.flag= =REC_FRAME )

      {

            exe_uart(   );                                     //处理串口数据函数

            UART0.flag= =NO_REC_FRAME;

             UART0.RX_count=0;

     }

  }

 } 

     当接收到一个完整帧数据后UART0.RX_count赋值为REC_FRAME,主函数判断UART0.flag= =REC_FRAME条件成立后便会调用    exe_uart(   )  处理接收到的数据。出具处理完成后   UART0.flag置NO_REC_FRAME, UART0.RX_count清零。可以开始接收下一帧数据了。

         这一节我们介绍了不定长数据帧的接收,其实就是怎样判断一帧数据是否接收完成。下一节我们介绍一个角度传感器的设计

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机-串口通讯变长协议编写 的相关文章

随机推荐