/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2025-03-24 RuoFeng the first version */ #ifndef APPLICATIONS_KEY_C_ #define APPLICATIONS_KEY_C_ /*********************↓ define ↓************************/ #define DBG_ENABLE #define DBG_COLOR #define DBG_TAG "key" #define DBG_LEVEL DBG_INFO #include #define KEY_THREAD_PRIORITY 11 // 线程优先级 #define KEY_THREAD_STACK_SIZE 512 // 线程栈空间大小 #define KEY_THREAD_TIMESLICE 10 // 时间片 #define LED_PIN Key_OUT #define LED_ON() rt_pin_write(LED_PIN, PIN_HIGH) #define LED_OFF() rt_pin_write(LED_PIN, PIN_LOW) #define DELAY_UNIT 100 #define ManualTime 60 // mins /*********************↑ define ↑************************/ /** * * * * * */ /*********************↓ include ↓************************/ #include /*********************↑ include ↑************************/ /** * * * * * */ /*********************↓ extern ↓************************/ extern works_def ws_now; /*********************↑ extern ↑************************/ /** * * * * * */ /********************↓ declaration ↓***********************/ static rt_timer_t KeyTimer; // 定时器命名 static volatile bool GetIn = false; static volatile bool GetOut = false; /** * * * */ /* 模式参数结构体 */ typedef struct { rt_uint16_t off_duration; rt_uint16_t on_duration; rt_uint8_t blink_count; } ModePattern; /* 模式参数映射表 */ static const ModePattern mode_pattern[ws_typemax] = { [ws_standby] = {10, 2, 1}, // 1000ms灭/200ms亮 [ws_wait0] = {10, 2, 2}, // 1000ms灭 双闪 [ws_wait_coll] = {10, 10, 1}, // 1000ms周期 // [ws_waitTig] = {10, 2, 3}, // 1000ms灭 三连闪 [ws_KeyTig] = {3, 1, 1}, // 300ms灭/100ms亮 [ws_takephoto] = {5, 30, 1}, // 拍照相关模式 }; /********************↑ declaration ↑***********************/ /** * * * * * */ /*********************↓ global variables ↓************************/ volatile uint16_t KeyTigCnt = 0; // 按键触发计数 static rt_bool_t KeyTrigFlag = RT_FALSE; /*********************↑ global variables ↑************************/ /** * * * * * */ /********** Key Drivers ************/ /* 防抖定时器回调 */ static void KeyHandler(void *param) { if (KeyTrigFlag == RT_TRUE) { rt_timer_stop(KeyTimer); KeyTigCnt++; rt_kprintf("[KeyFlags] get > %d\n", KeyTigCnt); } KeyTrigFlag = RT_FALSE; } static rt_err_t KeyIrqHandler(void *args) { // rt_kprintf("[Key] A activated! \n"); if (KeyTrigFlag != RT_TRUE) { KeyTrigFlag = RT_TRUE; rt_timer_start(KeyTimer); } return RT_EOK; } /** * @brief 初始化按键 * * @return int */ int ExtKeyInit(void) { /* GPIO模式配置 */ rt_pin_mode(Key_IN, PIN_MODE_INPUT_PULLDOWN); rt_pin_mode(Key_OUT, PIN_MODE_OUTPUT); rt_pin_write(Key_OUT, 1); rt_pin_write(Key_IN, 0); rt_pin_attach_irq(Key_IN, PIN_IRQ_MODE_RISING, KeyIrqHandler, RT_NULL); rt_pin_irq_enable(Key_IN, PIN_IRQ_ENABLE); KeyTimer = rt_timer_create("KeyTimer", KeyHandler, RT_NULL, 99, // 防抖时间 RT_TIMER_FLAG_ONE_SHOT); rt_kprintf("[Key] trigger initialized!\n"); return RT_EOK; } /********** Key Drivers ************/ static void ManualMode(void) { works_def res = ws_standby; bool rtu_status = rt_pin_read(RTU_DTU); uint16_t cnt = 0; res = ws_now; while (cnt++ < (ManualTime * 200) && GetOut == false) { //rt_kprintf("ManualModeExc\n"); ws_now = ws_KeyTig; ctr_RTU_DTU(ON); LED_ON(); rt_thread_mdelay(150); LED_OFF(); rt_thread_mdelay(150); } ws_now = res; if(ws_now == ws_KeyTig) { ws_now = ws_standby; } GetIn = false; GetOut = false; rtu_status ? ctr_RTU_DTU(ON) : ctr_RTU_DTU(OFF); } static void led_delay(uint16_t times) { for (uint16_t a = 0; a < times; a++) { rt_thread_mdelay(DELAY_UNIT); if (GetIn) { ManualMode(); } } } static void led_thread_entry(void *param) { int current_mode = 0; while (1) { current_mode = ws_now; if (ws_now >= ws_takephoto && ws_now < ws_KeyTig) { current_mode = ws_takephoto; } LED_OFF(); led_delay(mode_pattern[current_mode].off_duration); if (mode_pattern[current_mode].blink_count > 1) { for (int i = 0; i < mode_pattern[current_mode].blink_count; i++) { LED_ON(); led_delay(mode_pattern[current_mode].on_duration); if (current_mode != ws_now && current_mode != ws_takephoto) if (current_mode != ws_now) break; LED_OFF(); led_delay(mode_pattern[current_mode].on_duration); } } else { LED_ON(); led_delay(mode_pattern[current_mode].on_duration); } //rt_kprintf("current_mode > %d \n", current_mode); rt_thread_mdelay(100); } } int led_init(void) { rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); rt_thread_t tid = rt_thread_create("led", led_thread_entry, RT_NULL, 512, 20, 10); return tid ? rt_thread_startup(tid) : -1; } INIT_APP_EXPORT(led_init); static void Key_thread_entry(void *param) { ExtKeyInit(); while (1) { while (KeyTigCnt == 0) { rt_thread_mdelay(10); } for (char a = 0; a < 100; a++) { rt_thread_mdelay(30); if (KeyTigCnt >= 3) { break; } } if (KeyTigCnt >= 3 && GetIn != true) { rt_kprintf("KeyTigCnt GetIn\n"); GetIn = true; KeyTigCnt = 0; } else if (KeyTigCnt >= 3 && GetOut != true) { rt_kprintf("KeyTigCnt GetOut\n"); GetOut = true; KeyTigCnt = 0; } else { KeyTigCnt = 0; } } } void KeyThreadStart(void) { rt_thread_t Key_thread = rt_thread_create("Key_thread", Key_thread_entry, RT_NULL, KEY_THREAD_STACK_SIZE, KEY_THREAD_PRIORITY, KEY_THREAD_TIMESLICE); if (Key_thread != RT_NULL) { rt_thread_startup(Key_thread); } else { rt_kprintf("Key_thread start faild \n"); } } INIT_APP_EXPORT(KeyThreadStart); #endif /* APPLICATIONS_KEY_C_ */