参考了 https://blog.csdn.net/weixin_30407613/article/details/97446678
添加了读取队列状态函数,并将读取队列状态与对队列的实际操作分离,需要先判断队列是否可操作,然后再对其进行操作,原函数是直接进行操作,然后返回的操作结果。
修改了主函数,对其进行了测试。
Queue.c
#include "Queue.h"
/*******************************************************************************
* 函数名称: QueueInit
* 说 明: FIFO队列初始化
* 输入参数: pdI_Queue 要初始化的队列
* pdI_Prmt 队列的初始化参数
* 输出参数: 无
* 返回值 : 无
* 其 它:
*******************************************************************************/
void QueueInit(QueueDef *pdI_Queue, QueueCfgPrmtDef* pdI_Prmt)
{
pdI_Queue->rear = 0;
pdI_Queue->front = pdI_Queue->rear;//初始化时队列头队列首相连
pdI_Queue->count = 0;//队列计数为0
pdI_Queue->elemSize = pdI_Prmt->elemSize;
pdI_Queue->queueCnt = pdI_Prmt->queueCnt;
pdI_Queue->pdat = pdI_Prmt->paddr;
}
/*******************************************************************************
* 函数名称: QueueCheck
* 说 明: 检查FIFO队列状态
* 输入参数: pdI_Queue 目标队列
* 输出参数: 无
* 返回值 :
_QueueFull: 队列满
_QueueEmpty: 队列空
_QueueOperateOk:队列不空,也不满
* 其 它:
*******************************************************************************/
QueueResult QueueCheck(QueueDef *pdI_Queue)
{
if ((pdI_Queue->front == pdI_Queue->rear) && (pdI_Queue->count == pdI_Queue->queueCnt))//如果队列满了
{
return _QueueFull;//返回队列满的标志
}
else if ((pdI_Queue->front == pdI_Queue->rear) && (pdI_Queue->count == 0)) // 如果队列空
{
return _QueueEmpty;
}
return _QueueOperateOk;//允许操作
}
/*******************************************************************************
* 函数名称: QueueIn
* 说 明: FIFO队列插入一个元素
* 输入参数: pdI_Queue 操作的队列
* pvI_Dat 插入的元素
* 输出参数: 操作结果 队列满或者成功
* 返回值 :
* 其 它:
*******************************************************************************/
void QueueIn(QueueDef *pdI_Queue, void* pvI_Dat)
{
u8* operatAddr = (u8*)pdI_Queue->pdat;
operatAddr += pdI_Queue->rear * pdI_Queue->elemSize;
memcpy(operatAddr, pvI_Dat, pdI_Queue->elemSize);
pdI_Queue->rear = (pdI_Queue->rear + 1) % pdI_Queue->queueCnt;
pdI_Queue->count = pdI_Queue->count + 1;
}
/*******************************************************************************
* 函数名称: QueueOut
* 说 明: 从FIFO队列中取出一个元素
* 输入参数: pdI_Queue 操作的队列
* 输出参数: pvI_Dat 取出的元素
* 返回值 : 操作结果 队列空或者成功
* 其 它:
*******************************************************************************/
void QueueOut(QueueDef *pdI_Queue, void* pvI_Dat)
{
u8* operatAddr = (u8*)pdI_Queue->pdat;
operatAddr += pdI_Queue->front * pdI_Queue->elemSize;
memcpy(pvI_Dat, operatAddr, pdI_Queue->elemSize);
pdI_Queue->front = (pdI_Queue->front + 1) % pdI_Queue->queueCnt;
pdI_Queue->count = pdI_Queue->count - 1;
}
Queue.h
#ifndef _Queue_H
#define _Queue_H
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
typedef struct QueueDef_ //队列对象定义
{
u16 front; //队列头部
u16 rear; //队列尾部
u16 count; //对列计数
u16 elemSize; //元素大小
u16 queueCnt; //队列大小
void * pdat; //指向队列数据区
}QueueDef;
typedef struct QueueCfgPrmtDef_ //队列初始化参数
{
u16 elemSize; //元素大小
u16 queueCnt; //队列大小
u8* paddr; //指向队列数据区
}QueueCfgPrmtDef;
typedef enum QueueResult_ //队列操作执行结果
{
_QueueFull = 0, //FIFO满置0
_QueueEmpty = 1, //FIFO空置1
_QueueOperateOk = 2 //队列操作完成 赋值为2
}QueueResult;
/*******************************************************************************
* 函数名称: QueueInit
* 说 明: FIFO队列初始化
* 输入参数: pdI_Queue 要初始化的队列
* pdI_Prmt 队列的初始化参数
* 输出参数: 无
* 返回值 : 无
* 其 它:
*******************************************************************************/
void QueueInit(QueueDef *pdI_Queue, QueueCfgPrmtDef *pdI_Prmt);
/*******************************************************************************
* 函数名称: QueueCheck
* 说 明: 读取FIFO队列状态
* 输入参数: pdI_Queue 目标队列
* 输出参数: 无
* 返回值 :
_QueueFull: 队列满
_QueueEmpty: 队列空
_QueueOperateOk:不空,也不满
* 其 它:
*******************************************************************************/
QueueResult QueueCheck(QueueDef *pdI_Queue) ;
/*******************************************************************************
* 函数名称: QueueIn
* 说 明: FIFO队列插入一个元素
* 输入参数: pdI_Queue 操作的队列
* pvI_Dat 插入的元素
* 输出参数: 操作结果 队列满或者成功
* 返回值 :
* 其 它:
*******************************************************************************/
void QueueIn(QueueDef *pdI_Queue, void* pvI_Dat);
/*******************************************************************************
* 函数名称: QueueOut
* 说 明: 从FIFO队列中取出一个元素
* 输入参数: pdI_Queue 操作的队列
* 输出参数: 操作结果 队列空或者成功
* 返回值 : pvI_Dat 取出的元素
* 其 它:
*******************************************************************************/
void QueueOut(QueueDef *pdI_Queue, void* pvI_Dat);
#endif
main.c
#include "Queue.h"
#include "stdio.h"
typedef struct ElemTypeDef_
{
u8 e1;
u16 e2;
u32 e3;
}ElemTypeDef;
QueueDef MyQueue;
ElemTypeDef MyQueueData[10];
int main(void)
{
ElemTypeDef sh;
QueueCfgPrmtDef prmt;
u16 i;
prmt.elemSize = sizeof(ElemTypeDef);
prmt.queueCnt = sizeof(MyQueueData) / sizeof(ElemTypeDef);
prmt.paddr = (u8*)MyQueueData;
QueueInit(&MyQueue, &prmt);
printf("加载数据\r\n");
for (i = 0; i < 20; i++)
{
sh.e1=i;
sh.e2=i*2;
sh.e3=i*3;
if (QueueCheck(&MyQueue) != _QueueFull) //队列未满,允许操作
{
QueueIn(&MyQueue,&sh);
printf("e1=%d,e2=%d,e3=%d\r\n",sh.e1,sh.e2,sh.e3);
}
else
{
printf("加载完成\r\n");
break;//队列满了
}
}
for (i = 0; i < 20; i++)
{
sh.e1=0;
sh.e2=0;
sh.e3=0;
}
printf("开始输出\r\n");
for (i = 0; i < 20; i++)
{
if (QueueCheck(&MyQueue) != _QueueEmpty) //队列未空,允许操作
{
QueueOut(&MyQueue,&sh);
printf("e1=%d,e2=%d,e3=%d\r\n",sh.e1,sh.e2,sh.e3);
}
else
{
printf("输出完成\r\n");
break;//队列空了
}
}
return 0;
}
运行结果