Files
DistributedCollectorGateway/components/STATUS_LED/STATUS_LED.c

258 lines
6.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#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;
}
}