一、FIFO
是First Input First Output的缩写,先入先出队列。
使用的场景:一般是在不同的时钟域之间的数据传输**(简单理解即:一个(读\写)快,另外的一个(读\写)慢的场景中。)
本质操作:就是将收的数据存储的一个线性的数组中,通过指针指向该数组的自加1(偏移)来遍历数据,达到读取或者写入的目的。
作用:起到缓冲环节,可防止数据的丢失。
对数据量大的进行存储,避免频繁的总线操作。并且可满足dma的操作。
在fifo中需要理解连个重要成员:
宽度:指一次写读操作的数据位数。
深度:存储多少个宽度的数据。(如:存储8个16位宽的数据)。
第一类、FIFO处理机制如下:
FIFO信息的定义:
/*
该结构体定义成员有
缓存区,
长度,
输出,
输入的计数。
*/
typedef struct fifo_t {
uint8_t *buf;
uint32_t size;
uint32_t in;
uint32_t out;
} _fifo_str;
#define min(x,y) ((x) < (y)?(x):(y))
1、初始化FIFO
fifo_str fifo_str;
int FifoInit(uint8_t *fifo_addr, uint32_t fifo_size)//初始化fifo
{
_fifo_str *p = &fifo_str;
if(fifo_addr == NULL || fifo_size == 0)//判断数据是否为空
return -1;
memset((char *)p, 0, sizeof(_fifo_str));//初始化结构体
p->buf = fifo_addr;//对应宽度
p->in = 0;//输入计数
p->out = 0;//输出计数
p->size = fifo_size;//对应深度
return 0;
}
2、数据的长度获取
//数据的实际使用数据空间长度
int FifoDataLen(void)
{
_fifo_str *p = &fifo_str;
return (p->in - p->out);//输入计数-输出计数
}
//剩余数据空间长度
int FifoSpaceLen(void)
{
_fifo_str *p = &fifo_str;
return (p->size - (p->in - p->out));//定义长度-(实际长度)
}
3、FIFO的进和出处理
//获取fifo数据
//数据的内容缓存区,要读的长度
int FifoRead(uint8_t *buf, uint32_t len)
{
uint32_t i = 0, j = 0;
_fifo_str *p = &fifo_str;
j = (p->out % p->size);//获取剩余空间长度未读量
len = min(len, p->in - p->out);//防止长度为超出实际拥有的数据长度,即让读取的长度在 (0<设定len<定义的缓存区长度len )这间的实际长度
i = min(len, p->size - j);//获取实际内容的长度,的数据长度
memcpy(buf, p->buf + j, i);//将数据通道里的数据拷贝给缓存区
memcpy(buf + i, p->buf, len - i);//将未有数据的区域存入,对应为写入数据的区域数据(即,有数据的填数据,没数据的地方补0)
p->out += len;//已读的数据量
return len;//实际读到的数据长度
}
//对fifo写入数据
int FifoWrite(uint8_t *buf, uint32_t len)
{
uint32_t i = 0, j = 0;
_fifo_str *p = &fifo_str;
j = p->in % p->size;//获取要写入的剩余空间长度
len = min(len, p->size - p->in + p->out);//得到实际写入的长度
i = min(len, p->size - j);//实际写入数据的长度
memcpy(p->buf + j, buf, i);//将写入的数据的内容拷贝值数据中。
memcpy(p->buf, buf + i, len - i);//补充多余空间的内容
p->in += len;//记录实际写入数据的数量
return len;//返回写入的长度
}
4、置位记录量
//清空fifo 中的记录量
void FifoClear(void)
{
_fifo_str *p = &fifo_str;
p->in = 0;
p->out = 0;
}
5、应用处理机制
#define LEN 2048
uint8_t pdata[LEN] = {
0};
FifoInit(pdata, LEN);//初始化FIFO
uint8_t buf[32] = {
0};
int tx_len = 0;
uint8_t tx_buf[100] = {
0};
HAL_UART_Receive_IT(&huart1, buf, IT_LEN