这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » NUCLEO-U083RC学习历程38+串口通过队列的方式输出两个字符串

共1条 1/1 1 跳转至

NUCLEO-U083RC学习历程38+串口通过队列的方式输出两个字符串

高工
2025-08-15 21:23:36     打赏

    队列是一种先进先出(FIFO)的线性数据结构,只允许在队尾插入元素,在队头删除元素。对于队列的操作包括:入队,出队,查看队头元素,判断队列是否为空的操作。

    基本特性:先进先出的原则,最先进入队列的元素,最先被移除队列。

    主要操作:

    入队(enqueue):在队列的尾端添加元素。

 出队(dequeue):在队列的首端移除元素。

 队列的实现方式如下所示:

1:数组实现:

使用固定大小的数组

需要处理循环队列的情况以避免空间浪费

2:链表实现:

使用单向链表,头指针指向队首,尾指针指向队尾

不需要预先分配固定大小

二:代码实现部分:

2.1  队列结构体定义

typedef struct TQelemType						//队列每帧数据结构体
{
	uint8_t uLength;									//数据长度
	uint8_t buffer[32];								//数据数组
}QelemType;

typedef struct Tsquene							//队列结构体
{
	QelemType *base;
	int front;
	int rear;
}squene;

2.2  队列初始化

/**************************************************************************
 - 功能描述:队列初始化
 - 参数说明:*s 队列句柄		*buf 队列结构体数据地址
 - 返回说明:-1 失败		0 成功
 **************************************************************************/
int8_t Initquene(squene *s, QelemType *buf)
{
	s->base=buf;
	if(!s->base)
		return -1;
	s->front=0;
	s->rear=0;
	return 0;
}

2.2 入队列函数如下:

/**************************************************************************
 - 功能描述:入队列
 - 参数说明:*s 队列句柄		*e 要入队列数据的地址
 - 返回说明:无
 **************************************************************************/
void enquene(squene *s,QelemType *e)
{
	if(((s->rear)+1)%MAXSIZE==s->front)
	{
		return ;
	}
	memcpy(&(s->base[s->rear]), e, sizeof(QelemType));
	s->rear=((s->rear)+1)%MAXSIZE;
}

2.3 出队列函数如下所示:

/**************************************************************************
 - 功能描述:出队列
 - 参数说明:*s 队列句柄		*e 出队列数据要写入的地址
 - 返回说明:-1 失败		0 成功
 **************************************************************************/
int8_t dequene(squene *s,QelemType *e)
{
	if(s->rear==s->front)
	{
		return -1;
	}
	
	memcpy(e, &(s->base[s->front]), sizeof(QelemType));
	
	memset(&(s->base[s->front]), 0, sizeof(QelemType));
	
	
	s->front=((s->front)+1) % MAXSIZE;
	return 0;
}

2.4初始化所使用的队列:

/**************************************************************************
 - 功能描述:初始化所有应用的队列
 - 参数说明:void
 - 返回说明:void
 **************************************************************************/
void Queue_Init(void)
{
	Initquene(&QUsart1Tx, QUsart1TxData);
}

2.5  这里定义两个发送函数,主要是为了验证队列的输出函数:

void SendMPT01Order(uint8_t order)
{

	 QelemType Data = {0};
	 Data.uLength =  6 ;   //需要发送的数据长度
	 
	 Data.buffer[0] = 0xFE;
   Data.buffer[1] = 0x04;
   Data.buffer[2] = 0xA1;
   Data.buffer[3] = order;
   Data.buffer[4] = 0x00;
//   Data.buffer[5] = CalcSum2(5,&Data.buffer[0]);	//SUM   
//   SendDataToUART4(6);  //发送数据 
	 
	 	enquene(&QUsart1Tx,&Data);
}


void SendMPT01Ctrl(uint8_t TempCtrl,uint8_t AutoCtrl)
{

	 	 QelemType Data = {0};
	 Data.uLength =  6 ;   //需要发送的数据长度
 
	 Data.buffer[0] = 0xFE;
   Data.buffer[1] = 0x04;
   Data.buffer[2] = 0xA2;
   Data.buffer[3] = 0x03;
   Data.buffer[4] = 0x00;
 	 
 	 enquene(&QUsart1Tx,&Data);
}

2.6  重新定义一下串口的发送函数:

void Usart1Txbuffer(void)
{

	QelemType Data = {0},*PreData = NULL;		//创建临时一帧队列数据
	PreData = &Data;

	if(dequene(&QUsart1Tx,PreData) != 0)		//出队列
	return;	
	
	memcpy(SendBuffer1,PreData->buffer,Data.uLength );
	
	 HAL_UART_Transmit(&huart1,SendBuffer1,Data.uLength,100); 
}

主要实现:当队列种的数据不为空时,将队列的数据拷贝到串口的发送函数里面。

2.7  验证函数:

if(Time6point %100 == 0)
{
Usart1Txbuffer();
}

if(Time6point %200 == 0)
{

SendMPT01Order(01);
}

if(Time6point %500 == 0)
{

}

if(Time6point  %1000 == 0)
{
SendMPT01Ctrl (01,02);
 Time6point  = 0 ;
// HAL_UART_Transmit(&huart1,OUTPUT_str,sizeof(OUTPUT_str),100);
 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
}

三:实物图片如下所示:

0815-1.png

可见函数验证功能正常,使用队列的方式发送数据,可以保证数据正常发送,不会被其他发送函数打断。





关键词: NUCLEO-U083RC     队列    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]