环形队列串口(收)应用

45 篇文章 5 订阅
42 篇文章 2 订阅

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

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;
}
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值