注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
懒猫爱飞的个人空间 https://home.eeworld.com.cn/space-uid-238351.html [收藏] [复制] [分享] [RSS]
日志

关于循环队列的应用

已有 791 次阅读2018-11-29 16:05 |个人分类:C语言学习

关于循环队列的应用
                                               Author : Mark Xu


开发的USB项目中会用到连续的存取数据,于是在写了个简单的循环队列,循环队列的好处就是首尾相连节省空间,关于循环队列的概念课本上已说的很清楚,网上也有大量的博客文档,图文并茂,这里就不在赘述了,下面仅把代码做一下整理,相当于备份吧^_^
总共有两个源文件Xc_CircleQueue.c 与Xc_CircleQueue.h
1)       Xc_CircleQueue.c源代码
  
/******************************************************************************************
  
* Copyright(c) 2018, Mark Xu WorK Studio.  All rights reserved.
  
*
  
*  File Name :  Xc_CircleQueue.c
  
*
  
*  Brief     :  about the circle queue application
  
*
  
*  Author   : Mark Xu
  
*
  
*  Date   : 20181012
  
*
  
*  Version: V1.0
  
*
  
*  Remark : None
  
*
  
*-----------------------------------------------------------------------------------------------------------------------------------------------
  
*  History  :
  
*
  
*   1)  Author : xx xx
  
*
  
*     Modify  Date : xx xx xx
  
*
  
*     Modify  contents : xx xx xx xx xx
  
******************************************************************************************/
  
#define XC_CIRCLEQUEUE_IMPLEMENT
  
  
#include <stdio.h>
  
#include <string.h>
  
#include <stdint.h>
  
#include <stdlib.h>
  
#include "Xc_CircleQueue.h"
  
  
/************************************************************************************
  
* 函数名称 : Circle_Queue_Init
  
*
  
* 函数描述 : Initial the queue
  
*
  
* 入口参数 : *rbuf - the queue
  
*
  
*            *array - the data buffer
  
*
  
*            len - the depth of the queue
  
*
  
* 出口参数 : TRUE - initial successful
  
*
  
* 函数备注 : None
  
*************************************************************************************/
  
uint8_t Circle_Queue_Init(RingBuf_T  *rbuf, uint8_t *array, uint16_t len)
  
{
  
         if((len<2)||(array  == NULL))
  
                   return FALSE;
  
         
  
         rbuf->Buf     = array;
  
         rbuf->Depth   = len;
  
         rbuf->fillCnt = 0;
  
         rbuf->Head    = 0;
  
         rbuf->Tail    = 0;
  
  
         return TRUE;
  
}
  
  
/************************************************************************************
  
* 函数名称 : RingBuf_Clear
  
*
  
* 函数描述 : clear the queue
  
*
  
* 入口参数 : *rbuf - the queue
  
*
  
* 出口参数 : None
  
*
  
* 函数备注 : None
  
*************************************************************************************/
  
void RingBuf_Clear(RingBuf_T *rbuf)
  
{
  
         rbuf->fillCnt =  0;
  
         rbuf->Head =  0;
  
         rbuf->Tail  =  0;
  
}
  
  
  
/************************************************************************************
  
* 函数名称 : RingBuf_Chk_Full
  
*
  
* 函数描述 : clear the queue
  
*
  
* 入口参数 : *rbuf - the queue
  
*
  
* 出口参数 : true - full     false - not full
  
*
  
* 函数备注 : judging condition -  (tail+1) % buf_size_max == head
  
*************************************************************************************/
  
uint16_t  RingBuf_Chk_Full(RingBuf_T *rbuf)
  
{
  
         return((rbuf->Tail + 1)%rbuf->Depth ==  rbuf->Head);
  
}
  
  
/************************************************************************************
  
* 函数名称 : RingBuf_Chk_Empty
  
*
  
* 函数描述 : check the queue empty or  not
  
*
  
* 入口参数 : *rbuf - the queue
  
*
  
* 出口参数 : true - empty    false - not empty
  
*
  
* 函数备注 : judging condition - tail  == head
  
*************************************************************************************/
  
uint16_t  RingBuf_Chk_Empty(RingBuf_T *rbuf)
  
{
  
         return  (rbuf->Tail  ==  rbuf->Head);
  
}
  
  
  
/************************************************************************************
  
* 函数名称 : RingBuf_Write_Bytes
  
*
  
* 函数描述 : push the data to queue
  
*
  
* 入口参数 : *rbuf - the queue
  
*
  
*            *pValue - the value to be push
  
*
  
*            size  - the bytes of the value  buffer
  
*
  
* 出口参数 : true - success    false - fail
  
*
  
* 函数备注 : none
  
*************************************************************************************/
  
uint16_t  RingBuf_Write_Bytes(RingBuf_T *rbuf,uint8_t *pValue, uint16_t size)
  
{
  
        uint16_t len = 0;
  
        uint16_t ringBuf_bw  =  rbuf->Tail  ;
  
        uint16_t ringBuf_len  =  rbuf->Depth;
  
         uint8_t  *ringBuf_source =  rbuf->Buf;
  
         if(RingBuf_Chk_Full(rbuf))
  
                 return 0;
  
  
         if((ringBuf_bw  + size) <= ringBuf_len)
  
         {
  
                   memcpy((uint8_t  *)&ringBuf_source[ringBuf_bw],pValue,size);
  
         }
  
         else
  
         {
  
                   len = ringBuf_len -  ringBuf_bw;
  
  
                   memcpy(ringBuf_source+ringBuf_bw,pValue,len);
  
                   memcpy(ringBuf_source,pValue+ringBuf_bw,(size-len));
  
         }
  
         
  
         // 计算Tail  的位置
  
         rbuf->Tail = (rbuf->Tail +  size) % rbuf->Depth;
  
         rbuf->fillCnt += size;
  
         
  
         return  size;
  
}
  
  
/************************************************************************************
  
* 函数名称 : RingBuf_Write_Bytes
  
*
  
* 函数描述 : Read the data from the  queue
  
*
  
* 入口参数 : *rbuf - the queue
  
*
  
*            *pValue - the data buffer to store the read data
  
*
  
*            size  - the bytes of the value  buffer
  
*
  
* 出口参数 : true - success    false - fail
  
*
  
* 函数备注 : none
  
*************************************************************************************/
  
uint16_t  RingBuf_Read_Bytes(RingBuf_T *rbuf,uint8_t *pValue,uint16_t size)
  
{
  
        uint16_t len = 0;
  
        uint16_t ringBuf_br    =   rbuf->Head;
  
        uint16_t ringBuf_len   = rbuf->Depth;
  
         char  *ringBuf_src = rbuf->Buf;
  
         
  
         // 如果为空则返回0
  
         if(RingBuf_Chk_Empty(rbuf))
  
                 return 0;
  
  
         // tial等于head时,说明队列为空
  
         if(rbuf->fillCnt  == 0)
  
         {
  
//               printf("Buffer is  empty,nothing to be read \r\n");
  
                   return 0;   
  
         }
  
         
  
         // 只读取有效数据
  
         if(size  > rbuf->fillCnt)
  
             size = rbuf->fillCnt;
  
  
         if((ringBuf_br  + size) <= ringBuf_len)
  
         {
  
                   memcpy(pValue,ringBuf_src +  ringBuf_br,size);
  
         }
  
         else
  
         {
  
                   len = ringBuf_len -  ringBuf_br;
  
                   memcpy(pValue,ringBuf_src +  ringBuf_br,len);
  
                   memcpy(pValue+len, ringBuf_src,(size-len));
  
         }
  
         
  
         rbuf->Head = (rbuf->Head +  size) % rbuf->Depth;
  
         rbuf->fillCnt -= size;
  
         
  
         return  size;
  
}
  
2)       Xc_CircleQueue.h源代码
  
/******************************************************************************************
  
* Copyright(c) 2018, Mark Xu Work Studio.  All rights reserved.
  
*
  
* 文件名称 : Xc_Queue.h
  
*
  
* 文件描述 : 关于队列模块的一些声明与定义
  
*
  
* 文件作者 : Mark Xu
  
*
  
* 创建日期 : 20181010
  
*
  
* 当前版本 : V1.0
  
*
  
* 文件备注 : None
  
*
  
*----------------------------------------------------------------------------------------
  
* 修改记录 :
  
*
  
*   1)  修改人员 : xx xx
  
*
  
*       修改日期 : xx xx xx
  
*
  
*       修改内容 : xx xx xx xx xx
  
******************************************************************************************/
  
#ifndef __XC_CIRCLEQUEUE_H__
  
#define __XC_CIRCLEQUEUE_H__
  
  
//------------------------------------------------------------------------------------------------------------------------------------------------
  
//  Precompile
  
//-----------------------------------------------------------------------------------------------------------------------------------------------
  
#ifdef XC_CIRCLEQUEUE_IMPLEMENT
  
    #define CIRCLEQUEUE_EXTERN
  
#else
  
    #define CIRCLEQUEUE_EXTERN       extern
  
#endif /* XC_CIRCLEQUEUE_IMPLEMENT */
  
  
  
#include "stdio.h"
  
#include "stdlib.h"
  
#include "stdint.h"
  
#include "string.h"
  
  
//------------------------------------------------------------------------------------------------------------------------------------------------
  
//  数据类型声明
  
//------------------------------------------------------------------------------------------------------------------------------------------------
  
/*
  
  说明:
  
    1. fillCnt 是计数队列中的元素个数
  
    2. 当向队列中插入元素时,fillCnt 要增加
  
    3. 当从队列中读取元素时,fillCnt 要减少
  
    4. fillCnt0时说明队列中没有元素,不可读取
  
*/
  
#pragma pack(4)
  
typedef struct RingBuf_t{
  
    uint8_t *Buf;     /* 指向队列数组的指针 */
  
    uint16_t Depth;   /* 可存储的元素的个数 */
  
    uint16_t Head;    /* 队头,也是读取的指针 */
  
    uint16_t Tail;     /* 队尾,也是写的指针 */
  
    uint16_t fillCnt;   /* 元素计数  */
  
}RingBuf_T;
  
#pragma pack()
  
  
// 指针形式
  
typedef RingBuf_T*   RingBuf_Tp;
  
  
//------------------------------------------------------------------------------------------------------------------------------------------------
  
//  函数声明
  
//------------------------------------------------------------------------------------------------------------------------------------------------
  
CIRCLEQUEUE_EXTERN  uint8_t Circle_Queue_Init(RingBuf_T *rbuf, uint8_t *array, uint16_t len);
  
  
CIRCLEQUEUE_EXTERN  void RingBuf_Clear(RingBuf_T  *rbuf);
  
  
CIRCLEQUEUE_EXTERN  uint16_t RingBuf_Chk_Full(RingBuf_T *rbuf);
  
  
CIRCLEQUEUE_EXTERN  uint16_t RingBuf_Chk_Empty(RingBuf_T *rbuf);
  
  
CIRCLEQUEUE_EXTERN  uint16_t RingBuf_Write_Bytes(RingBuf_T *rbuf,uint8_t *pValue, uint16_t size);
  
  
CIRCLEQUEUE_EXTERN  uint16_t RingBuf_Read_Bytes(RingBuf_T *rbuf,uint8_t *pValue,uint16_t size);
  
  
  
#endif /* __XC_CIRCLEQUEUE_H__ */
  
  


此内容由EEWORLD论坛网友懒猫爱飞原创,如需转载或用于商业用途需征得作者同意并注明出处

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章