/** * @file main.c * @brief PC 模拟测试入口 * * 在 PC 上编译运行,模拟按键事件驱动 LED 状态机 * * 编译命令: * gcc -I inc -DAPP_DEBUG_LOG \ * src/main.c src/hal_mock.c src/led_driver.c src/btn_fsm.c src/app_controller.c \ * -o smart_led_test && ./smart_led_test * * 交互命令: * p → 模拟按下按键 (press) * r → 模拟释放按键 (release) * q → 退出 * * 测试场景: * 1. 短按一次(p → 等 100ms → r) → 单击: OFF → ON * 2. 快速按两次(p r p r,间隔 < 300ms) → 双击: ON → BLINK_SLOW * 3. 长按 1 秒以上(p → 等 1.2s → r) → 长按: 任意 → BREATHING */ #ifndef APP_DEBUG_LOG #define APP_DEBUG_LOG #endif #include #include #include #include "hal_gpio.h" #include "led_driver.h" #include "btn_fsm.h" #include "app_controller.h" /* hal_mock.c 中的模拟接口 */ extern void mock_set_button(uint8_t pressed); /* ======== 按键 HAL 适配层 ======== */ static uint8_t btn_read_pin(uint8_t button_id) { (void)button_id; return HAL_GPIO_ReadPin(GPIO_PORT_A, GPIO_PIN_0); } /* ======== 主程序 ======== */ int main(void) { printf("╔══════════════════════════════════════════╗\n"); printf("║ Smart LED Demo — OOPC + FSM 实例工程 ║\n"); printf("║ ║\n"); printf("║ p = 按下按键 r = 释放按键 ║\n"); printf("║ q = 退出 ║\n"); printf("║ ║\n"); printf("║ 操作指南: ║\n"); printf("║ 单击: p → 等50ms → r ║\n"); printf("║ 双击: p r p r (快速) ║\n"); printf("║ 长按: p → 等1.2s → r ║\n"); printf("╚══════════════════════════════════════════╝\n\n"); /* ---- 1. 创建 LED 驱动(不透明指针) ---- */ LedDriver_S* led = Led_Create(GPIO_PORT_B, GPIO_PIN_0, 1 /* active_low */); if (led == NULL) { printf("[ERROR] Led_Create failed\n"); return 1; } printf("[MAIN] LED driver created (opaque pointer)\n"); /* ---- 2. 初始化按键 FSM(开放结构体) ---- */ static Btn_FSM btn; /* 静态分配 */ Btn_Init(&btn, btn_read_pin, 0 /* button_id */, 0 /* active_low */); Btn_Start(&btn); printf("[MAIN] Button FSM initialized (open struct)\n"); /* ---- 3. 创建应用控制器(HSM) ---- */ AppCtrl_S* app = AppCtrl_Create(led, &btn); if (app == NULL) { printf("[ERROR] AppCtrl_Create failed\n"); return 1; } AppCtrl_Init(app); printf("[MAIN] App controller created (HSM)\n"); printf("[MAIN] Initial state: %s\n\n", AppCtrl_StateName(AppCtrl_GetState(app))); /* ---- 4. 主循环: 模拟按键输入 ---- */ char cmd[16]; uint32_t tick_count = 0; while (1) { printf("[STATE=%s] 输入命令 (p/r/q): ", AppCtrl_StateName(AppCtrl_GetState(app))); if (fgets(cmd, sizeof(cmd), stdin) == NULL) break; switch (cmd[0]) { case 'p': case 'P': mock_set_button(1); /* 按下 */ printf(" >>> 按键按下 <<<\n"); break; case 'r': case 'R': mock_set_button(0); /* 释放 */ printf(" >>> 按键释放 <<<\n"); break; case 'q': case 'Q': goto cleanup; default: printf(" 未知命令: %c\n", cmd[0]); continue; } /* 每次输入后执行若干 Tick(模拟 5ms 定时器 × 多次) */ for (int i = 0; i < 20; i++) { Btn_Tick(); AppCtrl_Poll(app, tick_count * 5); tick_count++; } printf(" LED brightness: %d%%\n\n", Led_GetBrightness(led)); } cleanup: printf("\n[MAIN] Cleanup...\n"); Btn_Stop(&btn); AppCtrl_Destroy(app); Led_Destroy(led); printf("[MAIN] Done.\n"); return 0; }