STM32F407学习记录(四)环形缓冲区

发布时间:2026/7/13 14:06:07

STM32F407学习记录(四)环形缓冲区
本质上是一个首尾相连的固定大小数组。它通过两个指针读指针Head和写指针Tail在数组内循环移动实现对数据的顺序存取。缓冲区实现包含4要素typedef struct { uint8_t *buffer; // 指向存储区的指针 uint32_t head; // 读指针指向下一个要被读出的数据 uint32_t tail; // 写指针指向下一个要存入的位置 uint32_t size; // 缓冲区总大小为了效率通常设为 2 的幂 } ring_buffer_t;写操作逻辑就是往ring_buffer数组中tail所指向位置写入一个数据然后tail移动至下一个需要写入的位置。例如往环形缓冲区中写入2、0、2、6四个数据那么环形缓冲区中的数据如下现在往里面继续写3个数据图1这时候发现tail已经来到了buffer的最后一个位置如果再往里面写一个数据tail应该回到开头也就是现在head所在的地方但这时候会发现headtail和一开始缓冲区为空的时候一致。所以一般情况下当tai如图1所示判断缓冲区满就不继续往缓冲区写入了注意根据应用场景你也可以继续写入进行覆盖。读操作逻辑就是从head所指示的位置读取数据然后将head移动至下一个可以读的位置。例如读取4个数据2、0、2、6。此时head指向数据0的位置。现在继续读取3个数据此时发现所有数据都读到了并且headtail也就是说缓冲区为空。当继续往这个缓冲区写数据时tail就会跳回到缓冲区开头。读操作同理。至此形成了一个环形的缓冲区。“空/满”判断判空head tail判满取模(tail 1) % size head注意取模操作比较费时如果对速度有要求可以将缓存区的大小设置为2的幂次方例如32、64、256。这样判断满的表达式可以改为(tail 1) (size - 1) head附C代码ringBuffer.c#include ./SYSTEM/ringBuffer/ringBuffer.h // 初始化 void ring_buffer_init(ring_buffer_t *rb, uint8_t *buffer, uint32_t size) { rb-buffer buffer; rb-head 0; rb-tail 0; rb-size size; // 注意size 必须是 2 的幂例如 64 } // 写入一个字节 uint8_t ring_buffer_push(ring_buffer_t *rb, uint8_t data) { uint32_t next_tail (rb-tail 1) (rb-size - 1); // 如果满了丢弃新数据防覆盖策略 if (next_tail rb-head) { return 0; // 写入失败 } rb-buffer[rb-tail] data; rb-tail next_tail; return 1; // 写入成功 } // 读取一个字节 uint8_t ring_buffer_pop(ring_buffer_t *rb, uint8_t *data) { if (rb-head rb-tail) { return 0; // 缓冲区为空 } *data rb-buffer[rb-head]; rb-head (rb-head 1) (rb-size - 1); return 1; // 读取成功 } // 查询当前待读数据长度方便主循环判断是否有包需要处理 uint32_t ring_buffer_available(ring_buffer_t *rb) { if (rb-tail rb-head) { return rb-tail - rb-head; } else { return rb-size - rb-head rb-tail; } }ringBuffer.h#ifndef __RINGBUFFER_H #define __RINGBUFFER_H typedef struct { uint8_t *buffer; // 指向存储区的指针 uint32_t head; // 读指针指向下一个要被读出的数据 uint32_t tail; // 写指针指向下一个要存入的位置 uint32_t size; // 缓冲区总大小为了效率通常设为 2 的幂 } ring_buffer_t; void ring_buffer_init(ring_buffer_t *rb, uint8_t *buffer, uint32_t size); uint8_t ring_buffer_push(ring_buffer_t *rb, uint8_t data); uint8_t ring_buffer_pop(ring_buffer_t *rb, uint8_t *data); uint32_t ring_buffer_available(ring_buffer_t *rb); #endif主函数调用工程基于正点原子串口收发实验#include ./SYSTEM/sys/sys.h #include ./SYSTEM/usart/usart.h #include ./SYSTEM/delay/delay.h #include ./SYSTEM/ringBuffer/ringBuffer.h #include ./SYSTEM/malloc/malloc.h ring_buffer_t rb; /* 定义环形缓冲区 */ int main(void) { sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */ delay_init(168); /* 延时初始化 */ usart_init(84, 115200); /* 串口初始化为115200 */ my_mem_init(SRAMIN); /* 内存池初始化 */ uint8_t *rx_buff mymalloc(SRAMIN, 64);/* 向内存池申请一段内存作为循环缓冲区共64字节 */ ring_buffer_init(rb, rx_buff, 64); /* 初始化环形缓冲区 */ while (1) { uint8_t data; while(ring_buffer_pop(rb, data)) { USART1-DR data; while ((USART1-SR 0X40) 0); /* 等待发送结束 */ printf(\r\n); /* 插入换行 */ } delay_ms(10); } } /** * brief 串口X中断服务函数 * param 无 * retval 无 */ void USART1_IRQHandler(void) { uint8_t rxdata; if (USART1-SR (1 5)) /* 接收到数据 */ { rxdata USART1-DR; ring_buffer_push(rb, rxdata); } }实验效果附工程链接通过网盘分享的文件串口收发之环形缓冲区.zip链接: https://pan.baidu.com/s/1ZBIpqIIOy4G-93C6t0NIJA?pwdwy6r 提取码: wy6r

相关新闻

慢一点也挺好:在快节奏时代找回生活的掌控感

慢一点也挺好:在快节奏时代找回生活的掌控感

2026/7/13 14:06:07

我们总被要求快一点,却不知一路的繁花似锦,才是人间最美的华章。每日一言(1/1)一切真实与虚假,一切辉煌与破灭,只存后人之言,只存岁月之中。引言:被速度裹挟的时代我们生活在一个被“快”字定义…

【新能源汽车研发测试能力建设深度解析:设备、趋势与行业展望】

【新能源汽车研发测试能力建设深度解析:设备、趋势与行业展望】

2026/7/13 14:06:07

摘要 随着全球能源转型加速,新能源汽车产业成为技术竞争的主战场。本文系统梳理新能源汽车研发测试的核心能力建设现状,聚焦“三电系统”、智能网联等关键技术,结合行业政策、市场规模及典型案例,解析测试设备发展趋势与未来挑战,为从业者提供全面参考。 关键词:新能源…

OSPF 外部路由 Type-1 vs Type-2:3个实验场景详解开销计算与选路差异

OSPF 外部路由 Type-1 vs Type-2:3个实验场景详解开销计算与选路差异

2026/7/13 13:56:07

OSPF外部路由Type-1与Type-2:3种典型场景下的选路逻辑与实战验证在网络工程师的日常工作中,OSPF协议的部署与优化占据了重要位置。当企业网络需要与外部系统互联时,外部路由的引入与选路机制成为关键设计点。本文将深入探讨OSPF中两种外部路由…

理查森外推法实战:3 步将 O(h^2) 差分精度提升至 O(h^4) 的 Python 代码解析

理查森外推法实战:3 步将 O(h^2) 差分精度提升至 O(h^4) 的 Python 代码解析

2026/7/13 23:46:37

理查森外推法实战:3步将差分精度从O(h)提升至O(h⁴)的Python实现数值微分在科学计算中扮演着关键角色,但传统中心差分方法的精度往往难以满足高精度需求。本文将揭示如何通过理查森外推法,仅用3个步骤就能将二阶精度(O(h))提升至四阶精度(O(h…

Unity插件合集实战指南:从视觉效果到网络同步的系统化开发工具箱

Unity插件合集实战指南:从视觉效果到网络同步的系统化开发工具箱

2026/7/13 23:46:37

1. 项目概述:一套能让你从“能跑”到“跑得漂亮”的Unity开发资源库干了这么多年Unity开发,我越来越觉得,一个项目的成败,很多时候不在于你写了多少行惊为天人的代码,而在于你是否选对了“轮子”。这个所谓的“Unity插…

Win11企业版LTSC:旧电脑重装系统性能优化全攻略

Win11企业版LTSC:旧电脑重装系统性能优化全攻略

2026/7/13 23:46:37

很多朋友都有这样的经历:旧电脑用久了越来越卡,想重装系统又担心装完还是卡,甚至更慢。特别是看到Win11的硬件要求比较高,更不敢轻易尝试。其实,选择适合的Win11版本和正确的安装方法,完全可以让旧电脑焕发…

Bootstrap 5 可视化工具对比:LayoutIt、Fancy Boot、Style Bootstrap 3款工具核心功能与代码生成效率实测

Bootstrap 5 可视化工具对比:LayoutIt、Fancy Boot、Style Bootstrap 3款工具核心功能与代码生成效率实测

2026/7/13 23:46:37

Bootstrap 5 可视化工具对比:LayoutIt、Fancy Boot、Style Bootstrap 3款工具核心功能与代码生成效率实测对于需要快速构建前端原型的中级前端开发者或全栈工程师来说,Bootstrap可视化工具能显著提升开发效率。本文将深入对比三款主流工具——LayoutIt、…

模板驱动型文档自动化:让重复文档生产变智能填空

模板驱动型文档自动化:让重复文档生产变智能填空

2026/7/13 23:46:37

1. 项目概述:用模板把文档生产变成“填空题” 你有没有过这种体验:每周一早上打开电脑,第一件事就是复制上个月的周报模板,改日期、换数据、删掉“待跟进”里已经解决的条目,再手动调整几处格式——整整40分钟&#xf…

eNSP 1.2.00.510 路由器CLI“###”问题:3步定位IP冲突与防火墙配置

eNSP 1.2.00.510 路由器CLI“###”问题:3步定位IP冲突与防火墙配置

2026/7/13 23:36:36

eNSP路由器CLI界面"###"故障:从现象到根因的系统排查指南当你在eNSP模拟器中启动AR路由器,却发现命令行界面(CLI)不断输出"###"符号而无法正常交互时,这种看似简单的现象往往隐藏着复杂的网络配置问题。本文将带你深入剖…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/13 7:41:16

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/13 20:43:19

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/13 20:43:10

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…

卡梅德生物技术快报|纯化重组蛋白:变异链球菌 SepM 截短蛋白载体构建、诱导优化与纯化重组蛋白全套参数方案

卡梅德生物技术快报|纯化重组蛋白:变异链球菌 SepM 截短蛋白载体构建、诱导优化与纯化重组蛋白全套参数方案

2026/7/13 0:05:25

1 研究背景与现存技术痛点(提出问题)在口腔微生物分子机制研究中,SepM 蛋白酶是调控变异链球菌群体感应、致龋菌素合成的核心功能蛋白,体外功能验证、抗体开发均依赖高纯度可溶性 SepM 蛋白。当前原核表达体系针对 SepM 存在三大技…

卡梅德生物技术快报|重组蛋白的表达和纯化:IMAC 金属螯合色谱全流程工艺手册|基质 - 配基 - 金属离子匹配与蛋白质分离纯化参数优化

卡梅德生物技术快报|重组蛋白的表达和纯化:IMAC 金属螯合色谱全流程工艺手册|基质 - 配基 - 金属离子匹配与蛋白质分离纯化参数优化

2026/7/13 0:05:25

1 研究背景与现存技术痛点(提出问题)基因工程、蛋白质组学、生物制药研发流程中,蛋白质分离纯化是决定下游实验成败的关键环节。当前实验室常规蛋白质分离纯化工艺存在三类难以标准化的技术瓶颈:传统离子交换、分子筛层析无特异性…

卡梅德生物技术快报|蛋白质分离纯化:肠激酶可溶性原核表达 + 两步层析全参数|标准化蛋白质分离纯化 SOP

卡梅德生物技术快报|蛋白质分离纯化:肠激酶可溶性原核表达 + 两步层析全参数|标准化蛋白质分离纯化 SOP

2026/7/13 0:05:25

研究痛点提出(提出问题)重组肠激酶是融合标签切除核心工具酶,当前原核表达体系存在三大标准化难题,直接阻碍可复现的蛋白质分离纯化流程搭建:Trx、GST、单 SUMO 标签融合产物绝大多数为包涵体,沉淀占比超 9…