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);
  }
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号