环形队列FIFO
来源:互联网 发布:base64解码 java代码 编辑:程序博客网 时间:2024/06/05 06:43
建立自己的缓存区,可以有序的发送接收数据,不担心数据丢失,可以有序地处理。
// -----------------------------------------------------------------------------// File Name : fifo.h// Title : General FIFO template// Author : Seeseawe - Copyright (C) 2008// Created : 2008-4-2// Version : 0.3// Target MCU : Any// Editor Tabs : 4// Editor Line : 80 chars/line// -----------------------------------------------------------------------------// Overview:/* This template provides a convenient way to create a FIFO circular buffer.*/// Version History:/* >>>2008-4-6: V0.3 is released. C: Changed data type of FIFO position pointer. >>>2008-4-3: V0.2 is released. +: FIFO_DUMP_DATA(FifoName, Num); +: FIFO_PUT_STR(FifoName, ptrData, Num); +: FIFO_GET_STR(FifoName, ptrData, Num); +: FIFO_PUTS(FifoName, "TxtString"); +: FIFO_##__NAME##_PutOneInt(Data); +: FIFO_##__NAME##_GetOneInt(ptrData); -: None C: Changed FIFO_PEEK_ONE(ptrData) to FIFO_PEEK_ONE(ptrData, index). >>>2008-4-2: V0.1 is released.*/#ifndef __FIFO_H__#define __FIFO_H__/* *********************************************************** 模板库说明:环形队列模板 ** 版本: v1.00beta ** 作者: 王卓然(OurAVR 傻孩子) ** 创建日期: 2008年1月19日 ** -------------------------------------------------------- ** [使用说明] *假设我想建立一个UART接收缓冲区,我们需要首先在UART模块的C文件里创建一个环形队列,名叫UART_RxFifo,大小为128个字节: NEW_FIFO(UART_RxFifo, 128, uint8, uint8);然后,在UART模块的头文件里导出该FIFO的API: EXPORT_FIFO_API(UART_RxFifo, 128, uint8, uint8);接下来,我们可以通过以下两种方法访问这个队列 // 加一个数据Data到UART_RxFifo 1. FIFO_PUT_ONE(UART_RxFifo, Data); 2. FIFO_UART_RxFifo_PutOne(Data); // 从ptrData处取出Num个数据,放入UART_RxFifo: 1. FIFO_PUT_STR(UART_RxFifo, ptrData, Num); 2. FIFO_UART_RxFifo_PutStr(ptrData, Num); // 从UART_RxFifo取出一个数据放到ptrData 1. FIFO_GET_ONE(UART_RxFifo, ptrData); 2. FIFO_UART_RxFifo_GetOne(ptrData); // 从UART_RxFifo取出Num个数据放到ptrData 1. FIFO_GET_STR(UART_RxFifo, ptrData, Num); 2. FIFO_UART_RxFifo_GetStr(ptrData, Num); // 偷看一眼UART_RxFifo里面index处的数据,将结果保存到ptrData 1. FIFO_PEEK_ONE(UART_RxFifo, ptrData, index); 2. FIFO_UART_RxFifo_PeekOne(ptrData); // 倒掉一些(Num个)不用的数据 1. FIFO_DUMP_DATA(UART_RxFifo, Num); 2. FIFO_UART_RxFifo_DumpData(Num); // 获取UART_RxFifo的当前数据量 1. FIFO_GET_COUNT(UART_RxFifo); 2. FIFO_UART_RxFifo_GetCount(); // 检测UART_RxFifo是否为空 1. FIFO_IS_EMPTY(UART_RxFifo); 2. FIFO_UART_RxFifo_IsEmpty(); // 将一个以'\0'结尾的字符串添加到UART_RxFifo 1. FIFO_PUTS(UART_RxFifo, "Hello World!");如果是在中断函数里面访问FIFO,应使用如下专门函数: FIFO_UART_RxFifo_PutOneInt(Data); FIFO_UART_RxFifo_GetOneInt(ptrData);NOTES: 头文件包含策略:推荐将本文件(fifo.h)包含在模块的头文件中, 这样,其他模块需要访问该fifo时,只需包含该模块的头文件即可。 如上例中: A. #include "fifo.h" // 在uart.h里面包含fifo.h B. #include "uart.h" // 在需要访问UART_RxFifo的模块中包含uart.h********************************************************** */ //\ //Bool FIFO_##__NAME##_PeekOne(__TYPE *pData, __SIZE_t Index)\ //{\ // if (Index < FIFO_##__NAME##_GetCount())\ // {\ // if ((FIFO_##__NAME##Tail + Index) >= (FIFO_##__NAME##Buffer + __SIZE))\ // *pData = *(FIFO_##__NAME##Tail + Index - __SIZE);\ // else \ // *pData = *(FIFO_##__NAME##Tail + Index);\ // return TRUE;\ // }\ // return FALSE;\ //}\ /* Dump some data of FIFO */\ //void FIFO_##__NAME##_DumpData(__SIZE_t Num)\ //{\ // _DI();\ // if (Num < FIFO_##__NAME##_GetCount())\ // {\ // FIFO_##__NAME##Tail += Num;\ // if (FIFO_##__NAME##Tail >= FIFO_##__NAME##Buffer + __SIZE) {\ // FIFO_##__NAME##Tail -= __SIZE;\ // }\ // }\ // else \ // {\ // FIFO_##__NAME##Head = FIFO_##__NAME##Buffer;\ // FIFO_##__NAME##Tail = FIFO_##__NAME##Buffer;\ // }\ // _EI();\ //}\/* ----------------------------------------------------------------------------- NAME: NEW_FIFO FUNCTION: Create a new FIFO INPUTS: __NAME: FIFO Name; __SIZE: FIFO Size; __TYPE: The data type of FIFO data member; __SIZE_t: The data type of FIFO size. OUTPUT: Methods for FIFO_PUT_ONE, FIFO_GET_ONE, FIFO_PEEK_ONE, FIFO_DUMP_DATA, FIFO_PUT_STR, FIFO_GET_STR, FIFO_PUTS, FIFO_GET_COUNT and FIFO_IS_EMPTY.----------------------------------------------------------------------------- *///#define NULL 0#define NEW_FIFO(__NAME,__SIZE,__TYPE,__SIZE_t) \ __TYPE FIFO_##__NAME##Buffer[(__SIZE)];\ __TYPE *FIFO_##__NAME##Tail = FIFO_##__NAME##Buffer;\ __TYPE *FIFO_##__NAME##Head = FIFO_##__NAME##Buffer;\ \ /* Get the current data count of FIFO outside ISR. */\ __SIZE_t FIFO_##__NAME##_GetCount(void)\ {\ __SIZE_t temp;\ _DI();\ if (FIFO_##__NAME##Head >= FIFO_##__NAME##Tail)\ temp = FIFO_##__NAME##Head - FIFO_##__NAME##Tail;\ else \ temp = FIFO_##__NAME##Head + __SIZE - FIFO_##__NAME##Tail;\ _EI();\ return temp;\ }\ \ /* Get the current Idel room count of FIFO outside ISR. */\ __SIZE_t FIFO_##__NAME##_GetIdelCount(void)\ {\ __SIZE_t temp;\ _DI();\ if (FIFO_##__NAME##Head >= FIFO_##__NAME##Tail)\ temp = ((__SIZE - 1) -(FIFO_##__NAME##Head - FIFO_##__NAME##Tail));\ else \ temp = (FIFO_##__NAME##Tail - 1 - FIFO_##__NAME##Head);\ _EI();\ return temp;\ }\ \ /* Put one data in FIFO outside ISR. */\ BOOL FIFO_##__NAME##_PutOne(__TYPE Data)\ {\ __SIZE_t DataCount;\ _DI();\ if (FIFO_##__NAME##Head >= FIFO_##__NAME##Tail)\ DataCount = FIFO_##__NAME##Head - FIFO_##__NAME##Tail;\ else \ DataCount =__SIZE + FIFO_##__NAME##Head - FIFO_##__NAME##Tail;\ _EI();\ if (DataCount < (__SIZE - 1))\ {\ _DI();\ *FIFO_##__NAME##Head = Data;\ /* "*FIFO_##__NAME##Head = Data;"需要在关中断下进行,字符型的操作可能引起错误 */\ if (FIFO_##__NAME##Head == FIFO_##__NAME##Buffer + (__SIZE - 1))\ FIFO_##__NAME##Head = FIFO_##__NAME##Buffer;\ else \ FIFO_##__NAME##Head++;\ _EI();\ return TRUE;\ }\ return FALSE;\ }\ \ /* Get one data from FIFO outside ISR. */\ BOOL FIFO_##__NAME##_GetOne(__TYPE *pData)\ {\ _DI();\ if (FIFO_##__NAME##Tail != FIFO_##__NAME##Head)\ {\ *pData = *FIFO_##__NAME##Tail;\ if (FIFO_##__NAME##Tail == FIFO_##__NAME##Buffer + (__SIZE - 1))\ FIFO_##__NAME##Tail = FIFO_##__NAME##Buffer;\ else \ FIFO_##__NAME##Tail++;\ _EI();\ return TRUE;\ }\ _EI();\ return FALSE;\ }\ /* take a look the data with Index*/\ BOOL FIFO_##__NAME##_PeekOne(__TYPE *pData, __SIZE_t Index)\ {\ if (Index < FIFO_##__NAME##_GetCount())\ {\ if ((FIFO_##__NAME##Tail + Index) >= (FIFO_##__NAME##Buffer + __SIZE))\ *pData = *(FIFO_##__NAME##Tail + Index - __SIZE);\ else \ *pData = *(FIFO_##__NAME##Tail + Index);\ return TRUE;\ }\ return FALSE;\ }\ /* Dump some data of FIFO */\ void FIFO_##__NAME##_DumpData(__SIZE_t Num)\ {\ _DI();\ if (Num < FIFO_##__NAME##_GetCount())\ {\ FIFO_##__NAME##Tail += Num;\ if (FIFO_##__NAME##Tail >= FIFO_##__NAME##Buffer + __SIZE) {\ FIFO_##__NAME##Tail -= __SIZE;\ }\ }\ else \ {\ FIFO_##__NAME##Head = FIFO_##__NAME##Buffer;\ FIFO_##__NAME##Tail = FIFO_##__NAME##Buffer;\ }\ _EI();\ }\ /* Put a string of data in FIFO */\ BOOL FIFO_##__NAME##_PutStr(__TYPE *pData, __SIZE_t Num)\ {\ if ((Num > FIFO_##__NAME##_GetIdelCount()) || (pData == NULL))\ return FALSE;\ while(Num--)\ {\ _DI();\ *FIFO_##__NAME##Head = *pData;\ if (FIFO_##__NAME##Head == FIFO_##__NAME##Buffer + (__SIZE - 1))\ FIFO_##__NAME##Head = FIFO_##__NAME##Buffer;\ else \ FIFO_##__NAME##Head++;\ pData++;\ _EI();\ }\ return TRUE;\ }\ BOOL FIFO_##__NAME##_GetStr(__TYPE *pData, __SIZE_t Num)\ {\ if ((Num > FIFO_##__NAME##_GetCount()) || (pData == NULL))\ return FALSE;\ while(Num--)\ {\ *pData = *FIFO_##__NAME##Tail;\ _DI();\ if (FIFO_##__NAME##Tail == FIFO_##__NAME##Buffer + (__SIZE - 1))\ FIFO_##__NAME##Tail = FIFO_##__NAME##Buffer;\ else \ FIFO_##__NAME##Tail++;\ pData++;\ _EI();\ }\ return TRUE;\ }\ BOOL FIFO_##__NAME##_IsEmpty(void)\ {\ if (FIFO_##__NAME##Tail == FIFO_##__NAME##Head) return TRUE;\ else return FALSE;\ } \ extern /*__inline*/ void FIFO_##__NAME##_PutOneInt(__TYPE Data)\ {\ if ((FIFO_##__NAME##Head+1) != FIFO_##__NAME##Tail) {\ if (((FIFO_##__NAME##Head+1)- __SIZE) != FIFO_##__NAME##Tail) {\ *FIFO_##__NAME##Head = Data;\ if (FIFO_##__NAME##Head == FIFO_##__NAME##Buffer + (__SIZE - 1))\ FIFO_##__NAME##Head = FIFO_##__NAME##Buffer;\ else \ FIFO_##__NAME##Head++;\ }\ }\ }\ extern /*__inline*/ BOOL FIFO_##__NAME##_GetOneInt(__TYPE *pData)\ {\ if (FIFO_##__NAME##Tail == FIFO_##__NAME##Head) return FALSE;\ *pData = *FIFO_##__NAME##Tail; \ if (FIFO_##__NAME##Tail == FIFO_##__NAME##Buffer + (__SIZE - 1)) {\ FIFO_##__NAME##Tail = FIFO_##__NAME##Buffer;\ }\ else {\ FIFO_##__NAME##Tail++;\ }\ return TRUE;\ }\#define EXPORT_FIFO_API(__NAME,__SIZE,__TYPE,__SIZE_t) \ extern __TYPE FIFO_##__NAME##Buffer[(__SIZE)];\ extern __TYPE *FIFO_##__NAME##Tail;\ extern __TYPE *FIFO_##__NAME##Head;\ extern BOOL FIFO_##__NAME##_PutOne(__TYPE Data);\ extern BOOL FIFO_##__NAME##_GetOne(__TYPE *pData);\ extern BOOL FIFO_##__NAME##_PeekOne(__TYPE *pData, __SIZE_t Index);\ extern void FIFO_##__NAME##_DumpData(__SIZE_t Num);\ extern BOOL FIFO_##__NAME##_PutStr(__TYPE *pData, __SIZE_t Num);\ extern BOOL FIFO_##__NAME##_GetStr(__TYPE *pData, __SIZE_t Num);\ extern BOOL FIFO_##__NAME##_IsEmpty(void);\ extern __SIZE_t FIFO_##__NAME##_GetCount(void);\ extern __SIZE_t FIFO_##__NAME##_GetIdelCount(void);\ extern /*__inline */void FIFO_##__NAME##_PutOneInt(__TYPE Data);\ /*{\ if ((FIFO_##__NAME##Head+1) != FIFO_##__NAME##Tail) {\ if (((FIFO_##__NAME##Head+1)- __SIZE) != FIFO_##__NAME##Tail) {\ *FIFO_##__NAME##Head = Data;\ if (FIFO_##__NAME##Head == FIFO_##__NAME##Buffer + (__SIZE - 1))\ FIFO_##__NAME##Head = FIFO_##__NAME##Buffer;\ else \ FIFO_##__NAME##Head++;\ }\ }\ }*/\ extern /*__inline*/ BOOL FIFO_##__NAME##_GetOneInt(__TYPE *pData);\ /*{\ if (FIFO_##__NAME##Tail == FIFO_##__NAME##Head) return FALSE;\ *pData = *FIFO_##__NAME##Tail; \ if (FIFO_##__NAME##Tail == FIFO_##__NAME##Buffer + (__SIZE - 1)) {\ FIFO_##__NAME##Tail = FIFO_##__NAME##Buffer;\ }\ else {\ FIFO_##__NAME##Tail++;\ }\ return TRUE;\ }*/\#define FIFO_INIT(__NAME) _DI();FIFO_##__NAME##Tail = FIFO_##__NAME##Buffer;\ FIFO_##__NAME##Head = FIFO_##__NAME##Buffer;_EI();#define FIFO_PUT_ONE_INT(__NAME,__DATA) FIFO_##__NAME##_PutOneInt(__DATA)#define FIFO_GET_ONE_INT(__NAME,__ADDR) FIFO_##__NAME##_GetOneInt(__ADDR)#define FIFO_PUT_ONE(__NAME,__DATA) FIFO_##__NAME##_PutOne(__DATA)#define FIFO_GET_ONE(__NAME,__ADDR) FIFO_##__NAME##_GetOne(__ADDR)#define FIFO_PEEK_ONE(__NAME,__ADDR,__IDX) FIFO_##__NAME##_PeekOne(__ADDR,__IDX)#define FIFO_DUMP_DATA(__NAME,__NUM) FIFO_##__NAME##_DumpData(__NUM)#define FIFO_GET_COUNT(__NAME) FIFO_##__NAME##_GetCount()#define FIFO_GET_IDEL_COUNT(__NAME) FIFO_##__NAME##_GetIdelCount()#define FIFO_IS_EMPTY(__NAME) FIFO_##__NAME##_IsEmpty()#define FIFO_PUT_STR(__NAME,__ADDR,__NUM) FIFO_##__NAME##_PutStr(__ADDR,__NUM)#define FIFO_GET_STR(__NAME,__ADDR,__NUM) FIFO_##__NAME##_GetStr(__ADDR,__NUM)#define FIFO_PUTS(__NAME,__ADDR) FIFO_##__NAME##_PutStr(__ADDR,sizeof(__ADDR))#endif
在h文件中添加添加输出EXPORT_FIFO_API():
EXPORT_FIFO_API(printf_can1_fifo, CAN_RX_FIFO_SIZE,CanRxMsg , u8);
EXPORT_FIFO_API(printf_can2_fifo, CAN_RX_FIFO_SIZE,CanRxMsg , u8);
在C文件中创建FIFO,NEW_FIFO():
NEW_FIFO(printf_can1_fifo, CAN_RX_FIFO_SIZE,CanRxMsg , u8);
NEW_FIFO(printf_can2_fifo, CAN_RX_FIFO_SIZE,CanRxMsg , u8);
通过FIFO_PUT_ONE()把消息RxMessage放入缓冲printf_can1_fifo:
FIFO_PUT_ONE(printf_can1_fifo, RxMessage);
FIFO_PUT_ONE(printf_can2_fifo, RxMessage);
通过FIFO_GET_ONE()从缓存区printf_can1_fifo把数据放入Get_CanRxMsg变量:
CanRxMsg Get_CanRxMsg;
FIFO_GET_ONE(printf_can1_fifo, &Get_CanRxMsg)
FIFO_GET_ONE(printf_can2_fifo, &Get_CanRxMsg)
从缓存区拿出can数据并打印处理:void Printf_Can_RxMessage() { CanRxMsg Get_CanRxMsg; Byte nData=0; if(FIFO_GET_ONE(printf_can1_fifo, &Get_CanRxMsg)) { //printf("\r\nIDE: 0X%02x",Get_CanRxMsg.IDE); if(!Get_CanRxMsg.IDE) printf("\r\nCAN1_STD:0X%04X",Get_CanRxMsg.StdId); else printf("\r\nCAN1_EXT:0X%08X",Get_CanRxMsg.ExtId); printf(" DLC:%02X Data:" ,Get_CanRxMsg.DLC); nData=0; while(nData<Get_CanRxMsg.DLC) { printf(" 0X%02X",Get_CanRxMsg.Data[nData]); nData++; } printf("\r\n"); } if(FIFO_GET_ONE(printf_can2_fifo, &Get_CanRxMsg)) { //printf("\r\nIDE: 0X%02x",Get_CanRxMsg.IDE); if(!Get_CanRxMsg.IDE) printf("\r\nCAN2_STD:0X%04X",Get_CanRxMsg.StdId); else printf("\r\nCAN2_EXT:0X%08X",Get_CanRxMsg.ExtId); printf(" DLC:%02X Data:" ,Get_CanRxMsg.DLC); nData=0; while(nData<Get_CanRxMsg.DLC) { printf(" 0X%02X",Get_CanRxMsg.Data[nData]); nData++; } printf("\r\n"); } }
CAN发送的数据打印处理:
void Printf_Can_TxMessage(CanTxMsg CanTxMessage,CAN_TypeDef * CAN){ CanTxMsg Get_CanTxMSG=CanTxMessage; Byte nData=0; CAN_TypeDef * CAN_Stype=CAN; if(CAN_Stype==CAN1){ if(!Get_CanTxMSG.IDE) printf("\r\nCAN1Send_STD:0X%04X",Get_CanTxMSG.StdId); else printf("\r\nCAN1Send_EXT:0X%08X",Get_CanTxMSG.ExtId); printf(" DLC:%02X Data:" ,Get_CanTxMSG.DLC); nData=0; while(nData<Get_CanTxMSG.DLC) { printf(" 0X%02X",Get_CanTxMSG.Data[nData]); nData++; } printf("\r\n"); } if(CAN_Stype==CAN2){ if(!Get_CanTxMSG.IDE) printf("\r\nCAN2Send_STD:0X%04X",Get_CanTxMSG.StdId); else printf("\r\nCAN2Send_EXT:0X%08X",Get_CanTxMSG.ExtId); printf(" DLC:%02X Data:" ,Get_CanTxMSG.DLC); nData=0; while(nData<Get_CanTxMSG.DLC) { printf(" 0X%02X",Get_CanTxMSG.Data[nData]); nData++; } printf("\r\n"); }}
阅读全文
0 0
- 环形队列FIFO
- 环形队列FIFO实现方法
- 数据结构-环形队列(FIFO)多字节读写
- 51单片机串口通信 环形缓冲区队列(FIFO)
- 精简通用环形fifo
- 软件模拟环形FIFO
- 队列 FIFO
- 环形队列
- 环形队列
- 环形队列
- 环形队列
- 环形队列
- 环形队列
- 环形队列
- 环形队列
- 环形队列
- FIFO环形缓冲区的实现
- java算法:FIFO队列
- Linux--RH254---unit 11 bash 2
- C++ builder 中的 XMLDocument 类详解(16) – 前一个节点、后一个节点和父节点
- 解决用命令行编译java文件出现的问题
- Linux学习之文件处理命令(三)链接命令
- DrawerLayout实现多样侧滑菜单效果
- 环形队列FIFO
- Ajax实现省市级联
- 如何用git将本地仓库中的项目上传到github
- _dl_runtime_resolve
- 数据库约束
- 原生JavaScript实现瀑布流布局
- C++每日一课(二)
- Windows Security之自主访问控制
- C++ builder 中的 XMLDocument 类详解(17) 更好地显示 xml 的测试结果