站群系统开发adsl服务器建网站
导言

 在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

 
 
 如上所示:
- 函数USART1_Put_Data_Into_Ringbuffer()的作用是将从串口收到的数据放入ringbuffer。此外,它会有一些额外的处理。比如当ringbuffer的剩余空间不足以放入新的数据时,会将旧的数据丢弃,让后放入新的数据。
- 在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、其他模块的代码,调用哪个函数将字符串从串口发送出去??

 如上所示,外部的模块可以调用两个函数,将数据从串口发送出去:
- 函数USART1_SendString_Blocking()串行发送。
- 函数USART1_Put_TxData_To_Ringbuffer()非阻塞,异步发送。
