环形队列FIFO实现方法

         有的单片机串口没有FIFO,或者可分配的FIFO大小是非常有限的,如果在程序中需要向外设发送一个很大的数据包,需要很长的时间,为了解决应用程序与外设硬件读写同步的问题,很有必要自己实现环形FIFO。

#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;

#define  ERROR_FULL_W  -1
#define  ERROR_EMPTY_R  -2

#define  TRUE   0
#define  FULL   1
#define  EMPTY  1
#define  UCHAR unsigned char
#define  UINT  unsigned int

一、环形FIFO的定义

struct Fifo{
  UCHAR *m_buf;     
  UINT m_bufsize;   
  UINT m_wp;          
  UINT m_rp;           
  UINT fullflag;    
  UINT emptyflag; 
};
typedef struct Fifo CFifo;

二、写入队列

 int fFifoPush(CFifo *myfifo, UCHAR c){
      UINT tmp_len;
      if(myfifo->fullflag != FULL){
         tmp_len = myfifo->m_wp;    
         myfifo->m_buf[tmp_len] = c; 
         tmp_len++;  
         if (tmp_len >= myfifo->m_bufsize) tmp_len = 0;                                     
         if (tmp_len == myfifo->m_rp) {
            myfifo-> fullflag = FULL;
         }
      myfifo->m_wp = tmp_len;
      myfifo-> emptyflag = !EMPTY;
      return TRUE; 
     }

   else return ERROR_FULL_W ; 
}

3.从队列中读出数据

int fFifoPop(CFifo *myfifo, int *data){
     UINT tmp_len;     
     UCHAR tmp_char;
     if(myfifo->emptyflag != EMPTY){
         tmp_len = myfifo->m_rp;
         tmp_char = myfifo->m_buf[tmp_len];    
         *data = tmp_char;
         tmp_len++;     
         if (tmp_len >= myfifo->m_bufsize) tmp_len = 0;
            myfifo->m_rp = tmp_len;
         if (tmp_len == myfifo->m_wp) { 
            myfifo->emptyflag = EMPTY;
          }
    myfifo-> fullflag = !FULL;
    return TRUE;
     }
  else  return ERROR_EMPTY_R;
}

4.计算队列中数据长度

UINT fFifoCheckLen(CFifo *myfifo){

    if(myfifo->emptyflag == EMPTY)      return 0;
    else if(myfifo->fullflag == FULL)   return myfifo->m_bufsize;
    if(myfifo->m_wp >= myfifo->m_rp ){
    return myfifo->m_wp - myfifo->m_rp ; 
 }
 else{
       return myfifo->m_bufsize - myfifo->m_rp + myfifo->m_wp;
       }
}

5.清空队列     

void fFifoEmpty(CFifo *myfifo){
    myfifo->m_wp = 0;    
    myfifo->m_rp = 0; 
    myfifo->emptyflag = EMPTY;
    myfifo->fullflag = !FULL;

6.初始化队列

void fFifoInit(CFifo *myfifo, UCHAR *tmp_buf, UINT tmp_size){
    myfifo->m_buf = tmp_buf;
    myfifo->m_bufsize = tmp_size;
    fFifoEmpty(myfifo); 
}

7.测试队列

int main(void){
    CFifo *myfifo;
    UCHAR  cnt = 0;
    int i = 0;
    int data = 0;

    if((myfifo = (CFifo *)calloc(1,sizeof(CFifo))) == NULL){
      cout<<"malloc failed"<<endl;
    } 
    UCHAR data_buf[20];
    fFifoInit(myfifo,data_buf,20);

    for(i = 0; i<21;i++){
        if(fFifoPush(myfifo,i*2) == TRUE)
            cout<<"The push data is "<<i*2<<" the lengh is "<<fFifoCheckLen(myfifo)<<endl;
       else break;
 }
    for(i = 0; i<22;i++){
         if(fFifoPop(myfifo, &data) == TRUE)
            cout<<"The pop data is "<<data<<"the lengh is"<<fFifoCheckLen(myfifo)<<endl;
      else break;
 }
}

 8.在VC6.0中运行结果

     

 

 

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
实现一个环形队列需要以下步骤: 1. 定义队列数组和队头、队尾指针 ```c #define QUEUE_SIZE 5 unsigned char queue[QUEUE_SIZE]; unsigned char head = 0, tail = 0; ``` 2. 实现入队操作 ```c void enQueue(unsigned char data) { if ((tail + 1) % QUEUE_SIZE == head) // 队列已满 { // 处理队列已满情况 return; } queue[tail] = data; tail = (tail + 1) % QUEUE_SIZE; // 队尾指针后移一位 } ``` 3. 实现出队操作 ```c unsigned char deQueue() { if (head == tail) // 队列为空 { // 处理队列为空情况 return 0; } unsigned char data = queue[head]; head = (head + 1) % QUEUE_SIZE; // 队头指针后移一位 return data; } ``` 4. 测试代码 ```c #include <reg52.h> void enQueue(unsigned char data); unsigned char deQueue(); void main() { unsigned char data; enQueue('A'); enQueue('B'); enQueue('C'); data = deQueue(); data = deQueue(); enQueue('D'); enQueue('E'); data = deQueue(); data = deQueue(); data = deQueue(); data = deQueue(); data = deQueue(); } void enQueue(unsigned char data) { if ((tail + 1) % QUEUE_SIZE == head) // 队列已满 { // 处理队列已满情况 return; } queue[tail] = data; tail = (tail + 1) % QUEUE_SIZE; // 队尾指针后移一位 } unsigned char deQueue() { if (head == tail) // 队列为空 { // 处理队列为空情况 return 0; } unsigned char data = queue[head]; head = (head + 1) % QUEUE_SIZE; // 队头指针后移一位 return data; } ``` 在上述代码中,我们先入队了三个元素,然后出队两个元素,再入队两个元素,最后出队所有元素。运行该代码可以得到以下结果: ``` data = 'A' data = 'B' data = 'D' data = 'E' 队列为空 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值