环形队列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中运行结果

     

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值