OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2937|回复: 5

串口自定义环形缓冲程序编写

[复制链接]

2

主题

3

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2018-7-19
在线时间
4 小时
发表于 2019-5-23 09:15:38 | 显示全部楼层 |阅读模式
1金钱
再实际工程中,用程序编写一个环形缓冲区,防止数据被覆盖等意外现象。
但是没有头绪,不知该如何编写。请问有没有人能提供下建议或者代码?

最佳答案

查看完整内容[请看2#楼]

/** ************************************************************ * @file ringbuffer.c * @brief Loop buffer processing * @author Gizwits * @date 2017-07-19 * @version V03030000 * @copyright Gizwits * * @note Gizwits is only for smart hardware * Gizwits Smart Cloud for Smart Products * Links | Value Added | Open | Ne ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4521
金钱
4521
注册时间
2018-5-11
在线时间
946 小时
发表于 2019-5-23 09:15:39 | 显示全部楼层
/**
************************************************************
* @file         ringbuffer.c
* @brief        Loop buffer processing
* @author       Gizwits
* @date         2017-07-19
* @version      V03030000
* @copyright    Gizwits
*
* @note         Gizwits is only for smart hardware
*               Gizwits Smart Cloud for Smart Products
*               Links | Value Added | Open | Neutral | Safety | Own | Free | Ecology
*               www.gizwits.com
*
***********************************************************/
#include "ringBuffer.h"
#include "common.h"

int8_t ICACHE_FLASH_ATTR rbCreate(rb_t* rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    rb->rbHead = rb->rbBuff;
    rb->rbTail = rb->rbBuff;
    return 0;
}

int8_t ICACHE_FLASH_ATTR rbDelete(rb_t* rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    rb->rbBuff = NULL;
    rb->rbHead = NULL;
    rb->rbTail = NULL;
    rb->rbCapacity = 0;
                return 0;
}

int32_t ICACHE_FLASH_ATTR rbCapacity(rb_t *rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    return rb->rbCapacity;
}

int32_t ICACHE_FLASH_ATTR rbCanRead(rb_t *rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    if (rb->rbHead == rb->rbTail)
    {
        return 0;
    }

    if (rb->rbHead < rb->rbTail)
    {
        return rb->rbTail - rb->rbHead;
    }

    return rbCapacity(rb) - (rb->rbHead - rb->rbTail);
}

int32_t ICACHE_FLASH_ATTR rbCanWrite(rb_t *rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    return rbCapacity(rb) - rbCanRead(rb);
}

int32_t ICACHE_FLASH_ATTR rbRead(rb_t *rb, void *data, size_t count)
{
    int32_t copySz = 0;

    if(NULL == rb)
    {
        return -1;
    }

    if(NULL == data)
    {
        return -1;
    }

    if (rb->rbHead < rb->rbTail)
    {
        copySz = min(count, rbCanRead(rb));
        memcpy(data, rb->rbHead, copySz);
        rb->rbHead += copySz;
        return copySz;
    }
    else
    {
        if (count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff))
        {
            copySz = count;
            memcpy(data, rb->rbHead, copySz);
            rb->rbHead += copySz;
            return copySz;
        }
        else
        {
            copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff);
            memcpy(data, rb->rbHead, copySz);
            rb->rbHead = rb->rbBuff;
            copySz += rbRead(rb, (char*)data+copySz, count-copySz);
            return copySz;
        }
    }
}

int32_t ICACHE_FLASH_ATTR rbWrite(rb_t *rb, const void *data, size_t count)
{
    int32_t tailAvailSz = 0;

    if((NULL == rb)||(NULL == data))
    {
        return -1;
    }

    if (count >= rbCanWrite(rb))
    {
        return -2;
    }

    if (rb->rbHead <= rb->rbTail)
    {
        tailAvailSz = rbCapacity(rb) - (rb->rbTail - rb->rbBuff);
        if (count <= tailAvailSz)
        {
            memcpy(rb->rbTail, data, count);
            rb->rbTail += count;
            if (rb->rbTail == rb->rbBuff+rbCapacity(rb))
            {
                rb->rbTail = rb->rbBuff;
            }
            return count;
        }
        else
        {
            memcpy(rb->rbTail, data, tailAvailSz);
            rb->rbTail = rb->rbBuff;

            return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);
        }
    }
    else
    {
        memcpy(rb->rbTail, data, count);
        rb->rbTail += count;
        return count;
    }
}
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

17

主题

587

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4467
金钱
4467
注册时间
2013-6-27
在线时间
565 小时
发表于 2019-5-23 09:29:20 | 显示全部楼层
去看看环形队列
让我们的思维驾驭在电的速度之上!
回复

使用道具 举报

0

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2016-5-27
在线时间
91 小时
发表于 2019-5-23 10:32:56 | 显示全部楼层
#define BUFFERSIZE 1024 // 1K Buffer 如果数据量大的话可以多点但是不能大于64K(估计CPU的RAM也没那么大)
u16  InCount,OutCount;       //进出计数
u8   USART_Buffer[BUFFERSIZE];  //环形缓冲

//调用函数  (这个函数得在WHILE中不断的查询缓存)
....
u8 redata=0;
if(OutCount!=InCount)
{
   redata=GetData();
  //你的数据处理代码
}
....

void USART1_IRQHandler(void)
{
     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
     {
       USART_ClearITPendingBit(USART1,USART_IT_RXNE);
       USART_Buffer[InCount++] = USART_ReceiveData(USART1);
       if(InCount>=BUFFERSIZE) InCount=0;                       
     }
}

u8 GetData(void)
{
        u8 data;        
          data=USART_Buffer[OutCount++];
                if(OutCount>=BUFFERSIZE) OutCount=0;        
        return data;
}
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4521
金钱
4521
注册时间
2018-5-11
在线时间
946 小时
发表于 2019-5-23 10:46:39 | 显示全部楼层
/**
************************************************************
* @file         ringbuffer.h
* @brief        Loop buffer processing
* @Author       Gizwits
* @date         2017-07-19
* @version      V03030000
* @Copyright    Gizwits
*
* @note         Gizwits is only for smart hardware
*               Gizwits Smart Cloud for Smart Products
*               Links | Value Added | Open | Neutral | Safety | Own | Free | Ecology
*               www.gizwits.com
*
***********************************************************/
#ifndef _GIZWITS_RING_BUFFER_H
#define _GIZWITS_RING_BUFFER_H

#ifdef __cplusplus
extern "C" {
#endif
       
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define min(a, b) (a)<(b)?(a)b)                   ///< Calculate the minimum value

#pragma pack(1)
typedef struct {
    size_t rbCapacity;
    uint8_t  *rbHead;
    uint8_t  *rbTail;
    uint8_t  *rbBuff;
}rb_t;
#pragma pack()

int8_t rbCreate(rb_t* rb);
int8_t rbDelete(rb_t* rb);
int32_t rbCapacity(rb_t *rb);
int32_t rbCanRead(rb_t *rb);
int32_t rbCanWrite(rb_t *rb);
int32_t rbRead(rb_t *rb, void *data, size_t count);
int32_t rbWrite(rb_t *rb, const void *data, size_t count);

#ifdef __cplusplus
}
#endif
       
#endif
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-5-23 12:53:14 | 显示全部楼层
安富莱有写好的,下载用就好了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 07:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表