首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

环形队列串口(收)应用

环形队列串口(收)应用

环形缓冲区的实现原理:
环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性


void CommISR(void) interrupt 4
{


if (RI0)



{



   RI0=0;




   CommRecBuffer[CommRecBufferTail]=SBUF0;     //receive data           

   CommRecBufferTail++;

   if (CommRecBufferTail==DB_RECMAXSIZE)

   {



CommRecBufferTail=0;

   }



ComRecBufNData++;

if(ComRecBufNData>DB_RECMAXSIZE)

{

   //满了,可增加异常处理

}



}
}


unsigned char GetCommChar(void)      
{
    unsigned char temp;




temp=CommRecBuffer[CommRecBufferHead];

CommRecBufferHead++;

if (CommRecBufferHead==DB_RECMAXSIZE)

{

CommRecBufferHead=0;

}

ComRecBufNData--;

if(ComRecBufNData==0)

{

  //空了,可增加异常处理

}

return temp;
}


/***********
协议格式:EF LEN ... SUM  
**************/
void uart_appcall(void)
{


   static unsigned char xdata deal_flag=0;
   static unsigned short xdata data_count = 0;
   unsigned char xdata temp;


   while(CommRecBufferHead != CommRecBufferTail)
// ??存在一个问题,如果缓存器满了,数据还未取走
   {
       temp = GetCommChar();


       switch (deal_flag)

  {

     case 0:
//head

       if(temp == 0xEF)
        {
             ComCommand[0] = temp;
             deal_flag = 1;
         }           

   break;



   case 1:    //len
            ComCommand[1] = temp;
            deal_flag = 2;

   break;



   case 2:

   ComCommand[2+data_count] = temp;
            data_count++;   

   if(data_count >= ComCommand[1])

   {
                parse_uart_cmd(ComCommand,data_count+2);   //处理正确格式包

       deal_flag = 0;
                data_count = 0;

   }


   break;



   default:
            deal_flag = 0;

   data_count = 0;

   break;

}
   }
}
返回列表