STM32串口环形缓冲区实现

2023-05-16

stm32串口环形缓冲区

一、ringbuff.h

#ifndef _RING_BUFFER_H_
#define _RING_BUFFER_H_

enum
{
	RING_FALSE,
	RING_TRUE,
};

enum
{
	RING_ERR,
	RING_OK,
};

typedef struct ringBuff{
    unsigned int head;     //队列的头部            
    unsigned int tail;     //队列的尾部          
    unsigned int size;     //队列的大小         
    unsigned char *buffer; //数据缓冲区指针
}RingBuff_t, *pRingBuff_t;

void RingBuff_Init(RingBuff_t *pRingBuff, unsigned char *pBuff, unsigned int buf_size);
int RingBuff_ReadNByte (RingBuff_t *pRingBuff, unsigned char *pData, int size);
int RingBuff_WriteNByte(RingBuff_t *pRingBuff, unsigned char *pData, int size);
int RingBuff_GetLen(RingBuff_t *pRingBuff);
unsigned char RingBuff_GetHeadItem(RingBuff_t *pRingBuff);
unsigned char RingBuff_GetIndexItem(RingBuff_t *pRingBuff, int index);

#endif

二、ringbuff.c

#include "ring_buffer.h"
#include "main.h"
#include "stdio.h"

//环形缓冲区初始化
void RingBuff_Init(RingBuff_t *pRingBuff, unsigned char *pBuff, unsigned int buf_size)
{
	if(NULL == pRingBuff || NULL == pBuff)
		return;
	
	pRingBuff->head = 0;
	pRingBuff->tail = 0;
	pRingBuff->size = buf_size;
	pRingBuff->buffer = pBuff;
}

//判断环形缓冲区是否为空
int RingBuff_isEmpty(RingBuff_t *pRingBuff) 
{
	if(NULL == pRingBuff)
		return RING_FALSE;
	
	if(pRingBuff->head == pRingBuff->tail)
	{
		return RING_TRUE;
	}
	return RING_FALSE;
}

//判断环形缓冲区是否为满
static int RingBuff_isFull(RingBuff_t *pRingBuff)
{
	if(NULL == pRingBuff)
		return RING_FALSE;

	if((pRingBuff->tail+1)%pRingBuff->size == pRingBuff->head)
	{
		return RING_TRUE;
	}
	return RING_FALSE;
}

//从环形缓冲区取出一个字节
int RingBuff_ReadOneByte(RingBuff_t *pRingBuff, unsigned char *pData)
{
	if(NULL == pRingBuff || NULL == pData)
		return RING_ERR;

	//判空
	if(RING_TRUE == RingBuff_isEmpty(pRingBuff))
	{
		//printf("ring buffer is empty!\r\n");
		return RING_ERR;
	}

	*pData = pRingBuff->buffer[pRingBuff->head];
	pRingBuff->head = (pRingBuff->head+1)%pRingBuff->size;
	return RING_OK;
}

//向环形缓冲区写入一个字节
static int RingBuff_WriteOneByte(RingBuff_t *pRingBuff, unsigned char *pData)
{
	if(NULL == pRingBuff || NULL == pData)
		return RING_ERR;

	//判满
	if(RING_TRUE == RingBuff_isFull(pRingBuff))
	{
		//printf("ring buffer is full!\r\n");
		return RING_ERR;
	}

	pRingBuff->buffer[pRingBuff->tail] = *pData;
	pRingBuff->tail = (pRingBuff->tail+1)%pRingBuff->size;
	return RING_OK;
}

//从环形缓冲区读多个字节
int RingBuff_ReadNByte(RingBuff_t *pRingBuff, unsigned char *pData, int size)
{
	if(NULL == pRingBuff || NULL == pData)
		return RING_ERR;

	for(int i = 0; i < size; i++)
	{
		RingBuff_ReadOneByte(pRingBuff, pData+i);
	}
	return RING_OK;
}

//向环形缓冲区写多个字节
int RingBuff_WriteNByte(RingBuff_t *pRingBuff, unsigned char *pData, int size)
{
	if(NULL == pRingBuff || NULL == pData)
		return RING_ERR;

	for(int i = 0; i < size; i++)
	{
		RingBuff_WriteOneByte(pRingBuff, pData+i);
	}
	return RING_OK;
}

//获取当前环形缓冲区中数据长度
int RingBuff_GetLen(RingBuff_t *pRingBuff)
{
	if(NULL == pRingBuff)
		return RING_ERR;

	if(pRingBuff->tail >= pRingBuff->head)
	{
		return pRingBuff->tail - pRingBuff->head;
	}
	
	return pRingBuff->tail + pRingBuff->size - pRingBuff->head;
}

//获取当前头部数据
unsigned char RingBuff_GetHeadItem(RingBuff_t *pRingBuff)
{
	if(NULL == pRingBuff)
		return RING_ERR;
	
	return pRingBuff->buffer[pRingBuff->head];
}

//获取指定下标数据
unsigned char RingBuff_GetIndexItem(RingBuff_t *pRingBuff, int index)
{
	if(NULL == pRingBuff || index > pRingBuff->size-1)
		return RING_ERR;

	return pRingBuff->buffer[index%pRingBuff->size];
}

三、应用例程(配合串口接受DMA使用)

extern UART_HandleTypeDef huart1;
RingBuff_t Uart1_RingBuff;
uint8_t USART1_DMA_Buff[USART1_DMA_SIZE];
uint8_t USART1_RingBuff[USART1_RING_BUFF_SIZE];

//通讯接口环形缓冲区初始化
void Data_InterFace_Init(void)
{
	RingBuff_Init(&Uart1_RingBuff, USART1_RingBuff, USART1_RING_BUFF_SIZE);
}

//串口DMA接收完成回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(&huart1 == huart)
	{
		//将数据拷贝到串口环形缓冲区中
		RingBuff_WriteNByte(&Uart1_RingBuff, USART1_DMA_Buff, USART1_DMA_SIZE);
		
		//使能串口接收DMA
		HAL_UART_Receive_DMA(&huart1, USART1_DMA_Buff, USART1_DMA_SIZE);
	}
}
//使能串口DMA
void Board_Init(void)
{
	//接口缓冲区初始化
	Data_InterFace_Init();
	
	//使能串口1接收DMA
	HAL_UART_Receive_DMA(&huart1, USART1_DMA_Buff, USART1_DMA_SIZE);
}

/* USER CODE END Header_Uart_Dma_Task */
void Uart_Dma_Task(void const * argument)
{
  /* USER CODE BEGIN Uart_Dma_Task */
    pParameter_t parameter = NULL;
    pRingBuff_t pRingBuff = NULL;
	uint8_t data_buff[10];
	uint8_t flag, t_data;
	
	parameter = (pParameter_t)argument;
	pRingBuff = parameter->Data_InterFace[UART1_NUM].pRingBuffCB;
	/* Infinite loop */
	for(;;)
	{	
		while(!RingBuff_isEmpty(pRingBuff))
		{
			if(RingBuff_GetHeadItem(pRingBuff) == 0xEB
			 &&RingBuff_GetIndexItem(pRingBuff, pRingBuff->head+1) == 0x90)
			{
				if(RingBuff_GetLen(pRingBuff) >= 10)
				{
					RingBuff_ReadNByte(pRingBuff, data_buff, 10);
					flag = 1;
				}
				else
				{
					break;
				}
			}
			else
			{
				RingBuff_ReadOneByte(pRingBuff, &t_data);
			}
		}
		
		//判断是否有收到报文
		if(1 == flag)
		{
			flag = 0;
			BSP_Uart1_SendData(data_buff, 10);
		}
		
		osDelay(10);
	}
  /* USER CODE END Uart_Dma_Task */
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32串口环形缓冲区实现 的相关文章

  • 基于stm32f103zet6的DS1302学习

    由于硬件出了问题 xff0c 也就是外部低速晶振没用 xff0c 震不起来 xff0c 然后查看了网上的帖子 xff0c STM32的RTC果然口碑不怎么样 xff0c 所以果断换DS1302 xff0c 在移植的过程中还算顺利 xff0c

随机推荐

  • 基于stm32f103zet6之使用FSMC驱动TFT的学习

    在完成IO驱动彩屏的试验后 xff0c 就准备着手使用FSMC来驱动彩屏 xff0c 先了解一下预备知识 一 所谓的FSMC机制 简单介绍FSMC在这篇博文里面很清楚 xff0c 推荐一下 http blog csdn net king b
  • (转)ds18b20时序说明

    ds18b20时序说明 新手在DS18B20读写过程中要犯很多错误 老衲普度众生 xff0c 简要说明它怎么用 1 过程1 2是初始化过程 xff0c 每次读取都要初始化 xff0c 否则18b20处于待机状态 xff0c 无法成功读取 过
  • H桥驱动芯片IR2110功能简介

    1 1 驱动芯片IR2110功能简介 在功率变换装置中 xff0c 根据主电路的结构 xff0c 起功率开关器件一般采用直接驱动和隔离驱动两种方式 美国IR公司生产的IR2110驱动器 xff0c 兼有光耦隔离和电磁隔离的优点 xff0c
  • 关于示波器是否必须要接地线的疑问

    这是一个非常隐蔽的问题 xff0c 稍不注意 xff0c 在接入示波器时 xff0c 就会导致线路板上的某些芯片突然爆炸 xff0c 不仅会对项目产生非常大的影响 xff0c 也足以让我们着实郁闷上几天 所以 xff0c 应该足够引起电路设
  • POCO C++库学习和分析 -- 进程

    POCO C 43 43 库学习和分析 进程 Poco Foundation库中涉及进程的内容主要包括了4个主题 xff0c 分别是进程 Process 进程间同步 xff08 inter process synchronization x
  • Mysql安装后在服务里找不到和服务启动不起来的解决方法

    一 安装完MySQL后找不到服务 在那完MySQL数据库后 xff0c 在计算机管理 61 61 服务和应用程序 61 61 服务中找不到MySQL的服务 解决方法 xff1a 1 以管理员的身份运行cmd或者Windows powersh
  • C++中虚继承

    一 虚继承和虚基类 1 多继承产生的冲突 在C 43 43 中多继承时很容易产生命名冲突 xff0c 即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字 xff0c 命名冲突依然有可能发生 xff0c 比如典型的是菱形继承 x
  • 跨平台C++单元测试框架——GTest

    1 简介 GTest是google公司发布的一个跨平台的 Liunx Mac OS X Windows Cygwin Windows CE and Symbian C 43 43 单元测试框架 它提供了丰富的断言 致命和非致命判断 参数化
  • 音频格式之AAC(高级音频编码技术)

    1 简介 ACC xff08 Advanced Audio Coding xff0c 高级音频编码 xff09 是杜比实验室为音乐社区提供的技术 xff0c 出现于1997年 xff0c 基于MPEG 2的音频编码技术 2000年 xff0
  • C++11之lambda回调设置与应用

    在程序中有时候我们需要实现回调效果 xff0c 比如先设置监听 xff0c 然后在后面具体执行完某个操作后再将该操作的结果通知给前面监听中 这种机制实际很常用 xff0c 比如window底下的消息机制 xff0c Qt中的信号槽的机制都有
  • 高速的C/C++编译工具——ccache

    1 简介 ccache xff08 compiler cache 的缩写 xff09 是一个编译器缓存 xff0c 该工具会高速缓存编译生成的信息 xff0c 并在编译的特定部分使用高速缓存的信息 xff0c 比如头文件 xff0c 这样就
  • Django17:内建用户系统

    1 定义 Django带有一个用户认证系统 它处理用户账号 组 权限以及基于cookie的用户会话 用户可以直接是使用Django自带的用户表 2 基本字段 模型类位置from django contrib contrib auth mod
  • Django18:文件上传

    1 上传规范 xff08 1 xff09 前端HTML 文件上传必须为POST提交方式 表达 lt form gt 中文件上传时必须带有enctype 61 multipart formdata 时才会包含文件内容数据 表单中用 lt in
  • Django19:发送邮件

    1 邮件相关协议 xff08 1 xff09 SMTP SMTP xff08 Simple Mail Transfer Protocol xff09 xff0c 简单邮件传输协议 xff08 25号端口 xff09 它是一组用于从原地址到目
  • JsonCpp的基本用法

    1 JsonCpp C 43 43 库 xff0c 允许操作JSON值 xff0c 包括与字符串串行化和序列化 它可在反序列化 序列化步骤中保留现有注释 xff0c 使其成为存储用户输入文件的便捷方式 是一个第三方JSON解析库 xff0c
  • POCO C++库学习和分析 -- 文件系统

    POCO C 43 43 库学习和分析 文件系统 既然作为一个框架性的库 xff0c 自然会提供对于文件系统的操作 在Poco库中 xff0c 封装了一些类去完成上述操作 这些类包括了 xff1a 1 Poco Path 2 Poco Fi
  • C++中的HTTP协议

    1 HTTP Hyper Text Transfer Protocol xff08 超文本传输协议 xff09 是一种通信协议 xff0c 它允许将超文本标记语言 HTML 文档从Web服务器传送到客户端的浏览器 在Internet中所有的
  • C++中析构函数为虚函数

    1 析构函数是否定义为虚函数的区别 xff08 1 xff09 析构函数定义为虚函数时 xff1a 基类指针可以指向派生类的对象 xff08 多态性 xff09 xff0c 如果删除该指针delete p xff1b 就会调用该指针指向的派
  • [Linux C]TCP通讯例程

    这个是最最最基本的例程 xff0c 先开一个坑 xff0c 稍后再慢慢完善 服务端程序 include lt stdio h gt include lt stdlib h gt include lt string h gt include
  • STM32串口环形缓冲区实现

    stm32串口环形缓冲区 一 ringbuff h span class token macro property span class token directive hash span span class token directiv