#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include "esp_log.h"
#define CONFIG_LOG_MAXIMUM_LEVEL 5
#define LED_PIN GPIO_NUM_13
#define BUTTON_PIN GPIO_NUM_35
#define DEBOUNCE_TIME 30
static const char *TAG = "BUTTON_APP";
static SemaphoreHandle_t btn_sem;
static void button_task(void *pv) {
bool last = 1; // 上拉電阻的預設狀態為1
while (1) {
bool curr = gpio_get_level(BUTTON_PIN);
if (last == 1 && curr == 0) {
vTaskDelay(pdMS_TO_TICKS(DEBOUNCE_TIME));
if (gpio_get_level(BUTTON_PIN) == 0) {
xSemaphoreGive(btn_sem); // 發送「按鈕事件」
// 等待放開按鍵
while (gpio_get_level(BUTTON_PIN) == 0) {
vTaskDelay(pdMS_TO_TICKS(10));
}
}
}
last = curr;
vTaskDelay(pdMS_TO_TICKS(10));
}
}
static void led_task(void *pv) {
bool led_state = false;
while (1) {
// 等待「按鍵事件」
if (xSemaphoreTake(btn_sem, portMAX_DELAY)) {
led_state = !led_state;
gpio_set_level(LED_PIN, led_state);
ESP_LOGI(TAG, "LED:%s", led_state ? "開" : "關");
}
}
}
void app_main(void) {
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
btn_sem = xSemaphoreCreateBinary(); // 建立二元信號量
// LED 初始化
gpio_config_t led_conf = {
.pin_bit_mask = 1ULL << LED_PIN,
.mode = GPIO_MODE_OUTPUT, // 輸出模式
};
gpio_config(&led_conf);
// Button 初始化
gpio_config_t btn_conf = {
.pin_bit_mask = 1ULL << BUTTON_PIN,
.mode = GPIO_MODE_INPUT, // 輸入模式
.pull_up_en = GPIO_PULLUP_ENABLE, // 啟用上拉電阻
};
gpio_config(&btn_conf);
xTaskCreate(button_task, "button_task", 2048, NULL, 5, NULL);
xTaskCreate(led_task, "led_task", 2048, NULL, 4, NULL);
}