#include #include "STATUS_LED.h" static const char *TAG = "status_led"; // LED 引脚定义 #define STATUS_LED_1_PIN (GPIO_NUM_8) #define STATUS_LED_2_PIN (GPIO_NUM_18) // LED 控制结构体 typedef struct { gpio_num_t pin; led_state_t state; int blink_period_ms; bool current_level; // 实际输出电平 TaskHandle_t task_handle; bool task_running; } status_led_t; static status_led_t led1 = {.pin = STATUS_LED_1_PIN, .state = LED_OFF, .task_running = false}; static status_led_t led2 = {.pin = STATUS_LED_2_PIN, .state = LED_OFF, .task_running = false}; /** * @brief LED控制任务 * * @param param 指向LED结构体的指针 */ static void led_control_task(void *param) { status_led_t *led = (status_led_t *)param; while(led->task_running) { switch(led->state) { case LED_OFF: gpio_set_level(led->pin, 1); // 低电平点亮,所以高电平关闭 vTaskDelay(100 / portTICK_PERIOD_MS); // 延迟100ms后再次检查状态 break; case LED_ON: gpio_set_level(led->pin, 0); // 低电平点亮 vTaskDelay(100 / portTICK_PERIOD_MS); // 延迟100ms后再次检查状态 break; case LED_BLINK_SLOW: led->current_level = !led->current_level; gpio_set_level(led->pin, !led->current_level); // 反转输出以适应低电平点亮 vTaskDelay(500 / portTICK_PERIOD_MS); // 慢闪周期500ms break; case LED_BLINK_FAST: led->current_level = !led->current_level; gpio_set_level(led->pin, !led->current_level); // 反转输出以适应低电平点亮 vTaskDelay(100 / portTICK_PERIOD_MS); // 快闪周期100ms break; case LED_HEARTBEAT: // 心跳模式:快速亮两次,然后长灭 gpio_set_level(led->pin, 0); // 点亮 vTaskDelay(100 / portTICK_PERIOD_MS); gpio_set_level(led->pin, 1); // 熄灭 vTaskDelay(100 / portTICK_PERIOD_MS); gpio_set_level(led->pin, 0); // 点亮 vTaskDelay(100 / portTICK_PERIOD_MS); gpio_set_level(led->pin, 1); // 熄灭 vTaskDelay(800 / portTICK_PERIOD_MS); // 间隔800ms break; default: gpio_set_level(led->pin, 1); // 默认关闭 vTaskDelay(100 / portTICK_PERIOD_MS); break; } } // 任务结束前关闭LED(高电平关闭) gpio_set_level(led->pin, 1); vTaskDelete(NULL); } /** * @brief 初始化GPIO引脚为输出模式 * * @param led_pin LED使用的GPIO引脚 */ static void init_gpio_pin(gpio_num_t led_pin) { gpio_config_t io_conf = {}; io_conf.intr_type = GPIO_INTR_DISABLE; io_conf.mode = GPIO_MODE_OUTPUT; io_conf.pin_bit_mask = (1ULL << led_pin); io_conf.pull_down_en = 0; io_conf.pull_up_en = 0; gpio_config(&io_conf); // 初始状态设为高电平(LED熄灭,适用于低电平点亮的LED) gpio_set_level(led_pin, 1); } /** * @brief 初始化状态LED * * 配置两个LED引脚为输出模式并设置初始状态 */ void status_led_init(void) { init_gpio_pin(STATUS_LED_1_PIN); init_gpio_pin(STATUS_LED_2_PIN); // 启动LED控制任务 led1.task_running = true; xTaskCreate(led_control_task, "led1_control", 2048, &led1, 5, &led1.task_handle); led2.task_running = true; xTaskCreate(led_control_task, "led2_control", 2048, &led2, 5, &led2.task_handle); ESP_LOGI(TAG, "Status LEDs initialized on pins GPIO%d and GPIO%d", STATUS_LED_1_PIN, STATUS_LED_2_PIN); } /** * @brief 控制指定LED的状态 * * @param led_num LED编号 (1 或 2) * @param state LED状态 (0=关闭, 1=开启) */ void status_led_set(uint8_t led_num, uint8_t state) { status_led_t *led = NULL; if (led_num == 1) { led = &led1; } else if (led_num == 2) { led = &led2; } else { ESP_LOGE(TAG, "Invalid LED number: %d", led_num); return; } if (state == 1) { led->state = LED_ON; } else { led->state = LED_OFF; } ESP_LOGD(TAG, "LED %d set to %s", led_num, state ? "ON" : "OFF"); } /** * @brief 切换指定LED的状态 * * @param led_num LED编号 (1 或 2) */ void status_led_toggle(uint8_t led_num) { status_led_t *led = NULL; if (led_num == 1) { led = &led1; } else if (led_num == 2) { led = &led2; } else { ESP_LOGE(TAG, "Invalid LED number: %d", led_num); return; } if (led->state == LED_ON) { led->state = LED_OFF; } else if (led->state == LED_OFF) { led->state = LED_ON; } ESP_LOGD(TAG, "LED %d toggled", led_num); } /** * @brief 设置LED为闪烁模式 * * @param led_num LED编号 (1 或 2) * @param mode 闪烁模式 (0=慢闪, 1=快闪, 2=心跳) */ void status_led_blink_mode(uint8_t led_num, uint8_t mode) { status_led_t *led = NULL; if (led_num == 1) { led = &led1; } else if (led_num == 2) { led = &led2; } else { ESP_LOGE(TAG, "Invalid LED number: %d", led_num); return; } switch(mode) { case 0: // 慢闪 led->state = LED_BLINK_SLOW; break; case 1: // 快闪 led->state = LED_BLINK_FAST; break; case 2: // 心跳 led->state = LED_HEARTBEAT; break; default: ESP_LOGE(TAG, "Invalid blink mode: %d", mode); return; } ESP_LOGD(TAG, "LED %d set to blink mode %d", led_num, mode); } /** * @brief 销毁LED控制任务 * * @param led_num LED编号 (1 或 2) */ void status_led_deinit(uint8_t led_num) { status_led_t *led = NULL; if (led_num == 1) { led = &led1; } else if (led_num == 2) { led = &led2; } else { ESP_LOGE(TAG, "Invalid LED number: %d", led_num); return; } if (led->task_running) { led->task_running = false; if (led->task_handle) { vTaskDelete(led->task_handle); led->task_handle = NULL; } gpio_set_level(led->pin, 1); // 关闭LED(高电平关闭) } } /** * @brief 获取LED当前状态 * * @param led_num LED编号 (1 或 2) * @return 当前LED状态 */ led_state_t status_led_get_state(uint8_t led_num) { if (led_num == 1) { return led1.state; } else if (led_num == 2) { return led2.state; } else { ESP_LOGE(TAG, "Invalid LED number: %d", led_num); return LED_OFF; } }