在 STM32 中使用环形队列的方式接收串口数据
#include <stdio.h>
#include <stm32f10x.h>
#include <stm32f10x_usart.h>
// 定义环形队列的结构体
typedef struct
{
uint8_t *buffer; // 数据缓冲区
uint16_t size; // 缓冲区大小
uint16_t front; // 队列头索引
uint16_t rear; // 队列尾索引
} RingQueue;
// 初始化环形队列
void RingQueue_Init(RingQueue *q, uint8_t *buffer, uint16_t size)
{
q->buffer = buffer;
q->size = size;
q->front = q->rear = 0;
}
// 判断环形队列是否为空
bool RingQueue_IsEmpty(RingQueue *q)
{
return q->front == q->rear;
}
// 判断环形队列是否已满
bool RingQueue_IsFull(RingQueue *q)
{
return ((q->rear + 1) % q->size == q->front);
}
// 向环形队列中添加数据
void RingQueue_EnQueue(RingQueue *q, uint8_t data)
{
if (RingQueue_IsFull(q))
{
// 队列已满,进行错误处理
printf("RingQueue is full, cannot enqueue data.\n");
return;
}
q->buffer[q->rear] = data;
q->rear = (q->rear + 1) % q->size;
}
// 从环形队列中取出数据
uint8_t RingQueue_DeQueue(RingQueue *q)
{
if (RingQueue_IsEmpty(q))
{
// 队列为空,进行错误处理
printf("RingQueue is empty, cannot dequeue data.\n");
return 0;
}
uint8_t data = q->buffer[q->front];
q->front = (q->front + 1) % q->size;
return data;
}
// 串口接收中断处理函数
void USART1_IRQHandler(void)
{
if (USART1->SR & USART_SR_RXNE)
{
RingQueue *q = &串口接收队列;
// 接收数据
uint8_t data = USART1->DR;
// 将数据添加到环形队列
RingQueue_EnQueue(q, data);
}
}
int main()
{
// 初始化串口
USART1_Init(115200, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No, USART_Mode_Rx | USART_Mode_Tx);
// 初始化环形队列
RingQueue queue;
RingQueue_Init(&queue, buffer, BUFFER_SIZE);
// 使能串口接收中断
USART1->CR1 |= USART_CR1_RXNEIE;
// 进入主循环,等待数据接收
while (1)
{
if (!RingQueue_IsEmpty(&queue))
{
// 从环形队列中取出数据
uint8_t data = RingQueue_DeQueue(&queue);
// 处理接收到的数据
printf("Received data: %c\n", data);
}
}
return 0;
}