有的单片机串口没有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中运行结果