找回密码
 立即注册
首页 业界区 安全 STM32串口缓冲区

STM32串口缓冲区

党新苗 2025-6-11 15:26:08
在嵌入式开发中,外设通信(如UART、SPI、I2C)的数据接收常面临两大挑战:不定时、不定量数据的实时处理和高频率数据流下的稳定性保障。传统的轮询方式效率低下,而中断驱动的接收逻辑又容易因处理延迟导致数据丢失。
本文提出了一种基于STM32 HAL库的轻量级环形缓冲区解决方案!
已解决
非阻塞数据接收:避免因数据处理延迟导致外设中断阻塞
动态数据缓存:支持UART、SPI、I2C等多种外设的异步数据流
内存高效利用:通过环形缓冲区设计减少内存碎片
跨平台兼容:提供GCC与Keil双版本静态库,无缝适配不同开发环境
实现原理

  • HAL库的RxXferCount机制
    STM32 HAL库为每个外设句柄(如UART_HandleTypeDef)维护了RxXferCount成员。该计数器在每次接收一个字节后递增,当传输完成时触发回调并重置。项目通过监控RxXferCount的值变化,动态追踪接收数据的边界。
  • 环形缓冲区设计
    写入策略:通过比较当前RxXferCount与上次记录值的差值,计算新数据长度
    覆盖保护:当缓冲区满时自动覆盖旧数据(可配置为阻塞模式)
使用示例
  1. #include "peripheral_buff.h"
  2. PeripheralBufHandle PeripheralUart1Buf;
  3. UART_HandleTypeDef uart1_handle;
  4. char uart1_buffer[1024];
  5. int uart1_buffer_len;
  6. int main()
  7. {
  8.     HAL_Init();
  9.     SystemClock_Config(); // 此处未实现
  10.     USART1_Init(921600);  // 此处未实现
  11.     // 缓冲区初始化
  12.     PeripheralUart1Buf = PeripheralBuffer_Init((const uint16_t *)&uart1_handle.RxXferCount, 1024);
  13.     if (!PeripheralUart1Buf)
  14.     {
  15.         printf("peripheral_buffer 初始化失败!(calloc();返回 NULL,检查 startup_stm32fxx_hd.s Heap_Size 值)\n");
  16.         printf("相关网址: https://blog.csdn.net/weixin_42518229/article/details/108574311 \n");
  17.     }
  18.     // 开启中断接收
  19.     HAL_UART_Receive_IT(&uart1_handle, (uint8_t *)PeripheralUart1Buf->Buf, PeripheralUart1Buf->Size);
  20.     while (1)
  21.     {
  22.         if (PeripheralBuffer_ReadInterval(PeripheralUart1Buf)) // 判断当前传输是否已停止,非必要
  23.         {
  24.             uart1_buffer_len = PeripheralBuffer_ReadAvailable(PeripheralUart1Buf); // 读取缓冲区内内容长度
  25.             if (uart1_buffer_len > 0)
  26.             {
  27.                 if (uart1_buffer_len > sizeof(uart1_buffer))
  28.                     uart1_buffer_len = sizeof(uart1_buffer);
  29.                 PeripheralBuffer_ReadBytes(PeripheralUart1Buf, uart1_buffer, uart1_buffer_len); // 读取缓冲区内内容
  30.                 uart1_buffer[uart1_buffer_len] = 0;
  31.                 printf("缓冲区数据 %s\n", uart1_buffer);
  32.             }
  33.         }
  34.         HAL_Delay(10);
  35.     }
  36.     return 0;
  37. }
复制代码
注意
1.单次接收超长文件而又未及时处理,会导致数据覆盖。
2.用户缓冲区数据边界
仓库地址
[https://github.com/DYXX-X/peripheral_buff]

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册