- UID
- 1023166
- 性别
- 男
- 来自
- 燕山大学
|
环形缓冲区的实现原理:
环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性
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;
}
}
} |
|