概要
为了防止数据被覆盖,使用环形缓冲区。
整体思路
首先,环形缓冲区需要读位置r和写位置w;如何判断环形缓冲区可读和可写?
初始化时,r和w都等于0,即环形缓冲区为空,
那么在读数据时,只要环形缓冲区为非空就可读,故当r != w时,可读;
而要想写数据,只要环形缓冲区未满,
但是写位置到达环形缓冲区长度时,会回到0位置,若自始至终未读,此时r = w = 0,与空状态一致,故需使用下一个写位置的状态来判断是否未满,当未满时,即可写数据。
代码分析
头文件
#include "main.h"
#ifndef __BUFFER_H
#define __BUFFER_H
typedef struct buffer{
uint32_t w;//写位置
uint32_t r;//读位置
uint32_t len;//环形缓冲区长度
uint32_t next_w;//下一个写位置
uint8_t *CircleBuf;//环形缓冲区
}circle_buffer,*pCircle_Buf;
void Circle_Buffer_Init(pCircle_Buf buffer,uint32_t len,uint8_t *buf);//环形缓冲区初始化
int Circle_Read(pCircle_Buf buffer,uint8_t *pVal);//环形缓冲区读函数
int Circle_Write(pCircle_Buf buffer,uint8_t val);//环形缓冲区写函数
#endif
c文件
#include"circle_buffer.h"
void Circle_Buffer_Init(pCircle_Buf buffer,uint32_t len,uint8_t *buf)//环形缓冲区初始化
{
buffer->w = 0;
buffer->r = 0;
buffer->len = len;
buffer->CircleBuf = buf;
}
int Circle_Read(pCircle_Buf buffer,uint8_t *pVal)//环形缓冲区读函数
{
if(buffer->r != buffer->w)//如果读的位置不等于写的位置,即环形缓冲区非空,可读
{
*pVal = buffer->CircleBuf[buffer->r];//读取当前读位置的数据
buffer->r++;
if(buffer->r == buffer->len)//如果读位置到达环形缓冲区的长度
{
buffer->r = 0;//从头开始读
}
return 0;//正确返回0
}
else
{
return -1;//错误返回-1
}
}
int Circle_Write(pCircle_Buf buffer,uint8_t val)//环形缓冲区写函数
{
buffer->next_w = buffer->w + 1;
if(buffer->next_w == buffer->len)//如果下一个写位置等于环形缓冲区的长度
buffer->next_w = 0;//下一个写位置到达最初的头位置
if(buffer->next_w != buffer->r)//如果下一个写位置不等于读位置,即环形缓冲区未满,可写
{
buffer->CircleBuf[buffer->w] = val;//将数据写入当前写位置
buffer->w = buffer->next_w;
return 0;//正确返回0
}
else
{
return -1;//正确返回-1
}
}