在一些高级语言中(C++、C#等)都内置了FIFO的数据类型,在使用C语言开发嵌入式设备时,有些时候可能会用到FIFO数据结构,实现比较简单,具体可以看下面测试代码。
#ifndef __USER_FIFO_H_
#define __USER_FIFO_H_
#include <stdint.h>
/*
* 自定义调试宏。
* 1.快速切换debug版本和relese版本工程
* 2.简化打印调试语句的编写,提高开发调试效率
*/
/* debug 调试宏定义 */
#define _MY_DEBUG_ 1
#ifdef _MY_DEBUG_
#define MY_DEBUG_PRINT_INFO(...) printf(__VA_ARGS__)
#define MY_DEBUG_PRINT_VAR(X, ...) printf("file: "__FILE__", Line: %d:"X"\r\n",__LINE__,##__VA_ARGS__)
#else
#define MY_DEBUG_PRINT_INFO(...)
#define MY_DEBUG_PRINT_VAR(X, ...)
#endif
/*! fifo缓冲区类型 */
#define FIFO_TYPE int32_t
/*! fifo缓冲区满后 是否覆盖旧数据 0进行覆盖 1报错入栈失败*/
#define FIFO_COVER 0
/**
* FIFO结构体
*/
typedef struct
{
FIFO_TYPE *buff; /* FIFO 缓冲区 */
uint16_t fifoLen; /* FIFO 缓冲区有效数据长度 */
uint16_t fifoSize; /* 缓冲区大小 */
uint16_t fifoWrite; /* 缓冲区写指针 */
uint16_t fifoRead; /* 缓冲区读指针 */
}fifo_t;
void fifo_init(fifo_t *fifo, FIFO_TYPE *buff, uint16_t size);
void fifo_resert(fifo_t *fifo);
uint8_t fifo_push(fifo_t *fifo, FIFO_TYPE data);
uint8_t fifo_pop(fifo_t *fifo, FIFO_TYPE *data);
FIFO_TYPE fifo_avg(fifo_t *fifo);
#endif
#include "user_fifo.h"
/*!
* @brief fifo初始化
*
* @param fifo_t : FIFO
*
* @return 无
*
* @note 无
*
* @see fifo_t tempFifo;
* FIFO_TYPE tempBuff[20];
* fifo_init(&tempFifo, tempBuff, 20); //fifo初始化
*
* @date 2020/5/21
*/
void fifo_init(fifo_t *fifo, FIFO_TYPE *buff, uint16_t size)
{
fifo->fifoLen = 0;
fifo->fifoRead = 0;
fifo->fifoWrite = 0;
fifo->buff = buff;
fifo->fifoSize = size;
}
/*!
* @brief fifo复位
*
* @param fifo_t : FIFO
*
* @return 无
*
* @note 无
*
* @see fifo_t tempFifo;
* fifo_resert(&tempFifo); //fifo复位
*
* @date 2020/5/21
*/
void fifo_resert(fifo_t *fifo)
{
fifo->fifoLen = 0;
fifo->fifoRead = 0;
fifo->fifoWrite = 0;
}
/*!
* @brief fifo压入数据
*
* @param fifo_t : FIFO
* @param data : 入栈数据
*
* @return 0 :成功 1 :失败
*
* @note FIFO_COVER 宏定义进行判断缓冲区满后的操作
*
* @see fifo_t tempFifo;
* fifo_push(&tempFifo, 120); //fifo中压入一个数据
*
* @date 2020/5/21
*/
uint8_t fifo_push(fifo_t *fifo, FIFO_TYPE data)
{
fifo->fifoLen++;
/* 判断缓冲区是否已满 */
if(fifo->fifoLen > fifo->fifoSize)
{
fifo->fifoLen = fifo->fifoSize;
#if FIFO_COVER
MY_DEBUG_PRINT_INFO("入栈失败,缓冲区已满! \r\n");
return 1;
#else
if(++fifo->fifoRead >= fifo->fifoSize)
{
fifo->fifoRead = 0;
}
#endif
}
fifo->buff[fifo->fifoWrite] = data;
if(++fifo->fifoWrite >= fifo->fifoSize)
{
fifo->fifoWrite = 0;
}
return 0;
}
/*!
* @brief fifo弹出数据
*
* @param fifo_t : FIFO
* @param data : 出栈数据
*
* @return 0 :成功 1 :失败
*
* @note 无
*
* @see fifo_t tempFifo;
* FIFO_TYPE tempData;
* fifo_push(&tempFifo, 120); //fifo中压入一个数据
* fifo_pop(&tempFifo, &tempData); //fifo中弹出一个数据
*
* @date 2020/5/21
*/
uint8_t fifo_pop(fifo_t *fifo, FIFO_TYPE *data)
{
/* 缓冲区为空 */
if(fifo->fifoLen == 0)
{
// MY_DEBUG_PRINT_INFO("出栈失败,缓冲区为空! \r\n");
return 1;
}
fifo->fifoLen--;
*data = fifo->buff[fifo->fifoRead];
if(++fifo->fifoRead >= fifo->fifoSize)
{
fifo->fifoRead = 0;
}
return 0;
}
FIFO_TYPE fifo_avg(fifo_t *fifo)
{
FIFO_TYPE tmp = 0;
// for(int i = 0; i < fifo->fifoLen; i++)
// {
// tmp += fifo->buff[i];
// }
// return tmp/(fifo->fifoLen);
int32_t max = fifo->buff[0], min = fifo->buff[0];
for(int i = 0; i < fifo->fifoLen; i++)
{
tmp += fifo->buff[i];
if(fifo->buff[i] > max)
{
max = fifo->buff[i];
}
if(fifo->buff[i] < min)
{
min = fifo->buff[i];
}
}
/* 剔除最大 最小值 */
if(fifo->fifoLen > 3)
{
tmp -= max;
tmp -= min;
return tmp/(fifo->fifoLen-2);
}
return tmp/(fifo->fifoLen);
}