目录
- 前言
- 一、构建环形队列结构体
- 二、队列初始化
- 三、读写数据
- 1、队列满判断
- 2、队列空判断
- 3、队列写入数据
- 4、队列读取数据
- 四、实际使用
前言
环形队列的理论知识网上有很多文章,这里我就仅通过代码分享一下使用经验,在我的驱动中,队列内容是一包一包的待处理数据包,而不是一个个的字节。
一、构建环形队列结构体
队列中头部位置和尾部位置的指示是必须的,另外为了使用方便,加入数据包计数cnt,写入一包数据时cnt++,读取一包数据时cnt–,需要判断队列空或满时,就看cnt是否为0或最大值。
*注意:因为在驱动中,队列中放置的是一包一包的待处理数据包,所以又加入了每个数据包的有效长度lenth,读取到数据包后,还返回此包的数据长度。
首先需要定义队列大小:队列中最多存放多少数据包、单包的最大长度
#define Queue_Packet_MaxNumber 64
#define Queue_Packet_MaxLenth 256
typedef struct{
int front;
int rear;
int counter;
uint8_t data[Queue_Packet_MaxNumber][Queue_Packet_MaxLenth];
uint16_t lenth[Queue_Packet_MaxNumber];
}xQueue_Typedef;
二、队列初始化
1.定义一个队列
xQueue_Typedef Usart_Receive_Queue;
void xQueue_Init(xQueue_Typedef *Queue)
{
Queue->front=0;
Queue->rear=0;
Queue->counter=0;
memset(&Queue->data[0][0],0,Queue_Packet_MaxLenth*Queue_Packet_MaxNumber);
}
2.队列初始化,调用上面的函数即可,会把传入的队列清空
xQueue_Init(&Usart_Receive_Queue);
三、读写数据
1、队列满判断
读取队列内容前,要先判断队列是否为空,如果为空,读取失败。
队列写入数据前,要先判断队列是否已满,如果已满,写入失败。
uint8_t xQueue_FullJudge(xQueue_Typedef *Queue)
{
if(Queue->counter==Queue_Packet_MaxNumber)
{
return 1;
}else
{
return 0;
}
}
2、队列空判断
uint8_t xQueue_EmptyJudge(xQueue_Typedef *Queue)
{
if(Queue->counter==0)
{
return 1;
}else
{
return 0;
}
}
3、队列写入数据
uint8_t xQueue_WriteData(xQueue_Typedef *Queue,uint8_t *Data,uint16_t Lenth)
{
if(xQueue_FullJudge(Queue))
{
return 0;
}else
{
Queue->counter++;
memcpy(&Queue->data[Queue->rear][0],&Data[0],Lenth);
Queue->lenth[Queue->rear]=Lenth;
Queue->rear=(Queue->rear+1)%Queue_Packet_MaxNumber;
return 1;
}
}
4、队列读取数据
uint16_t xQueue_ReadData(xQueue_Typedef *Queue,uint8_t *Data)
{
uint16_t Lenth;
if(xQueue_EmptyJudge(Queue))
{
return 0;
}else
{
Queue->counter--;
Lenth=Queue->lenth[Queue->front];
memcpy(&Data[0],&Queue->data[Queue->front][0],Lenth);
Queue->front=(Queue->front+1)%Queue_Packet_MaxNumber;
return Lenth;
}
}
四、实际使用
后续有时间了更新一篇STM32串口使用总结:CubeMX配置、接收中断逐字节处理、空闲中断整包处理、空闲中断+DMA接收、串口阻塞发送与DMA发送等等
xQueue_Typedef Usart_Receive_Queue;
int main()
{
xQueue_Init(&Usart_Receive_Queue);
return 0;
}
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&UART1_Handler);
if(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
HAL_UART_DMAStop(&UART1_Handler);
Receive_Frame_Len_Usart=RECEIVE_MAX_LENTH-__HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
xQueue_WriteData(&Usart_Receive_Queue,Receive_Buff_Usart,Receive_Frame_Len_Usart);
HAL_UART_Receive_DMA(&UART1_Handler,Receive_Buff_Usart,RECEIVE_MAX_LENTH);
}
}
int UnpackModule_Periodic_Handle()
{
uint8_t Data[Queue_Packet_MaxLenth];
uint16_t Lenth;
Lenth=xQueue_ReadData(&Usart_Receive_Queue,Data);
if(Lenth)
{
if(Data[0] != 0x55 || Data[Lenth-] != 0xAA)
{
return 0;
}
switch(Data[2])
{
default:break;
}
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)