stm32实用循环buffer

发布者:温馨家园最新更新时间:2019-08-26 来源: eefocus关键字:stm32  循环buffer 手机看文章 扫描二维码
随时随地手机看文章

本人在实际开发中多次用到串口的循环buffer,最开始在网上搜索了相关文章和资料,感觉通用性不是很高。自己也写过fifo,感觉还是过于臃肿。一直想找个完美的循环buffer。在看linux内核代码时,发现内核里面也经常使用fifo。linux内核代码是最优美、精简的,高效的代码。真是“山穷水尽疑无路,柳暗花明又一村”。特意移植除出来,希望对大家有用。代码设计的相当的巧妙~~~


头文件:


/*******************************************************************************

* @File   : fifo.h

* @Author   : cqx

* @Version  : V0.0.1

* @Date   : 29-november-2016

* @Brief   : This file provides all the fifo functions.

********************************************************************************

* @Attention:

* Non

*

*******************************************************************************/

 

/* Define to prevent recursive inclusion -------------------------------------*/

#ifndef _FIFO_H

#define _FIFO_H

 

#include

 

#ifdef __cplusplus

 extern "C" {

#endif

 

/* Includes ------------------------------------------------------------------*/

/* Define --------------------------------------------------------------------*/

#ifndef min

#define min(a, b) (((a) < (b)) ? (a) : (b))

#endif

 

#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))

/* Private typedef -----------------------------------------------------------*/

struct fifo {

unsigned int in;

unsigned int out;

unsigned int mask;

unsigned char *data;

}; 

 

/* Function prototypes -------------------------------------------------------*/

extern unsigned int fifo_used(struct fifo *fifo);

extern signed int fifo_alloc(struct fifo *fifo, unsigned int size);

extern void         fifo_free(struct fifo *fifo);

extern int          fifo_init(struct fifo *fifo, unsigned char *buffer, unsigned int size);

extern unsigned int fifo_in(struct fifo *fifo, unsigned char *buf, unsigned int len);

extern unsigned int fifo_out(struct fifo *fifo, unsigned char *buf, unsigned int len);

 

#ifdef __cplusplus

}

#endif

 

#endif



源文件:


/******************************************************************************

* @File   : ringbuffer.c

* @Author   : cqx

* @Version  : V0.0.1

* @Date   : 29-november-2016

* @Brief   : This file provides all the fifo functions.

******************************************************************************

* @Attention:

*

******************************************************************************/

/* Includes -----------------------------------------------------------------*/

#include "fifo.h"

#include "stdlib.h"

#include "string.h"

#include "includes.h"

 

/* Variables -----------------------------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

/******************************************************************************/

 

/*

 * internal helper to calculate the unused elements in a fifo

 */

static __inline unsigned int fifo_unused(struct fifo *fifo)

{

  return (fifo->mask + 1) - (fifo->in - fifo->out);

}

 

unsigned int fifo_used(struct fifo *fifo)

{

  return (fifo->in - fifo->out);

}

 

signed int fifo_alloc(struct fifo *fifo, unsigned int size)

{

/*

* round down to the next power of 2, since our 'let the indices

* wrap' technique works only in this case.

*/

if (!is_power_of_2(size))

return -1;

 

fifo->in = 1;

fifo->out = 1;

if (size < 2){

fifo->data = NULL;

fifo->mask = 0;

return -1;

}

fifo->data = malloc(size);

if (!fifo->data){

fifo->mask = 0;

return -1;

}

fifo->mask = size - 1;

  

  return 0;

}

 

void fifo_free(struct fifo *fifo)

{

free(fifo->data);

fifo->in = 0;

fifo->out = 0;

fifo->data = NULL;

fifo->mask = 0;

}

 

int fifo_init(struct fifo *fifo, unsigned char *buffer, unsigned int size)

{

if (!is_power_of_2(size))

return -1;

 

fifo->in = 0;

fifo->out = 0;

fifo->data = buffer;

 

if (size < 2) {

fifo->mask = 0;

return -1;

}

fifo->mask = size - 1;

 

return 0;

}

 

static void fifo_copy_in(struct fifo *fifo, unsigned char *src, unsigned int len, unsigned int off)

{

unsigned int size = fifo->mask + 1;

unsigned int l;

 

off &= fifo->mask;

 

l = min(len, size - off);

 

memcpy(fifo->data + off, src, l);

memcpy(fifo->data, src + l, len - l);

}

 

unsigned int fifo_in(struct fifo *fifo, unsigned char *buf, unsigned int len)

{

unsigned int l;

 

l = fifo_unused(fifo);

if (len > l)

len = l;

 

fifo_copy_in(fifo, buf, len, fifo->in);

fifo->in += len;

return len;

}

 

static void fifo_copy_out(struct fifo *fifo, unsigned char *dst, unsigned int len, unsigned int off)

{

unsigned int size = fifo->mask + 1;

unsigned int l;

 

off &= fifo->mask;

l = min(len, size - off);

 

memcpy(dst, fifo->data + off, l);

memcpy(dst + l, fifo->data, len - l);

}

 

unsigned int fifo_out_peek(struct fifo *fifo, unsigned char *buf, unsigned int len)

{

unsigned int l;

 

l = fifo->in - fifo->out;

if (len > l)

len = l;

 

fifo_copy_out(fifo, buf, len, fifo->out);

return len;

}

 

unsigned int fifo_out(struct fifo *fifo, unsigned char *buf, unsigned int len)

{

len = fifo_out_peek(fifo, buf, len);

fifo->out += len;

return len;

}


关键字:stm32  循环buffer 引用地址:stm32实用循环buffer

上一篇:基于STM32的串口数据环形缓冲队列
下一篇:stm32F4 串口DMA+环形缓冲区的实现

推荐阅读最新更新时间:2024-11-13 12:16

STM32 DTH11温湿度模块读写代码
dth11.c #include dth11.h /* DTH11 ---- PG9 */ void DHT11_Init(void) { GPIO_InitTypeDef GFIO_InitStruct; //开始GPIOG时钟 RCC_AHB1PeriphClockCmd(RCC_AHBPeriph_GPIOG, ENABLE); //配置以及初始化GPIO模式 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_out; //输出 GPIO_InitStruct.GPIO_OTy
[单片机]
工程师STM32单片机学习基础手记(4):用PWM实现荧火虫灯(二)
用PWM生成正弦波   有了PWM,自然就可以用PWM的方法生成正弦波了。下面生成500Hz正弦波的方法参考自张明峰的《PIC单片机入门与实践》   每个正弦波分成四个像限,每个像限16点,共64点,每点出现2个PWM周期,故PWM的周期为:2ms/128=156.25us,频率为64KHz。   TIM3 Frequency = TIM3 counter clock/(ARR + 1)   倒过来:   ARR=TIM3 Counter Clock/TIM3 Frequenc - 1 =562.5-1 =561   如果取ARR的值是561的话,那么实际的频率是64.056KHz,即最终生成为的正弦波频率
[模拟电子]
STM32 USB DFU设备固件升级 工程讲解
说到STM32 USB的UDF,其实就是我们常说的IAP( In Application Programming )在应用编程。IAP有很多方法,我之前就用过串口IAP,网络IAP。而这里我们使用的是USB IAP,就是通过USB更新代码。所以这里有必要线了解IAP。 IAP是In Application Programming的首字母缩写,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的 固件 程序进行更新升级。 通常在用户需要实现IAP功能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,第一个项目程序不执行
[单片机]
STM32开发笔记21: USB驱动的移植
单片机型号:STM32L053R8T6 现在使用的STM32L053R8T6单片机带有USB接口,原先一直使用UART转USB芯片来完成USB功能的支持,现在这款单片机带了就希望使用以下。由于已经建立了自己的工程目录,再重新使用STM32CubeMX生成的工程文件,重新建立是不显示的,所以本文探索将USB驱动文件移植到自己项目中的方法,我使用的是USB的CDCD类,步骤如下: 1、使用STM32CubeMX使能USB,如下图所示: 2、设置时钟,USB需要48M时钟,使用内部和外部均可,我这里使用外部时钟。 3、生成工程文件。 4、在自己的工程目录中加入如下图所示的2个文件,如果此2个文件
[单片机]
<font color='red'>STM32</font>开发笔记21: USB驱动的移植
基于STM32-蜂鸣器
1.蜂鸣器 蜂鸣器是一种发声设备,被广泛用于计算机、打印机、复印机、报警器、电子玩具等。后面介绍定时器是会给大家说说利用蜂鸣器实现歌曲演奏。蜂鸣器分为有源蜂鸣器和无源蜂鸣器。那么什么是有源,什么是无源呢?这里的有源不是指电源的“源”,而是指有没有自带震荡电路,有源蜂鸣器自带了震荡电路,一通电就会发声;无源蜂鸣器则没有自带震荡电路,必须外部提供 2~5Khz 左右的方波驱动才能发声。 2.硬件介绍 这里使用STM32F103实现无源蜂鸣器的交替发声,下图是硬件设计图。首先,STM32F1 的单个 IO 最大可以提供 25mA 电流(数据手册查看),而蜂鸣器的驱动电流是 30mA 。这里使用一个NPN三极管(S8050)扩
[单片机]
基于STM32-蜂鸣器
STM32的地址分配
一.存储器组织 注:每一个外设都对应一个寄存器组,如定时器TIM2对应的寄存器地址为0x40000000~0x400003FF. 二.嵌入的SRAM以及嵌入的闪存 1.嵌入的SRAM可以以字节,半字,全字访问,这里SRAM的起始地址为0x20000000. 2.闪存存储器有主存储块和信息块组成。 注:有关闪存寄存器的详细信息,请参考《STM32F10xxx闪存编程手册》。
[单片机]
stm32-afio的使用
1. AFIO的功能 为了优化64脚或100脚封装的外设数目,可以把一些复用功能重新映射到其他引脚上。设置复用重映射和调试I/O配置寄存器(AFIO_MAPR)实现引脚的重新映射。这时,复用功能不再映射到它们的原始分配上。 简言之,AFIO实现了复用功能的重新映射。 2. 在什么情况下,需要开启AFIO时钟? 参考手册中写道:对寄存器AFIO_EVCR, AFIO_MAPR和AFIO_EXTICRX进行读写操作前,应当首先打开AFIO的时钟。 在数据手册的引脚定义中(pin definitions),复用功能 Alternate functions 栏下分为两栏:默认 Default 和重映射 R
[单片机]
stm32-afio的使用
关于stm32串口下载的问题
今天在用stm32f103rct6调程序的时候,不知道怎么回事j-link不能下载了,好像还不是驱动的问题,是她彻底坏了,没办法只能用串口下载了,以前没弄过,果然碰壁了。 首先、将boot0置1,boot1置0 其次就是串口的选择问题,注意需要选择串口1进行程序的下载
[单片机]
关于<font color='red'>stm32</font>串口下载的问题
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved