#define KEY_PIN 20
#define LED_PIN 14
SemaphoreHandle_t led = NULL; // 二进制信号量
volatile TickType_t keyDeounce = 0;   // 按下按钮的时间

void led_task(void *param_t){
  pinMode(LED_PIN, OUTPUT);
  while(1){
    // 这种去抖方式是很Low的,正确的方式要使用定时器。
    if((xSemaphoreTake(led, 1000) == pdTRUE) && ((xTaskGetTickCount() - keyDeounce) < 200)){
      digitalWrite(LED_PIN,!digitalRead(LED_PIN));
      vTaskDelay(500);
    }
  }
}

// 中断服务函数
void IRAM_ATTR ISR() {
  keyDeounce = xTaskGetTickCountFromISR();    // 记录下按下的时间,用于放抖动,正式开发中不要这样写,有Bug
  xSemaphoreGiveFromISR(led, NULL);
}

void setup() {
  Serial.begin(115200);
  led = xSemaphoreCreateBinary(); //创建二进制信号量
  xTaskCreate(led_task, "LED-DSP", 1024, NULL, 1, NULL);
  // 安装中断
  pinMode(KEY_PIN, INPUT_PULLUP);
  attachInterrupt(KEY_PIN, ISR, FALLING);
}

void loop() {
  delay(10);
}