STM32串口缓冲区
在嵌入式开发中,外设通信(如UART、SPI、I2C)的数据接收常面临两大挑战:不定时、不定量数据的实时处理和高频率数据流下的稳定性保障。传统的轮询方式效率低下,而中断驱动的接收逻辑又容易因处理延迟导致数据丢失。本文提出了一种基于STM32 HAL库的轻量级环形缓冲区解决方案!
已解决
非阻塞数据接收:避免因数据处理延迟导致外设中断阻塞
动态数据缓存:支持UART、SPI、I2C等多种外设的异步数据流
内存高效利用:通过环形缓冲区设计减少内存碎片
跨平台兼容:提供GCC与Keil双版本静态库,无缝适配不同开发环境
实现原理
[*]HAL库的RxXferCount机制
STM32 HAL库为每个外设句柄(如UART_HandleTypeDef)维护了RxXferCount成员。该计数器在每次接收一个字节后递增,当传输完成时触发回调并重置。项目通过监控RxXferCount的值变化,动态追踪接收数据的边界。
[*]环形缓冲区设计
写入策略:通过比较当前RxXferCount与上次记录值的差值,计算新数据长度
覆盖保护:当缓冲区满时自动覆盖旧数据(可配置为阻塞模式)
使用示例
#include "peripheral_buff.h"
PeripheralBufHandle PeripheralUart1Buf;
UART_HandleTypeDef uart1_handle;
char uart1_buffer;
int uart1_buffer_len;
int main()
{
HAL_Init();
SystemClock_Config(); // 此处未实现
USART1_Init(921600);// 此处未实现
// 缓冲区初始化
PeripheralUart1Buf = PeripheralBuffer_Init((const uint16_t *)&uart1_handle.RxXferCount, 1024);
if (!PeripheralUart1Buf)
{
printf("peripheral_buffer 初始化失败!(calloc();返回 NULL,检查 startup_stm32fxx_hd.s Heap_Size 值)\n");
printf("相关网址: https://blog.csdn.net/weixin_42518229/article/details/108574311 \n");
}
// 开启中断接收
HAL_UART_Receive_IT(&uart1_handle, (uint8_t *)PeripheralUart1Buf->Buf, PeripheralUart1Buf->Size);
while (1)
{
if (PeripheralBuffer_ReadInterval(PeripheralUart1Buf)) // 判断当前传输是否已停止,非必要
{
uart1_buffer_len = PeripheralBuffer_ReadAvailable(PeripheralUart1Buf); // 读取缓冲区内内容长度
if (uart1_buffer_len > 0)
{
if (uart1_buffer_len > sizeof(uart1_buffer))
uart1_buffer_len = sizeof(uart1_buffer);
PeripheralBuffer_ReadBytes(PeripheralUart1Buf, uart1_buffer, uart1_buffer_len); // 读取缓冲区内内容
uart1_buffer = 0;
printf("缓冲区数据 %s\n", uart1_buffer);
}
}
HAL_Delay(10);
}
return 0;
}注意
1.单次接收超长文件而又未及时处理,会导致数据覆盖。
2.用户缓冲区数据边界
仓库地址
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]