STM32环形串口队列程序 大数据串口收发 实时不丢包 串口程序平常产品开发中编写或移植的程序并亲自测试通过,均为工程文件格式,可直接编译使用。 该程序为大数据量吞吐的串口收发例程,中断接收,边收边发,采用大数据环形队列,处理过程超快不丢包,接收buffer可以定义成2K,4K,8K均可。 也可以用到其余单片机上

在平常的产品开发中,串口通信是极为常见的需求。特别是当涉及大数据量吞吐时,保证实时性且不丢包就成了关键挑战。今天就来分享一款我亲自编写并测试通过的 STM32 环形串口队列程序,以工程文件格式呈现,能直接编译使用,并且还能轻松移植到其他单片机上哦。

中断接收:高效的开始

首先,采用中断接收的方式是这个程序高效运行的基础。在 STM32 中,我们可以通过配置 NVIC(Nested Vectored Interrupt Controller)来使能串口中断。下面是一段简单的使能串口 1 中断的代码示例:

// 使能串口1中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

这里我们设置了中断通道为 USART1 的中断,并且给了它较高的抢占优先级和子优先级,确保串口中断能及时响应。

大数据环形队列:核心奥秘

环形队列是这个程序的核心所在,它就像一个智能的存储环,能高效地处理大数据。我们可以根据需求将接收 buffer 定义成 2K、4K 或者 8K。下面看看环形队列的数据结构定义:

#define RX_BUFFER_SIZE 2048 // 这里以2K为例
typedef struct {
    uint8_t buffer[RX_BUFFER_SIZE];
    volatile uint16_t head;
    volatile uint16_t tail;
} RingBuffer;
RingBuffer rxRingBuffer;

在这个结构里,buffer 就是我们的环形存储区域,head 表示新数据写入的位置,tail 表示数据读出的位置。

STM32环形串口队列程序 大数据串口收发 实时不丢包 串口程序平常产品开发中编写或移植的程序并亲自测试通过,均为工程文件格式,可直接编译使用。 该程序为大数据量吞吐的串口收发例程,中断接收,边收边发,采用大数据环形队列,处理过程超快不丢包,接收buffer可以定义成2K,4K,8K均可。 也可以用到其余单片机上

当有数据通过串口中断接收进来时,我们这样处理:

void USART1_IRQHandler(void) {
    if (USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET) {
        uint8_t data = USART_ReceiveData(USART1);
        uint16_t nextHead = (rxRingBuffer.head + 1) % RX_BUFFER_SIZE;
        if (nextHead!= rxRingBuffer.tail) {
            rxRingBuffer.buffer[rxRingBuffer.head] = data;
            rxRingBuffer.head = nextHead;
        }
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

代码中,先读取串口接收到的数据 data,然后计算下一个 head 位置 nextHead。如果下一个 head 位置不等于 tail,说明队列还有空间,就把数据存入 buffer 并更新 head。这样即使数据连续快速到来,也能有条不紊地存储。

边收边发:流畅的流转

边收边发功能让串口数据能快速处理并转发出去。在主循环中,我们可以这样实现:

int main(void) {
    // 初始化代码...

    while (1) {
        if (rxRingBuffer.head!= rxRingBuffer.tail) {
            uint8_t data = rxRingBuffer.buffer[rxRingBuffer.tail];
            rxRingBuffer.tail = (rxRingBuffer.tail + 1) % RX_BUFFER_SIZE;
            USART_SendData(USART1, data);
            while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        }
    }
}

这里,只要环形队列中有数据(head 不等于 tail),就取出数据 data 并通过串口发送出去,同时更新 tail。等待发送完成标志 TXE 置位,确保数据发送成功。

这个 STM32 环形串口队列程序,凭借中断接收、大数据环形队列以及边收边发的特性,在大数据串口收发场景下表现出色,真正做到实时不丢包。而且它易于移植到其他单片机上,希望能在大家的项目开发中发挥作用!

更多推荐