活动介绍
file-type

DirectShow编程指南:全面掌握DV与TV应用

5星 · 超过95%的资源 | 下载需积分: 4 | 6.12MB | 更新于2025-06-15 | 153 浏览量 | 5 下载量 举报 收藏
download 立即下载
根据提供的文件信息,可以看出这些文件是一套关于DirectShow编程的电子书籍及资源。DirectShow是微软提供的一套用于开发媒体播放器、音视频编辑等应用的软件开发包(SDK)。接下来,我将详细介绍与DirectShow相关的知识点。 ### 知识点一:DirectShow简介 DirectShow是微软公司推出的一套针对Windows平台的媒体框架(Media Foundation),属于Windows平台多媒体应用的一部分。DirectShow SDK提供了开发音视频处理软件所必需的工具和接口,允许开发者编写程序来捕获、解码和显示音视频数据。DirectShow提供了基础的底层API,并通过Filter Graph管理器将不同的音视频处理单元(Filter)连接起来形成一个处理流程。 ### 知识点二:Filter Graph概念 Filter Graph是DirectShow的核心概念,它是由多个filter组成的有向图。Filter Graph管理器负责管理和调度这些filter,从而实现数据的流动和处理。典型的filter包括Source Filter、Transform Filter、Rendering Filter等。Source Filter负责数据的获取,如从文件、网络流中读取数据;Transform Filter负责数据的处理,如解码、编码、格式转换等;Rendering Filter负责数据的输出,如播放到屏幕或扬声器。 ### 知识点三:DirectShow编程基础 DirectShow编程涉及到COM(Component Object Model)接口的使用,这是因为DirectShow的Filter以及Filter Graph管理器都是基于COM技术实现的。编程人员需要熟练掌握如何使用COM接口,并了解如何在C++等支持COM的语言中创建和操作DirectShow对象。 ### 知识点四:MSPress Programming DirectShow 本系列的电子书籍由MSPress出版,是关于DirectShow编程的权威参考。书中将详细介绍DirectShow的工作原理、架构、主要的编程接口以及实际应用案例。这些内容对于想要深入学习DirectShow开发的程序员来说,是宝贵的资源。 ### 知识点五:文件格式说明 - CHM(Compiled HTML Help):一种Windows平台上的帮助文件格式,将HTML页面、图像和其他资源编译成一个单独的文件。程序员可以通过阅读CHM格式的电子书籍学习DirectShow编程技术。 - PDF(Portable Document Format):便携式文档格式,由Adobe公司开发,用于电子文档的交换和阅读。PDF文件通常用于打印或跨平台阅读。 - CD:在该上下文中,CD可能指的是伴随电子书籍的光盘资源。这可能包括示例代码、工具、演示程序或者其他开发资源。 ### 知识点六:DirectShow应用场景 DirectShow不仅限于音视频播放器的开发,它还广泛应用于以下领域: - 视频捕捉和编辑工具 - 数字媒体转换软件 - 直播和流媒体播放 - 多媒体内容分析和管理 ### 知识点七:DirectShow的优缺点 优点包括: - 灵活性高,支持多种音视频格式和数据流 - 开发人员可以自定义Filter,实现特定功能 - 良好的社区支持和文档资料 - 支持硬件加速,优化性能 缺点可能包括: - 对于初学者而言,学习曲线较为陡峭,COM编程复杂度高 - 不一定支持所有最新的音视频格式 - 微软不再重点开发DirectShow,对最新技术的支持有限 通过上述知识点的详细介绍,可以看出DirectShow在多媒体处理方面的强大功能和在Windows平台开发中的重要地位。对于有志于在音视频处理、流媒体和数字媒体领域深入发展的程序员而言,掌握DirectShow的开发技术是非常必要的。同时,利用MSPress的权威指南和配套的资源文件,将极大加快学习进度和提升开发技能。

相关推荐

filetype

这是我的button.h和button.c文件 /** * @File: flexible_button.h * @Author: MurphyZhao * @Date: 2018-09-29 * * Copyright (c) 2018-2019 MurphyZhao <[email protected]> * https://github.com/murphyzhao * All rights reserved. * License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Change logs: * Date Author Notes * 2018-09-29 MurphyZhao First add * 2019-08-02 MurphyZhao Migrate code to github.com/murphyzhao account * 2019-12-26 MurphyZhao Refactor code and implement multiple clicks * */ #ifndef __BUTTON_H__ #define __BUTTON_H__ #include "stdint.h" #include "key_app.h" #include "KEY.h" #define FLEX_BTN_SCAN_FREQ_HZ 50 // How often flex_button_scan () is called #define FLEX_MS_TO_SCAN_CNT(ms) (ms / (1000 / FLEX_BTN_SCAN_FREQ_HZ)) /* Multiple clicks interval, default 300ms */ #define MAX_MULTIPLE_CLICKS_INTERVAL (FLEX_MS_TO_SCAN_CNT(300)) /** * @brief 按钮事件枚举类型 * * 定义了各种按钮触发事件类型,包括: * - 按下(FLEX_BTN_PRESS_DOWN) * - 单击(FLEX_BTN_PRESS_CLICK) * - 双击(FLEX_BTN_PRESS_DOUBLE_CLICK) * - 重复点击(FLEX_BTN_PRESS_REPEAT_CLICK) * - 短按开始(FLEX_BTN_PRESS_SHORT_START) * - 短按抬起(FLEX_BTN_PRESS_SHORT_UP) * - 长按开始(FLEX_BTN_PRESS_LONG_START) * - 长按抬起(FLEX_BTN_PRESS_LONG_UP) * - 长按保持(FLEX_BTN_PRESS_LONG_HOLD) * - 长按保持后抬起(FLEX_BTN_PRESS_LONG_HOLD_UP) * - 最大值(FLEX_BTN_PRESS_MAX) * - 无事件(FLEX_BTN_PRESS_NONE) */ typedef enum { FLEX_BTN_PRESS_DOWN = 0, FLEX_BTN_PRESS_CLICK, FLEX_BTN_PRESS_DOUBLE_CLICK, FLEX_BTN_PRESS_REPEAT_CLICK, FLEX_BTN_PRESS_SHORT_START, FLEX_BTN_PRESS_SHORT_UP, FLEX_BTN_PRESS_LONG_START, FLEX_BTN_PRESS_LONG_UP, FLEX_BTN_PRESS_LONG_HOLD, FLEX_BTN_PRESS_LONG_HOLD_UP, FLEX_BTN_PRESS_MAX, FLEX_BTN_PRESS_NONE, } flex_button_event_t; /** * flex_button_t * * @brief Button data structure * Below are members that need to user init before scan. * * @member next * Internal use. * One-way linked list, pointing to the next button. * * @member usr_button_read * User function is used to read button vaule. * * @member cb * Button event callback function. * * @member scan_cnt * Internal use, user read-only. * Number of scans, counted when the button is pressed, plus one per scan cycle. * * @member click_cnt * Internal use, user read-only. * Number of button clicks * * @member max_multiple_clicks_interval * Multiple click interval. Default 'MAX_MULTIPLE_CLICKS_INTERVAL'. * Need to use FLEX_MS_TO_SCAN_CNT to convert milliseconds into scan cnts. * * @member debounce_tick * Debounce. Not used yet. * Need to use FLEX_MS_TO_SCAN_CNT to convert milliseconds into scan cnts. * * @member short_press_start_tick * Short press start time. Requires user configuration. * Need to use FLEX_MS_TO_SCAN_CNT to convert milliseconds into scan cnts. * * @member long_press_start_tick * Long press start time. Requires user configuration. * Need to use FLEX_MS_TO_SCAN_CNT to convert milliseconds into scan cnts. * * @member long_hold_start_tick * Long hold press start time. Requires user configuration. * * @member id * Button id. Requires user configuration. * When multiple buttons use the same button callback function, * they are used to distinguish the buttons. * Each button id must be unique. * * @member pressed_logic_level * Requires user configuration. * The logic level of the button pressed, each bit represents a button. * * @member event * Internal use, users can call 'flex_button_event_read' to get current button event. * Used to record the current button event. * * @member status * Internal use, user unavailable. * Used to record the current state of buttons. * */ typedef struct flex_button { struct flex_button* next; uint8_t (*usr_button_read)(void *); flex_button_response_callback cb; uint16_t scan_cnt; uint16_t click_cnt; uint16_t max_multiple_clicks_interval; uint16_t debounce_tick; uint16_t short_press_start_tick; uint16_t long_press_start_tick; uint16_t long_hold_start_tick; uint8_t id; uint8_t pressed_logic_level : 1; uint8_t event : 4; uint8_t status : 3; } flex_button_t; #ifdef __cplusplus extern "C" { #endif int32_t flex_button_register(flex_button_t *button); flex_button_event_t flex_button_event_read(flex_button_t* button); uint8_t flex_button_scan(void); void user_button_init(void); #ifdef __cplusplus } #endif #endif /* __FLEXIBLE_BUTTON_H__ */ /** * @File: flexible_button.c * @Author: MurphyZhao * @Date: 2018-09-29 * * Copyright (c) 2018-2019 MurphyZhao <[email protected]> * https://github.com/murphyzhao * All rights reserved. * License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Change logs: * Date Author Notes * 2018-09-29 MurphyZhao First add * 2019-08-02 MurphyZhao Migrate code to github.com/murphyzhao account * 2019-12-26 MurphyZhao Refactor code and implement multiple clicks * */ #include "button.h" #include "KEY.h" #include "string.h" #include "key_app.h" typedef enum { USER_BUTTON_UP = 0, // 对应 IoT Board 开发板的 PIN_KEY0 USER_BUTTON_LEFT, // 对应 IoT Board 开发板的 PIN_KEY1 USER_BUTTON_RIGHT, // 对应 IoT Board 开发板的 PIN_KEY2 USER_BUTTON_DOWN, USER_BUTTON_MID, // 对应 IoT Board 开发板的 PIN_WK_UP USER_BUTTON_MAX } user_button_t; static flex_button_t user_button[USER_BUTTON_MAX]; static uint8_t common_btn_read(void *arg) { uint8_t value = 0; flex_button_t *btn = (flex_button_t *)arg; switch (btn->id) { case USER_BUTTON_UP: value = key_scan().up; break; case USER_BUTTON_LEFT: value = key_scan().left; break; case USER_BUTTON_RIGHT: value =key_scan().right; break; case USER_BUTTON_DOWN: value = key_scan().down; break; case USER_BUTTON_MID: value = key_scan().mid; break; } return value; } // 配置项 说明 // id 按键编号 // usr_button_read 设置按键读值回调函数 // cb 设置按键事件回调函数 // pressed_logic_level 设置按键按下时的逻辑电平 // short_press_start_tick 短按起始 tick,使用 FLEX_MS_TO_SCAN_CNT 宏转化为扫描次数 // long_press_start_tick 长按起始 tick,使用 FLEX_MS_TO_SCAN_CNT 宏转化为扫描次数 // long_hold_start_tick 超长按起始 tick,使用 FLEX_MS_TO_SCAN_CNT 宏转化为扫描次数 // 注意,short_press_start_tick、long_press_start_tick 和 long_hold_start_tick 必须使用 FLEX_MS_TO_SCAN_CNT 将毫秒时间转化为扫描次数。 // user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(1500); 表示按键按下开始计时,1500 ms 后按键依旧是按下状态的话,就断定为短按开始。 //--------------------------------------------------改到这里了----------------------------- void user_button_init(void) { int i; memset(&user_button[0], 0x0, sizeof(user_button)); user_button[USER_BUTTON_UP].cb = up_btn_evt_cb; user_button[USER_BUTTON_LEFT].cb = left_btn_evt_cb; user_button[USER_BUTTON_RIGHT].cb = right_btn_evt_cb; user_button[USER_BUTTON_DOWN].cb = down_btn_evt_cb; user_button[USER_BUTTON_MID].cb = mid_btn_evt_cb; for (i = 0; i < USER_BUTTON_MAX; i ++) { user_button[i].id = i; user_button[i].usr_button_read = common_btn_read; user_button[i].pressed_logic_level = 0; user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(1500); user_button[i].long_press_start_tick = FLEX_MS_TO_SCAN_CNT(3000); user_button[i].long_hold_start_tick = FLEX_MS_TO_SCAN_CNT(4500); flex_button_register(&user_button[i]); } } #ifndef NULL #define NULL 0 #endif #define EVENT_SET_AND_EXEC_CB(btn, evt) \ do \ { \ btn->event = evt; \ if(btn->cb) \ btn->cb((flex_button_t*)btn); \ } while(0) /** * BTN_IS_PRESSED * * 1: is pressed * 0: is not pressed */ #define BTN_IS_PRESSED(i) (g_btn_status_reg & (1 << i)) enum FLEX_BTN_STAGE { FLEX_BTN_STAGE_DEFAULT = 0, FLEX_BTN_STAGE_DOWN = 1, FLEX_BTN_STAGE_MULTIPLE_CLICK = 2 }; typedef uint32_t btn_type_t; static flex_button_t *btn_head = NULL; /** * g_logic_level * * The logic level of the button pressed, * Each bit represents a button. * * First registered button, the logic level of the button pressed is * at the low bit of g_logic_level. */ btn_type_t g_logic_level = (btn_type_t)0; /** * g_btn_status_reg * * The status register of all button, each bit records the pressing state of a button. * * First registered button, the pressing state of the button is * at the low bit of g_btn_status_reg. */ btn_type_t g_btn_status_reg = (btn_type_t)0; static uint8_t button_cnt = 0; /** * @brief Register a user button * * @param button: button structure instance * @return Number of keys that have been registered, or -1 when error */ int32_t flex_button_register(flex_button_t *button) { flex_button_t *curr = btn_head; if (!button || (button_cnt > sizeof(btn_type_t) * 8)) { return -1; } while (curr) { if(curr == button) { return -1; /* already exist. */ } curr = curr->next; } /** * First registered button is at the end of the 'linked list'. * btn_head points to the head of the 'linked list'. */ button->next = btn_head; button->status = FLEX_BTN_STAGE_DEFAULT; button->event = FLEX_BTN_PRESS_NONE; button->scan_cnt = 0; button->click_cnt = 0; button->max_multiple_clicks_interval = MAX_MULTIPLE_CLICKS_INTERVAL; btn_head = button; /** * First registered button, the logic level of the button pressed is * at the low bit of g_logic_level. */ g_logic_level |= (button->pressed_logic_level << button_cnt); button_cnt ++; return button_cnt; } /** * @brief Read all key values in one scan cycle * * @param void * @return none */ static void flex_button_read(void) { uint8_t i; flex_button_t* target; /* The button that was registered first, the button value is in the low position of raw_data */ btn_type_t raw_data = 0; for(target = btn_head, i = button_cnt - 1; (target != NULL) && (target->usr_button_read != NULL); target = target->next, i--) { raw_data = raw_data | ((target->usr_button_read)(target) << i); } g_btn_status_reg = (~raw_data) ^ g_logic_level; } /** * @brief Handle all key events in one scan cycle. * Must be used after 'flex_button_read' API * * @param void * @return Activated button count */ static uint8_t flex_button_process(void) { uint8_t i; uint8_t active_btn_cnt = 0; flex_button_t* target; for (target = btn_head, i = button_cnt - 1; target != NULL; target = target->next, i--) { if (target->status > FLEX_BTN_STAGE_DEFAULT) { target->scan_cnt ++; if (target->scan_cnt >= ((1 << (sizeof(target->scan_cnt) * 8)) - 1)) { target->scan_cnt = target->long_hold_start_tick; } } switch (target->status) { case FLEX_BTN_STAGE_DEFAULT: /* stage: default(button up) */ if (BTN_IS_PRESSED(i)) /* is pressed */ { target->scan_cnt = 0; target->click_cnt = 0; EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_DOWN); /* swtich to button down stage */ target->status = FLEX_BTN_STAGE_DOWN; } else { target->event = FLEX_BTN_PRESS_NONE; } break; case FLEX_BTN_STAGE_DOWN: /* stage: button down */ if (BTN_IS_PRESSED(i)) /* is pressed */ { if (target->click_cnt > 0) /* multiple click */ { if (target->scan_cnt > target->max_multiple_clicks_interval) { EVENT_SET_AND_EXEC_CB(target, target->click_cnt < FLEX_BTN_PRESS_REPEAT_CLICK ? target->click_cnt : FLEX_BTN_PRESS_REPEAT_CLICK); /* swtich to button down stage */ target->status = FLEX_BTN_STAGE_DOWN; target->scan_cnt = 0; target->click_cnt = 0; } } else if (target->scan_cnt >= target->long_hold_start_tick) { if (target->event != FLEX_BTN_PRESS_LONG_HOLD) { EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_LONG_HOLD); } } else if (target->scan_cnt >= target->long_press_start_tick) { if (target->event != FLEX_BTN_PRESS_LONG_START) { EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_LONG_START); } } else if (target->scan_cnt >= target->short_press_start_tick) { if (target->event != FLEX_BTN_PRESS_SHORT_START) { EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_SHORT_START); } } } else /* button up */ { if (target->scan_cnt >= target->long_hold_start_tick) { EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_LONG_HOLD_UP); target->status = FLEX_BTN_STAGE_DEFAULT; } else if (target->scan_cnt >= target->long_press_start_tick) { EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_LONG_UP); target->status = FLEX_BTN_STAGE_DEFAULT; } else if (target->scan_cnt >= target->short_press_start_tick) { EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_SHORT_UP); target->status = FLEX_BTN_STAGE_DEFAULT; } else { /* swtich to multiple click stage */ target->status = FLEX_BTN_STAGE_MULTIPLE_CLICK; target->click_cnt ++; } } break; case FLEX_BTN_STAGE_MULTIPLE_CLICK: /* stage: multiple click */ if (BTN_IS_PRESSED(i)) /* is pressed */ { /* swtich to button down stage */ target->status = FLEX_BTN_STAGE_DOWN; target->scan_cnt = 0; } else { if (target->scan_cnt > target->max_multiple_clicks_interval) { EVENT_SET_AND_EXEC_CB(target, target->click_cnt < FLEX_BTN_PRESS_REPEAT_CLICK ? target->click_cnt : FLEX_BTN_PRESS_REPEAT_CLICK); /* swtich to default stage */ target->status = FLEX_BTN_STAGE_DEFAULT; } } break; } if (target->status > FLEX_BTN_STAGE_DEFAULT) { active_btn_cnt ++; } } return active_btn_cnt; } /** * flex_button_event_read * * @brief Get the button event of the specified button. * * @param button: button structure instance * @return button event */ flex_button_event_t flex_button_event_read(flex_button_t* button) { return (flex_button_event_t)(button->event); } /** * flex_button_scan * * @brief Start key scan. * Need to be called cyclically within the specified period. * Sample cycle: 5 - 20ms * * @param void * @return Activated button count */ uint8_t flex_button_scan(void) { flex_button_read(); return flex_button_process(); }

filetype

/*********右按键扫描*********/ uchar Right_key_boot() { /**************************/ if(Right_Key_EN==0)return(0); else if(Right_Espresso_Button!=1&&Right_Key_LED) { while(Right_Espresso_Button!=1&&Right_Espresso_Press_Bit==0) { delay_us(1); if(Right_Key_Shake_Count++>=10) { Right_Espresso_Press_Bit=1; Right_Key_Shake_Count=10; } } if(Right_Espresso_Press_Bit) { if(Right_Lungo_Button!=1||Right_Play_Button!=1||Right_Key_Long_Press_Bit)return(0); else if(Right_Key_Press_Time>30) { Right_Espresso_Press_Bit=0; Right_Key_Long_Press_Bit=1; return(Right_Espresso_Button_Long_Press); } } } else if(Right_Espresso_Press_Bit&&Right_Key_Long_Press_Bit!=1) { Right_Espresso_Press_Bit=0; return(Right_Espresso_Button_Press); } /**************************/ else if(Right_Lungo_Button!=1&&Right_Key_LED) { while(Right_Lungo_Button!=1&&Right_Lungo_Press_Bit==0) { delay_us(1); if(Right_Key_Shake_Count++>=10) { Right_Lungo_Press_Bit=1; Right_Key_Shake_Count=10; } } if(Right_Lungo_Press_Bit) { if(Right_Espresso_Button!=1||Right_Play_Button!=1||Right_Key_Long_Press_Bit)return(0); else if(Right_Key_Press_Time>30) { Right_Lungo_Press_Bit=0; Right_Key_Long_Press_Bit=1; return(Right_Lungo_Button_Long_Press); } } } else if(Right_Lungo_Press_Bit&&Right_Key_Long_Press_Bit!=1) { Right_Lungo_Press_Bit=0; return(Right_Lungo_Button_Press); } /**************************/ else if(Right_Play_Button!=1) { while(Right_Play_Button!=1&&Right_Play_Press_Bit==0) { delay_us(1); if(Right_Key_Shake_Count++>=10) { Right_Play_Press_Bit=1; Right_Key_Shake_Count=10; } } if(Right_Play_Press_Bit) { if(Right_Espresso_Button!=1||Right_Lungo_Button!=1||Right_Key_Long_Press_Bit)return(0); else if(Right_Key_Press_Time>30) { Right_Play_Press_Bit=0; Right_Key_Long_Press_Bit=1; return(Right_Play_Button_Long_Press); } } } else if(Right_Play_Press_Bit&&Right_Key_Long_Press_Bit!=1) { Right_Play_Press_Bit=0; return(Right_Play_Button_Press); } /**************************/ else { Right_Key_Press_Time=0; Right_Key_Press_Bit=0; Right_Key_Long_Press_Bit=0; Right_Key_Shake_Count=0; Right_Espresso_Press_Bit=0; Right_Lungo_Press_Bit=0; Right_Play_Press_Bit=0; } //按键按下定时,按键按下标志,按键长按标志,按键防抖计时器 return(0); }

filetype
filetype
filetype
filetype
filetype
filetype

void Timer0_init() //20ms T = (65536-[TH0,TL0])/SYSCLK*分频数(12T或1T) { AUXR &= 0x7F; // 定时器0时钟12T模式 TMOD &= 0xF0; // 设置定时器模式 TMOD |= 0x00; // 16位自动重装 TL0 = 0xC0; // 初始化定时值 TH0 = 0x63; // 初始化定时值 TF0 = 0; // 清除TF0标志 TR0 = 1; // 启动定时器0 ET0 = 1; // 允许定时器0中断 EA = 1; // 开启总中断 } /*定时器中断*/ void TM0_Isr() interrupt 1 { unsigned int key_menu_press_time, key_up_press_time, key_down_press_time; // 扫描KEY_MENU if (KEY_MENU == 0) { // 按下(假设低电平有效) switch (key_menu_state) { case KEY_IDLE: key_menu_state = KEY_DEBOUNCE; key_menu_press_time = 0; break; case KEY_DEBOUNCE: key_menu_press_time++; if(key_menu_press_time >= 1) { // 20ms消抖 key_menu_state = KEY_PRESSED; } break; case KEY_PRESSED: key_menu_press_time++; if(key_menu_press_time >= 50) { // 1s长按 key_menu_state = KEY_LONG; } break; case KEY_LONG: // 长按保持 break; case KEY_RELEASE: // 不可能出现,因为按键还按着 break; } } else { // 松开 if(key_menu_state == KEY_PRESSED || key_menu_state == KEY_LONG) { // 触发按键事件(短按或长按) if (key_menu_state == KEY_PRESSED) { key_menu_event = EVENT_MENU_SHORT; } else { key_menu_event = EVENT_MENU_LONG; } key_menu_state = KEY_IDLE; } else { key_menu_state = KEY_IDLE; } } // 扫描KEY_UP if (KEY_UP == 0) { // 按下(假设低电平有效) switch (key_up_state) { case KEY_IDLE: key_up_state = KEY_DEBOUNCE; key_up_press_time = 0; break; case KEY_DEBOUNCE: key_up_press_time++; if(key_up_press_time >= 1) { // 20ms消抖 key_up_state = KEY_PRESSED; } break; case KEY_PRESSED: key_up_press_time++; if(key_up_press_time >= 50) { // 1s长按 key_up_state = KEY_LONG; } break; case KEY_LONG: // 长按保持 break; case KEY_RELEASE: // 不可能出现,因为按键还按着 break; } } else { // 松开 if(key_up_state == KEY_PRESSED || key_up_state == KEY_LONG) { // 触发按键事件(短按或长按) if (key_up_state == KEY_PRESSED) { key_up_event = EVENT_UP_SHORT; } else { key_up_event = EVENT_UP_LONG; } key_up_state = KEY_IDLE; } else { key_up_state = KEY_IDLE; } } // 扫描KEY_DOWN if (KEY_DOWN == 0) { // 按下(假设低电平有效) switch (key_down_state) { case KEY_IDLE: key_down_state = KEY_DEBOUNCE; key_down_press_time = 0; break; case KEY_DEBOUNCE: key_down_press_time++; if(key_down_press_time >= 1) { // 20ms消抖 key_down_state = KEY_PRESSED; } break; case KEY_PRESSED: key_down_press_time++; if(key_down_press_time >= 50) { // 1s长按 key_down_state = KEY_LONG; } break; case KEY_LONG: // 长按保持 break; case KEY_RELEASE: // 不可能出现,因为按键还按着 break; } } else { // 松开 if(key_down_state == KEY_PRESSED || key_down_state == KEY_LONG) { // 触发按键事件(短按或长按) if (key_down_state == KEY_PRESSED) { key_down_event = EVENT_DOWN_SHORT; } else { key_down_event = EVENT_DOWN_LONG; } key_down_state = KEY_IDLE; } else { key_down_state = KEY_IDLE; } } }这段定时器在运行时key_down按下 EVENT_DOWN_SHORT的时候没有反应,EVENT_DOWN_LONG有反应是什么情况

Littlejohnnyh
  • 粉丝: 2
上传资源 快速赚钱