欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > STM32F103_LL库+寄存器学习笔记12.1 - 串口DMA高效收发实战:引入ringbuffer结构(开源库lwrb)

STM32F103_LL库+寄存器学习笔记12.1 - 串口DMA高效收发实战:引入ringbuffer结构(开源库lwrb)

2025/5/18 3:25:57 来源:https://blog.csdn.net/wallace89/article/details/147902570  浏览:    关键词:STM32F103_LL库+寄存器学习笔记12.1 - 串口DMA高效收发实战:引入ringbuffer结构(开源库lwrb)

导言


在这里插入图片描述
在STM32串口通信中,传统中断方式处理效率低、耦合度高,难以应对高频收发场景。为此,本章引入ringbuffer结构,配合USART1的DMA机制,实现接收数据的自动搬运与发送数据的非阻塞输出。ringbuffer作为中间缓冲区,有效解耦了硬件DMA与用户代码逻辑,不仅提升了数据处理效率,也增强了系统稳定性和可扩展性。

效果如下:
在这里插入图片描述
如上所示,从SSCOM串口助手与单片机的全局变量看来,单片机没有丢包。单片机一共发送356607bytes,接收344960bytes。

项目地址:
github:

  • LL库: https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_ll_library12_1_usart_dma_ringbuffer
  • 寄存器方式:https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_reg_library12_1_usart_dma_ringbuffer

gitee(国内):

  • LL库: https://gitee.com/wallace89/MCU_Develop/tree/main/stm32f103_ll_library12_1_usart_dma_ringbuffer
  • 寄存器方式: https://gitee.com/wallace89/MCU_Develop/tree/main/stm32f103_reg_library12_1_usart_dma_ringbuffer

一、代码


LL库与寄存器方式的代码类似的,这里只介绍LL库。

1.1、myUsartDrive.c

1.1.1、ringbuffer初始化

在这里插入图片描述
在这里插入图片描述
如上所示,完成发送ringbuffer与接收ringbuffer的初始化。

1.1.2、接收ringbuffer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上所示:

  1. 函数USART1_Put_Data_Into_Ringbuffer()的作用是将从串口收到的数据放入ringbuffer。此外,它会有一些额外的处理。比如当ringbuffer的剩余空间不足以放入新的数据时,会将旧的数据丢弃,让后放入新的数据。
  2. 在DMA接收中断与串口空闲接收中断里分别调用函数USART1_Put_Data_Into_Ringbuffer(),将接收到的数据放入ringbuffer。

1.1.3、发送ringbuffer

在这里插入图片描述
如上所示,函数USART1_Put_TxData_To_Ringbuffer()的目的是给其他模块调用,将需要发送的数据先放入ringbuffer,等待DMA一次性发送出去。

1.1.4、接收、发送ringbuffer的处理

在这里插入图片描述

1.2、main.c

在这里插入图片描述

二、细节补充


2.1、其他模块的代码,调用哪个函数将字符串从串口发送出去??

在这里插入图片描述
如上所示,外部的模块可以调用两个函数,将数据从串口发送出去:

  1. 函数USART1_SendString_Blocking()串行发送。
  2. 函数USART1_Put_TxData_To_Ringbuffer()非阻塞,异步发送。

2.2、在Keil的AC5编译器上移植lwrb库,报错找不到头文件"<stdatomic.h>"

<stdatomic.h> 是什么?
<stdatomic.h>C11 标准引入的一个头文件,提供了原子操作相关的API和类型(比如 atomic_ulong),用来多线程环境下保证并发读写安全。在本 lwrb 库中,作者默认用 atomic_ulong 替代普通的 unsigned long,用于 lwrb_sz_atomic_t 这些类型,以支持并发操作时的原子性,防止数据竞争和不可预期的行为。

为什么你编译时报错?
AC5 (Keil MDK ARM Compiler 5) 并不支持 C11 的 <stdatomic.h>(它只支持到C99),所以会提示找不到这个头文件。

AC5编译器该怎样处理?
对于 STM32 这类 MCU 项目,大部分情况下不会涉及真正的多核并发,一般都是单核+中断(或者临界区保护),并不需要用到C11原子操作。你只要在项目里定义 LWRB_DISABLE_ATOMIC(在 options->C/C++->Define 增加宏定义,或者在代码最前面加上 #define LWRB_DISABLE_ATOMIC), wrb 库就会自动改为普通的 unsigned long,不会再包含 <stdatomic.h>,也就兼容Keil了!
在这里插入图片描述

#define LWRB_DISABLE_ATOMIC // 在AC5编译器环境下,必须这个宏定义

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词