ESP32 FreeRtos 队列传输单种类数据

简介

队列是一种数据结构,可以包含一组固定大小的数据。在创建队列的同时,队列的长度和所包含数据类型的大小就确认下来了。一个队列可以有多个写入数据的任务和多个读取数据的任务。当一个任务试图从队列读取数据的时候,它可以设置一个阻塞时间(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);
  }
}

运行环境

使用队列传刷单种类数据

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值