ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

手把手实战教程:用Ring-Buffer实现串口UART数据收发缓冲

手把手实战教程:用Ring-Buffer实现串口UART数据收发缓冲 手把手实战教程用Ring-Buffer实现串口UART数据收发缓冲【免费下载链接】Ring-BufferA simple ring buffer (circular buffer) designed for embedded systems.项目地址: https://gitcode.com/gh_mirrors/rin/Ring-Buffer在嵌入式开发中串口UART是最常用的通信外设而串口UART数据收发缓冲的设计直接影响数据是否丢失、系统是否卡顿。本教程将手把手带你使用轻量级开源库Ring-Buffer环形缓冲区在 STM32 等单片机上实现高效、无锁的串口数据收发缓冲全程零依赖、只需两个源文件。快速了解Ring-Buffer 是一个专为嵌入式系统设计的简单环形缓冲区库核心代码只有 ringbuffer.h 与 ringbuffer.c 两个文件API 简洁、内存占用极低非常适合在资源受限的 MCU 上做串口缓冲。为什么串口收发需要环形缓冲区先看一个常见痛点很多新手在写串口接收时习惯在主循环里死等数据或只用单字节变量暂存。这两种做法有两个致命问题丢数据中断来不及处理时新到的字节会覆盖旧数据卡系统主程序被串口接收绑死其他任务无法执行。而环形缓冲区用读指针 tail与写指针 head循环读写生产者串口中断只负责写消费者主循环只负责读两者互不阻塞从根源上解决丢数据与卡顿问题。环形缓冲区原理图解head 与 tail 的循环读写 上图是环形缓冲区的核心原理数据存储在一块固定大小的数组里写指针 head 负责生产读指针 tail 负责消费指针走到数组末尾时自动绕回开头首尾相接形成环。因此它天生具备两大优势零拷贝读写只移动指针不搬移数据CPU 开销极低天然异步中断写入与主循环读取完全解耦互不干扰。Ring-Buffer 快速上手三步完成初始化 这个库的使用极其简单只需 3 步就能建好一个缓冲区完整示例见 examples/simple.c定义缓冲区数组与句柄调用ring_buffer_init()完成初始化用ring_buffer_queue()/ring_buffer_dequeue()读写数据。两个必须记住的约定缓冲区大小必须是2 的幂如 64、128、256实际可用容量为大小减 164 字节数组最多存 63 字节这是为了能用位运算实现极速取模。手把手实战在 STM32 上实现串口 UART 接收缓冲 下面进入今天的重头戏——把 Ring-Buffer 集成进 STM32 工程实现完整的串口 UART 接收缓冲整体流程如下第一步获取源码并移植到工程获取源码后将ringbuffer.h与ringbuffer.c复制到工程目录并在编译器的头文件路径中加入该目录即可git clone https://gitcode.com/gh_mirrors/rin/Ring-Buffer第二步声明并初始化接收缓冲区#define RX_BUF_SIZE 256 char rx_buf[RX_BUF_SIZE]; ring_buffer_t uart_rx; ring_buffer_init(uart_rx, rx_buf, RX_BUF_SIZE);第三步在串口中断里写入数据UART 接收中断触发时把收到的字节直接丢进缓冲区中断服务程序保持极短void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE)) { ring_buffer_queue(uart_rx, USART_ReceiveData(USART1)); } }第四步在主循环里读取处理主循环随时调用ring_buffer_dequeue()取走数据配合ring_buffer_num_items()判断数据量逐字节解析命令或数据帧char ch; while (ring_buffer_dequeue(uart_rx, ch)) { process_byte(ch); // 解析、组帧、执行命令 }发送缓冲怎么用一发一收原理相同 接收用缓冲发送同样适用。先把待发送数据通过ring_buffer_queue_arr()批量写入发送缓冲区再在发送完成中断里逐个 dequeue 发出即可实现攒一批、发一批的高效发送避免逐字节阻塞等待。这正是本库批量接口queue_arr/dequeue_arr的典型用法可参考 examples/tail.c——一个迷你版tail -c命令的实现。常用 API 速查表 函数作用ring_buffer_init初始化 / 重置缓冲区ring_buffer_queue写入 1 字节满时覆盖最旧数据ring_buffer_queue_arr批量写入数组ring_buffer_dequeue读取 1 字节空时返回 0ring_buffer_dequeue_arr批量读取ring_buffer_peek查看第 N 个字节但不取出ring_buffer_is_empty/is_full判断空 / 满ring_buffer_num_items当前缓冲区数据量实战避坑指南3 个高频问题 ⚠️缓冲区大小不是 2 的幂ring_buffer_init会直接断言失败定义数组前务必检查可用容量是 size-1规划容量时按需预留防止误判缓冲区已满中断原子性若主循环也向同一缓冲区写入需临时关中断保护如__disable_irq()避免读写竞争导致数据错乱。总结一次移植到处通用 ✅用 Ring-Buffer 实现串口 UART 数据收发缓冲代码量小、无锁高效、移植简单无论是 STM32、AVR 还是其他 MCU 都能轻松集成。完整的 API 说明可查阅 ringbuffer.h 中的注释配套示例与构建脚本位于 examples/ 目录的 Makefile。现在就动手把串口丢数据的问题彻底解决吧【免费下载链接】Ring-BufferA simple ring buffer (circular buffer) designed for embedded systems.项目地址: https://gitcode.com/gh_mirrors/rin/Ring-Buffer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表