/*****************************************************************************************
filename: modfifo.h
文件功能:实现简单的FIFO功能
策 略:PUT时,若FIFO满,则不能载入后来的数据。
GUT时,按先入先出原则
编译环境:VS2005 keil V4.14
编 者:张永辉 2012年11月28日
修 改:张永辉 2013年03月04日
修 改:张永辉 2013年03月07日 ModFifoDataNumGet()函数
*****************************************************************************************/
#ifndef __MOD_FIFO_H
#define __MOD_FIFO_H
/****************************************************************************************/
#define MOD_FIFO_LEN 5 //FIFO长度 字节
#define MOD_FIFO_TYPE unsigned char //FIFO数据类型
#define MOD_FIFO_NUM_TYPE unsigned int //FIFO数据计数器类型
void ModFifoInit(void);
void ModFifoTest(void);
MOD_FIFO_NUM_TYPE ModFifoPut (MOD_FIFO_TYPE* buff, MOD_FIFO_NUM_TYPE len);
MOD_FIFO_NUM_TYPE ModFifoGet (MOD_FIFO_TYPE* buff, MOD_FIFO_NUM_TYPE len);
MOD_FIFO_NUM_TYPE ModFifoPutByte(MOD_FIFO_TYPE buff);
MOD_FIFO_NUM_TYPE ModFifoGetByte(MOD_FIFO_TYPE* buff);
MOD_FIFO_NUM_TYPE ModFifoDataNumGet(void);
/*****************************************************************************************/
#endif
/*****************************************************************************************
filename:modfifo.c
文件功能:实现简单的FIFO功能
策 略:PUT时,若FIFO满,则不能载入后来的数据。
GUT时,按先入先出原则
*****************************************************************************************/
#include "modfifo.h"
struct fifo
{
MOD_FIFO_TYPE FifoBuffer[MOD_FIFO_LEN];
MOD_FIFO_NUM_TYPE FifoNum; //FIFO未取走的数据个数
MOD_FIFO_NUM_TYPE FifoIn; //指向下次要放入数据的地方。
MOD_FIFO_NUM_TYPE FifoOut; //指向下次要取出数据的地方。
}ModFifo;
/*****************************************************************************************
函数功能: 测试函数
*****************************************************************************************/
void ModFifoTest(void)
{
MOD_FIFO_TYPE inp[MOD_FIFO_LEN+1] = {'1','2','3','4','5'};
MOD_FIFO_TYPE oup[MOD_FIFO_LEN+1];
MOD_FIFO_TYPE out;
MOD_FIFO_TYPE i = 0;
ModFifoInit();
for (i = 0;i < MOD_FIFO_LEN + 2;i++)
{
ModFifoPutByte(i);
}
for (i = 0;i < MOD_FIFO_LEN + 2;i++)
{
ModFifoGetByte(&out);
}
ModFifoPutByte(99);
ModFifoPutByte(23);
ModFifoGetByte(&out);
ModFifoGetByte(&out);
ModFifoGetByte(&out);
ModFifoPut(inp,3);
ModFifoGetByte(&out);
ModFifoPut(inp,5);
ModFifoGet(oup,5);
while(1);
}
/*****************************************************************************************
函数功能: 初始化函数
使用前,先调用此函数
*****************************************************************************************/
void ModFifoInit(void)
{
//初始化
ModFifo.FifoNum = 0;
ModFifo.FifoIn = 0;
ModFifo.FifoOut = 0;
}
/*****************************************************************************************
向FIFO存入一串数据
参数:buff 要存的数据的地址
len 数据长度
返回:成功存入数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoPut (MOD_FIFO_TYPE* buff, MOD_FIFO_NUM_TYPE len)
{
MOD_FIFO_NUM_TYPE i;
if(ModFifo.FifoNum >= MOD_FIFO_LEN)
{
return 0;
}
i = MOD_FIFO_LEN - ModFifo.FifoNum;
len = (len < i)?len:i; //取最小值
for (i = 0;i<len;i++)
{
ModFifo.FifoBuffer[ModFifo.FifoIn] = *buff++;
if (++ModFifo.FifoIn >= MOD_FIFO_LEN)
{
ModFifo.FifoIn = 0;
}
}
ModFifo.FifoNum += len;
return len;
}
/*****************************************************************************************
从FIFO获取一个数据
参数:buff 要存数据的地址
返回:取得数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoGet (MOD_FIFO_TYPE* buff, MOD_FIFO_NUM_TYPE len)
{
MOD_FIFO_NUM_TYPE i;
//LOCK
if(ModFifo.FifoNum <= 0)
{ //UNLOCK
return 0; //空的,直接返回
}
len = (len < ModFifo.FifoNum)?len:ModFifo.FifoNum; //取最小值
for (i = 0;i<len;i++)
{
*buff++ = ModFifo.FifoBuffer[ModFifo.FifoOut];
if (++ModFifo.FifoOut >= MOD_FIFO_LEN)
{
ModFifo.FifoOut = 0;
}
}
ModFifo.FifoNum -= len;
return len;
}
/*****************************************************************************************
向FIFO存入一个数据
参数:buff 要存的数据
返回:成功存入数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoPutByte(MOD_FIFO_TYPE buff)
{
//LOCK
//若此处无锁,若2线程同时 达到此处,都判断到未,同时加入数据则出问题了。
if(ModFifo.FifoNum >= MOD_FIFO_LEN)
{
return 0;
}
//UNLOCK
ModFifo.FifoBuffer[ModFifo.FifoIn] = buff;
if (++ModFifo.FifoIn >= MOD_FIFO_LEN)
{
ModFifo.FifoIn = 0;
}
ModFifo.FifoNum++;
return 1;
}
/*****************************************************************************************
从FIFO获取一个数据
参数:buff 要存数据的地址
返回:取得数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoGetByte(MOD_FIFO_TYPE* buff)
{
//LOCK
if(ModFifo.FifoNum <= 0)
{ //UNLOCK
return 0; //空的,直接返回
}
*buff = ModFifo.FifoBuffer[ModFifo.FifoOut];
if (++ModFifo.FifoOut >= MOD_FIFO_LEN)
{
ModFifo.FifoOut = 0;
}
ModFifo.FifoNum--;
return 1;
}
/*****************************************************************************************
查询FIFO中已有数据个数
参数:无
返回:数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoDataNumGet(void)
{
return ModFifo.FifoNum;
}