循环队列 C语言
本文地址:http://tongxinmao.com/Article/Detail/id/153
#ifndef __fifo_h__
#define __fifo_h__
#include <stdint.h>
typedef uint8_t ELETYPE;
typedef volatile struct queue
{
uint16_t front; //指向队列第一个元素
uint16_t rear; //指向队列最后一个元素的下一个元素
uint16_t size; //循环队列的最大存储空间
ELETYPE *pBase;
}QUEUE,*PQUEUE;
QUEUE extern printerQueue;
QUEUE extern piQueue;
void CreateQueue(PQUEUE Q,ELETYPE* buf,uint16_t maxsize);
uint8_t FullQueue(QUEUE Q);
uint8_t EmptyQueue(QUEUE Q);
uint16_t SizeQueue(QUEUE);
uint8_t Enqueue(PQUEUE Q, ELETYPE val);
uint8_t Dequeue(PQUEUE Q, ELETYPE *val);
#endif
#include "fifo.h"
#include <stdio.h>
#define RBSIZE 3000u
static ELETYPE printerFifoBuf[RBSIZE];
static ELETYPE piFifoBuf[RBSIZE];
QUEUE printerQueue;
QUEUE piQueue;
void appFifoInit(void)
{
//fifo_init(&printerFifo,printerFifoBuf,RBSIZE);
//fifo_init(&piFifo,piFifoBuf,RBSIZE);
CreateQueue(&printerQueue,printerFifoBuf,RBSIZE);
CreateQueue(&piQueue,piFifoBuf,RBSIZE);
}
/***********************************************
Function: Create a empty stack;
************************************************/
void CreateQueue(PQUEUE Q,ELETYPE* buf,uint16_t maxsize)
{
Q->pBase=buf;
Q->rear=0; //初始化参数
Q->front=0;
Q->size=maxsize;
}
uint8_t FullQueue(QUEUE Q )
{
return (Q.rear)%Q.size==Q.front?1:0;
}
uint8_t EmptyQueue(QUEUE Q)
{
return Q.rear==Q.front?1:0;
}
uint8_t Enqueue(PQUEUE Q, ELETYPE e)
{
//牺牲一个单元来区分队空和队满,入队时少用一个队列单元,这是一种较为普遍的 做法,约定以“队头指针在队尾指针的下一位置作为队满的标志”,
if((Q->rear+1)%Q->size == Q->front) return 0; //队满
Q->pBase[Q->rear]=e;
Q->rear= (Q->rear+1)%Q->size; //队尾指针加 1 取模
return 1;
}
uint8_t Dequeue(PQUEUE Q, ELETYPE *e)
{
if(Q->rear == Q->front) return 0; //队空,报错
*e=Q->pBase[Q->front];
Q->front= (Q->front+1)%Q->size; //队头指针加 1 取模
return 1;
}
uint16_t SizeQueue(QUEUE Q)
{
return (Q.rear-Q.front+Q.size)%Q.size;
}
//////////////////////////////////////////////////////////////////////////////
如果使用单独变量记录队列长度,记住改写此变量一定要加临界保护!
上一篇:USB逻辑分析仪68013 描述符
下一篇:USB键盘描述符