#define START_FLAG      (1 << 0)
#define BREAD_FLAG      (1 << 1)
#define MEAT_FLAG       (1 << 2)
#define VEGETABLE_FLAG  (1 << 3)

EventGroupHandle_t xEventHamburg = NULL;  // 做汉堡的事件组
// 面包服务员
void waiter_bread_task(void *param_t){
  EventBits_t uxBits;
  uxBits = xEventGroupWaitBits(xEventHamburg, // 事件组句柄
                              START_FLAG,     // 等待开始事件
                              pdTRUE,         // 读取后清空标志位
                              pdTRUE,         // ADN关系,1个值无所谓
                              portMAX_DELAY);
  printf("[BRED] 等到开始事件 : %X\n", uxBits);
  vTaskDelay(pdMS_TO_TICKS(random(500,2000)));
  uxBits = xEventGroupSetBits(xEventHamburg, BREAD_FLAG); // 设置面包标志位
  printf("[BRED] 面包已就绪 : %X\n", uxBits);
  vTaskDelete(NULL);
}

// 肉饼服务员
void waiter_meat_task(void *param_t){
  EventBits_t uxBits;
  uxBits = xEventGroupWaitBits(xEventHamburg, // 事件组句柄
                              BREAD_FLAG,     // 等待面包事件
                              pdFALSE,        // 读取后不清空
                              pdTRUE,         // ADN关系,1个值无所谓
                              portMAX_DELAY);
  printf("[MEAT] 等到面包做好 : %X\n", uxBits);
  vTaskDelay(pdMS_TO_TICKS(random(500,2000)));
  uxBits = xEventGroupSetBits(xEventHamburg, MEAT_FLAG); // 设置肉饼标志位
  printf("[MEAT] 肉饼已就绪 : %X\n", uxBits);
  vTaskDelete(NULL);
}

// 蔬菜服务员
void waiter_vegetable_task(void *param_t){
  EventBits_t uxBits;
  uxBits = xEventGroupWaitBits(xEventHamburg, // 事件组句柄
                              MEAT_FLAG,      // 等待开始事件
                              pdFALSE,        // 读取后不清空
                              pdTRUE,         // ADN关系,1个值无所谓
                              portMAX_DELAY);
  printf("[VEGE] 等到肉饼做好 : %X\n", uxBits);
  vTaskDelay(pdMS_TO_TICKS(random(500,2000)));
  uxBits = xEventGroupSetBits(xEventHamburg, VEGETABLE_FLAG); // 设置蔬菜标志位
  printf("[VEGE] 蔬菜已就绪 : %X\n", uxBits);
  vTaskDelete(NULL);
}

// 厨师线程
void chef_task(void *param_t){
  pinMode(4, INPUT_PULLUP);
  while(1){
    if(digitalRead(4) == LOW){
      // 开始做汉堡
      EventBits_t uxBits;  // 设置事件标志位的返回值
      uxBits = xEventGroupSetBits(xEventHamburg, START_FLAG);  // 这个返回值有可能会清空标志位,具体读文档
      printf("[CHEF] 开始做汉堡 : %X\n", uxBits);
      uxBits = xEventGroupWaitBits(xEventHamburg,                            // 事件句柄
                                  BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG,    // 等待代表面包、肉饼、蔬菜的标志位
                                  pdFALSE,                                    // 是否清空对应标志位
                                  pdTRUE,                                     // 等待的Bits判断关系 True为 AND, False为 OR
                                  portMAX_DELAY);                             // 等待超时时间
      printf("[CHEF] 汉堡做完了 : %X\n", uxBits);
      // 重置事件组
      xEventGroupClearBits(xEventHamburg, START_FLAG | BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG);
      uxBits = xEventGroupGetBits(xEventHamburg);
      printf("[CHEF] 汉堡做好了,我下班了 : %X\n", uxBits);
      vTaskDelete(NULL);
    }
    vTaskDelay(100);
  }
}

void setup() {
  Serial.begin(115200);
  xEventHamburg = xEventGroupCreate();  //初始化事件组

  // 启动各个线程
  xTaskCreate(chef_task, "Chef", 1024*2, NULL, 1, NULL);
  xTaskCreate(waiter_bread_task, "Bread", 1024*2, NULL, 1, NULL);
  xTaskCreate(waiter_meat_task, "Meat", 1024*2, NULL, 1, NULL);
  xTaskCreate(waiter_vegetable_task, "Vegetable", 1024*2, NULL, 1, NULL);
}

void loop() {
  delay(100);
}
Loading
esp32-s3-devkitc-1
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r