/** * led.c — OOPC 不透明指针模式实现 * * 结构体 Led_S 的定义仅在此文件中可见。 * led.h 中只有前向声明——外部无法访问任何字段。 */ #include #include "led.h" /* ======================================================== * 第一步:完整结构体定义(在 .c 中,对外不可见) * ======================================================== */ #define MAX_LEDS 8 struct Led_S { GPIO_TypeDef* port; /* GPIO 端口基地址 */ uint16_t pin; /* GPIO 引脚号 */ volatile uint8_t state; /* 当前状态(ISR 可改写) */ uint8_t brightness; /* PWM 亮度,0-100 */ uint8_t initialized; /* 初始化标志 */ }; /* ======================================================== * 第二步:静态内存池(无 malloc) * ======================================================== */ static Led_S g_pool[MAX_LEDS]; static uint8_t g_used[MAX_LEDS]; /* ======================================================== * 第三步:内部辅助函数(static,对外不可见) * ======================================================== */ /* 计算 RCC 使能 GPIO 时钟用的位 */ static uint32_t _rcc_bit(GPIO_TypeDef* port) { if (port == GPIOA) return RCC_APB2Periph_GPIOA; else if (port == GPIOB) return RCC_APB2Periph_GPIOB; else if (port == GPIOC) return RCC_APB2Periph_GPIOC; else if (port == GPIOD) return RCC_APB2Periph_GPIOD; else if (port == GPIOE) return RCC_APB2Periph_GPIOE; return 0; } /* ======================================================== * 第四步:公开 API 实现 * ======================================================== */ Led_S* Led_Create(GPIO_TypeDef* port, uint16_t pin) { /* 参数检查 */ if (port == NULL) return NULL; if (pin > 15) return NULL; /* 遍历静态内存池,找空闲槽位 */ for (uint8_t i = 0; i < MAX_LEDS; i++) { if (g_used[i] == 0) { g_used[i] = 1; Led_S* inst = &g_pool[i]; /* 初始化实例字段 */ inst->port = port; inst->pin = (uint16_t)(1u << pin); /* 转为位掩码 */ inst->state = 0; inst->brightness = 100; inst->initialized = 0; /* ── 硬件初始化 ── */ /* 1. 使能 GPIO 时钟 */ uint32_t rcc_bit = _rcc_bit(port); if (rcc_bit != 0) { RCC_APB2PeriphClockCmd(rcc_bit, ENABLE); } /* 2. 配置 GPIO 为推挽输出 */ GPIO_InitTypeDef gpio_init; gpio_init.GPIO_Pin = inst->pin; gpio_init.GPIO_Mode = GPIO_Mode_Out_PP; gpio_init.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(port, &gpio_init); /* 3. 初始状态 = 灭 */ GPIO_ResetBits(port, inst->pin); inst->initialized = 1; return inst; } } /* 所有槽位已用完 */ return NULL; } void Led_On(Led_S* me) { if (me == NULL || !me->initialized) return; GPIO_SetBits(me->port, me->pin); me->state = 1; } void Led_Off(Led_S* me) { if (me == NULL || !me->initialized) return; GPIO_ResetBits(me->port, me->pin); me->state = 0; } void Led_Toggle(Led_S* me) { if (me == NULL || !me->initialized) return; if (me->state) { GPIO_ResetBits(me->port, me->pin); me->state = 0; } else { GPIO_SetBits(me->port, me->pin); me->state = 1; } } uint8_t Led_GetState(const Led_S* me) { if (me == NULL) return 0; return me->state; } void Led_SetBrightness(Led_S* me, uint8_t pct) { if (me == NULL) return; if (pct > 100) pct = 100; me->brightness = pct; /* PWM 实现需依赖 TIM 外设,本 Demo 仅保留接口占位 */ } void Led_Destroy(Led_S* me) { if (me == NULL) return; for (uint8_t i = 0; i < MAX_LEDS; i++) { if (&g_pool[i] == me) { /* 关闭 LED 并归还槽位 */ GPIO_ResetBits(me->port, me->pin); g_used[i] = 0; return; } } }