/** * @file led_driver.c * @brief LED 驱动实现 — OOPC 不透明指针模式 * * 内部结构体定义在本文件,外部不可见 * 静态内存池分配,无 malloc */ #include "led_driver.h" #include /* ======== 内部结构体(不透明指针的真身) ======== */ struct LedDriver_S { GPIO_Port_TypeDef port; GPIO_Pin_TypeDef pin; uint8_t active_low; /* 1=低电平点亮 */ volatile LedState_E state; volatile uint8_t brightness; /* 0-100 */ /* 闪烁参数 */ uint16_t blink_period_ms; uint32_t blink_last_toggle; uint8_t blink_on; /* 呼吸灯参数 */ uint16_t breath_step; /* 0-200 三角波步数 */ uint8_t breath_dir; /* 0=渐亮, 1=渐暗 */ uint32_t breath_last_tick; }; /* ======== 静态内存池 ======== */ static LedDriver_S g_led_pool[LED_MAX_INSTANCES]; static uint8_t g_led_used[LED_MAX_INSTANCES]; /* ======== 内部辅助函数 ======== */ static void led_hw_on(LedDriver_S* me) { GPIO_PinState_TypeDef s = me->active_low ? GPIO_PIN_RESET : GPIO_PIN_SET; HAL_GPIO_WritePin(me->port, me->pin, s); } static void led_hw_off(LedDriver_S* me) { GPIO_PinState_TypeDef s = me->active_low ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(me->port, me->pin, s); } static void led_hw_set_pwm(LedDriver_S* me, uint8_t percent) { /* * 真实硬件: 设置 TIM 占空比 * TIM_SetCompare(me->h_tim, me->channel, percent * ARR / 100); * * PC 模拟: 简化为 ON/OFF 模拟亮度 */ me->brightness = percent; if (percent >= 50) { led_hw_on(me); } else { led_hw_off(me); } } /* ======== 公开 API 实现 ======== */ LedDriver_S* Led_Create(GPIO_Port_TypeDef port, GPIO_Pin_TypeDef pin, uint8_t active_low) { for (uint8_t i = 0; i < LED_MAX_INSTANCES; i++) { if (g_led_used[i] == 0) { g_led_used[i] = 1; LedDriver_S* me = &g_led_pool[i]; memset(me, 0, sizeof(LedDriver_S)); me->port = port; me->pin = pin; me->active_low = active_low; me->state = LED_STATE_OFF; /* 硬件初始化 */ HAL_GPIO_Init(port, pin, GPIO_MODE_OUTPUT); led_hw_off(me); return me; } } return NULL; /* 内存池满 */ } void Led_Destroy(LedDriver_S* me) { if (me == NULL) return; led_hw_off(me); for (uint8_t i = 0; i < LED_MAX_INSTANCES; i++) { if (&g_led_pool[i] == me) { g_led_used[i] = 0; break; } } } void Led_On(LedDriver_S* me) { if (me == NULL) return; me->state = LED_STATE_ON; me->brightness = 100; led_hw_on(me); } void Led_Off(LedDriver_S* me) { if (me == NULL) return; me->state = LED_STATE_OFF; me->brightness = 0; led_hw_off(me); } void Led_SetBlink(LedDriver_S* me, uint16_t period_ms) { if (me == NULL) return; me->state = LED_STATE_BLINK; me->blink_period_ms = period_ms; me->blink_last_toggle = 0; /* 将在 Poll 中重置 */ me->blink_on = 1; } void Led_SetBreathing(LedDriver_S* me) { if (me == NULL) return; me->state = LED_STATE_BREATHING; me->breath_step = 0; me->breath_dir = 0; /* 从暗开始渐亮 */ me->breath_last_tick = 0; } void Led_Poll(LedDriver_S* me, uint32_t now_ms) { if (me == NULL) return; switch (me->state) { case LED_STATE_OFF: case LED_STATE_ON: /* 静态状态,无需处理 */ break; case LED_STATE_BLINK: { uint16_t half = me->blink_period_ms / 2; if (half == 0) half = 1; if (me->blink_last_toggle == 0) { me->blink_last_toggle = now_ms; } if ((now_ms - me->blink_last_toggle) >= half) { me->blink_last_toggle = now_ms; me->blink_on = !me->blink_on; if (me->blink_on) { led_hw_on(me); me->brightness = 100; } else { led_hw_off(me); me->brightness = 0; } } break; } case LED_STATE_BREATHING: { /* * 呼吸灯: 三角波 0→100→0 * 每 15ms 变化 1 步, 200 步一个完整周期 ≈ 3 秒 */ if (me->breath_last_tick == 0) { me->breath_last_tick = now_ms; } if ((now_ms - me->breath_last_tick) >= 15) { me->breath_last_tick = now_ms; if (me->breath_dir == 0) { /* 渐亮 */ me->breath_step++; if (me->breath_step >= 100) { me->breath_dir = 1; } } else { /* 渐暗 */ if (me->breath_step == 0) { me->breath_dir = 0; } else { me->breath_step--; } } led_hw_set_pwm(me, (uint8_t)me->breath_step); } break; } } } LedState_E Led_GetState(const LedDriver_S* me) { if (me == NULL) return LED_STATE_OFF; return me->state; } uint8_t Led_GetBrightness(const LedDriver_S* me) { if (me == NULL) return 0; return me->brightness; }