串口接收二维数组环形缓冲队列
51单片机使用此方法可能效果不大。
此二维数组环形缓冲队列是我从一维数组环形缓冲队列改编而来,与一维数组理念相同。但是对于数据的处理要更加的方便。
环形缓冲区就是一个带“头指针”和“尾指针”的数组。“头指针”指向环形缓冲区中可读的数据,“尾指针”指向环形缓冲区中可写的缓冲空间。通过移动“头指针”和“尾指针”就可以实现缓冲区的数据读取和写入。在通常情况下,应用程序读取环形缓冲区的数据仅仅会影响“头指针”,而串口接收数据仅仅会影响“尾指针”。当串口接收到新的数组,则将数组保存到环形缓冲区中,同时将“尾指针”加1,以保存下一个数据;应用程序在读取数据时,“头指针”加1,以读取下一个数据。当“尾指针”超过数组大小,则“尾指针”重新指向数组的首元素,从而形成“环形缓冲区”!,有效数据区域在“头指针”和“尾指针”之间。
环形缓冲区就是一个带“头指针”和“尾指针”的数组。“头指针”指向环形缓冲区中可读的数据,“尾指针”指向环形缓冲区中可写的缓冲空间。通过移动“头指针”和“尾指针”就可以实现缓冲区的数据读取和写入。在通常情况下,应用程序读取环形缓冲区的数据仅仅会影响“头指针”,而串口接收数据仅仅会影响“尾指针”。当串口接收到新的数组,则将数组保存到环形缓冲区中,同时将“尾指针”加1,以保存下一个数据;应用程序在读取数据时,“头指针”加1,以读取下一个数据。当“尾指针”超过数组大小,则“尾指针”重新指向数组的首元素,从而形成“环形缓冲区”!,有效数据区域在“头指针”和“尾指针”之间。
typedef struct rcv_buff
{
unsigned char pop_head;
unsigned char pop_tail;
unsigned char buf[10][50];
}rh_bluebuff_t;
rh_bluebuff_t rh_buff;
void Uart2() interrupt 8 using 1
{
int i = 0;
if(S2CON & S2RI)
{
S2CON &= ~S2RI; //清除S2RI位
buff_write(S2BUF);
// P2 = (S2CON & S2RB8); //P2.2显示校验位
}
if(S2CON & S2TI)
{
S2CON &= ~S2TI; //清除S2TI位
busy = 0; //清忙标志
}
}
void buff_write(unsigned char data_t)
{
unsigned char _temp;
if(data_t != '\n')
{
rh_buff.buf[rh_buff.pop_tail][buf_count] = data_t; //从尾部追加
buf_count++;
if(buf_count>=50) buf_count = 49;
}
else
{
rh_buff.buf[rh_buff.pop_tail][buf_count] = data_t; //从尾部追加
buf_count = 0;
#if 1
_temp = (rh_buff.pop_tail + 1); //_temp = (rh_buff.pop_tail + 1) % 10; stc不能取余
if(_temp >= 10) _temp = 0;
if(_temp != rh_buff.pop_head)
{
rh_buff.pop_tail = _temp;
}
#else
if(++rh_buff.pop_tail >= 10) //尾节点偏移
rh_buff.pop_tail=0; //大于数组最大长度 归零 形成环形队列
if(rh_buff.pop_tail == rh_buff.pop_head)//如果尾部节点追到头部节点,则修改头节点偏移位置丢弃早期数据
{
if(++rh_buff.pop_head >= 10)
{
rh_buff.pop_head = 0;
}
}
#endif
}
}
unsigned char buff_read(unsigned char *data_t)
{
if(rh_buff.pop_head == rh_buff.pop_tail) //如果头尾接触表示缓冲区为空
{
return 1; //返回1,环形缓冲区是空的
}
else
{
memcpy(data_t, &rh_buff.buf[rh_buff.pop_head][0], 50);
memset(&rh_buff.buf[rh_buff.pop_head][0], 0, 50);
if(++rh_buff.pop_head >= 10)
{
rh_buff.pop_head = 0;
}
return 0; //返回0,表示读取数据成功
}
}