ESP32 FreeRtos 队列传输单种类数据1

简介
队列是一种数据结构,可以包含一组固定大小的数据。在创建队列的同时,队列的长度和所包含数据类型的大小就确认下来了。一个队列可以有多个写入数据的任务和多个读取数据的任务。当一个任务试图从队列读取数据的时候,它可以设置一个阻塞时间(block time)。这是当队列数据为空时,任务会进入阻塞状态的时间。当有数据在队列或者到达阻塞时间的时候,任务都会进入就绪状态。如果有多个任务同时在阻塞状态等待队列数据,优先级高的任务会在数据到达时进入就绪状态;在优先级相同的时候,等待时间长的任务会进入就绪状态。同理可以推及多个任务写入数据时候的运行状态。

 

API:

QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength,UBaseType_t uxItemSize );

BaseType_t xQueueSend(

QueueHandle_t xQueue,

const void * pvItemToQueue,

TickType_t xTicksToWait );

BaseType_t xQueueReceive(

QueueHandle_t xQueue,

void *pvBuffer,

TickType_t xTicksToWait

);

程序实现
首先,在setup()函数内,创建三个向队列传输数据的任务,创建一个从队列读取数据的任务。

void setup()
{
Serial.begin(115200);

xTaskCreate(userA, "User A", 1024 * 8, NULL, 1, NULL);
xTaskCreate(userB, "User B", 1024 * 8, NULL, 1, NULL);
xTaskCreate(userC, "User C", 1024 * 8, NULL, 1, NULL);

xTaskCreate(lcdTask, "lcd", 1024 * 8, NULL, 1, NULL);
}


void loop() {}

 将LCD初始化,创建消息队列

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

QueueHandle_t queueMsg = xQueueCreate(8, sizeof(char[20]));

 创建随机显示字母的函数

String randomMsg() {
String myStrings[] = {
"Nice to meet you",
"Where are U from?",
"What do you do?",
"What do U like?",
"What is UR num?",
"Do U have FB?",
"Thanks so much.",
"I am Chinese.",
"I do not KNOW.",
"Thank you.",
"That helps.",
"I Love U",
"Do U miss me?",
"Be careful.",
"Don't worry.",
"Good idea.",
"He's right.",
"I ate already.",
"More than that.",
"Nothing else.",
"See you later.",
"Take it outside.",
};
return myStrings[random(0, 22)];
}

定义三个向队列传送消息的函数

void userA(void *ptParam) {
char msg[20];
String userID = "A: ";

while (1) {
(userID + randomMsg()).toCharArray(msg, 20);

TickType_t timeOut = portMAX_DELAY;
//TickType_t timeOut = 10;
if (xQueueSend(queueMsg, &msg, timeOut) != pdPASS) {
Serial.print(userID);
Serial.println("Queue is full.");
};

vTaskDelay(2000);
}
}

void userB(void *ptParam) {
char msg[20];
String userID = "B: ";

while (1) {
(userID + randomMsg()).toCharArray(msg, 20);

//portMAX_DELAY - 无限Block
TickType_t timeOut = portMAX_DELAY;
//TickType_t timeOut = 10;
if (xQueueSend(queueMsg, &msg, timeOut) != pdPASS) {
Serial.print(userID);
Serial.println("Queue is full.");
};

vTaskDelay(2000);
}
}

void userC(void *ptParam) {
char msg[20];
String userID = "C: ";

while (1) {
(userID + randomMsg()).toCharArray(msg, 20);

//portMAX_DELAY - 无限Block
TickType_t timeOut = portMAX_DELAY;
//TickType_t timeOut = 10;
if (xQueueSend(queueMsg, &msg, timeOut) != pdPASS) {
Serial.print(userID);
Serial.println("Queue is full.");
};

vTaskDelay(2000);
}
}

定义LCD显示函数

void lcdTask(void *ptParam) { //LCD任务主体

lcd.init();
lcd.backlight();

char line0[20] = {' '};
char line1[20] = {' '};
char line2[20] = {' '};
char line3[20] = {' '};
char * lines[] = { line0, line1, line2, line3 };

while (1) {
//文字向上滚动
strcpy(line0, line1);
strcpy(line1, line2);
strcpy(line2, line3);

//TickType_t timeOut = portMAX_DELAY;
TickType_t timeOut = 10;
if (xQueueReceive(queueMsg, lines[3], timeOut) == pdPASS) {
//显示所有的4行文字
for (int i = 3; i >= 0; i--) {
lcd.setCursor(0, i);
lcd.print(" "); //clear this line
lcd.setCursor(0, i);
lcd.print(lines[i]);
}
} else {
Serial.println("Message Queue is Empty");
};



vTaskDelay(10);
}
}

posted @ 2024-05-10 10:52  苍月代表我  阅读(43)  评论(0)    收藏  举报