zoukankan      html  css  js  c++  java
  • 实用按键事件检测(单击、长按)

      前断时间阅读“大佬”程序,发掘出有几个好用的,自定义的函数,此类函数巧妙使用返回值,传递参数,设置标志位、定时、赋值等功能,今晚特此来分享下。

    一、定时功能函数

    1.1   user_timer.c

    #include    "user_define.h"
    extern U16 timer1_time_cnt;
    
    static    U16 user_timer_array[USER_TIMER_AMOUNT] = {0};
    static    U16 timeout_control_array[USER_TIMER_AMOUNT] = {0};
    void user_timer_init(void)        // 数组初始化
    {
        U8 i = 0 ;
        for(i = 0; i < USER_TIMER_AMOUNT; i++){
            user_timer_array[i] = 0;
            timeout_control_array[i] = 0;
        }
    }
    
    /*********************
        function:    
            The system reference time is added to the user time array.
        parameter:
            null
        return:
            null
    *********************/
    void add_system_time(void)                  // 添加 时间 (放主循环)
    {
        U16 i = 0 ;
        U16 temp;
        
        temp = timer1_time_cnt;
        timer1_time_cnt = 0;
        
        for(i = 0; i < USER_TIMER_AMOUNT; i++)
        {
            if(user_timer_array[i] <= timeout_control_array[i])
                user_timer_array[i] += temp;
    
        }
    }
    
    /*********************
        function:    
            Clear the user time count.
        parameter:
            USER_TIMER0_CNT ...... USER_TIMERN_CNT or user typedef name
        return:
            null
    *********************/
    void clear_time_cnt(U8 time_number)        // 清除时间
    {
        if(USER_TIMER_AMOUNT > time_number)
            user_timer_array[time_number] = 0;
    }
    
    /*********************
        function:    
            time if arrived
        parameter:
            <time_number>
                USER_TIMER0_CNT ...... USER_TIMERN_CNT or user typedef name
            <time>
                check time
        return:
            null
    *********************/ 
    
    
    
    
    U8 check_time_arrive(U8 time_number, U16 time)  // 检查设定时间,是否到达
    {
        if(USER_TIMER_AMOUNT > time_number){
            timeout_control_array[time_number] = time;
            
            if(time <= user_timer_array[time_number])
                return 1;
            else
                return 0;
        }
        return 0;
    }

    1.2 user_timer.h

    //============================================
    //user timer
    //============================================
    #define    USER_TIMER_AMOUNT    5
    
    #define    KEY_TRIGGER_TIMER    0
    #define VR_TIMEOUT_TIMER    1
    #define    RANDOM_TIMER        2
    #define KEY_CONTROL_TIMER     3
    #define USER_TIMER_0        4
    
    ////============================================================
    //key
    //
    ////============================================================
    
    #define KEY_IO_INPUT    0
    #define KEY_IO_OUTPUT   1
    
    #define KEY_DEBOUNCE_TIME   8   //8MS
    #define KEY_LONG_PRESS_TIME 2300    //2s
    
    
    #define KEY_NOT_ACTION  0
    #define KEY_CLICK_ACTION   1
    #define KEY_LONG_PRESS_ACTION   3
    #define KEY_LONG_RELEASE_ACTION   4
    
    extern void user_timer_init(void);
    extern void add_system_time(void);
    extern void clear_time_cnt(U8 time_number);
    extern U8 check_time_arrive(U8 time_number, U16 time);

    二、按键事件

    1.1 user_key.c

    #include    "user_key.h"
    
    static U8 key_event_flag = 0;
    
    /* 需注意,当产生单击事件时,处理完毕后,记得释放按键事件,即调用,void rest_key_state();函数,释放按键。*/
    
    void user_key_init()
    {
      key_event_flag = KEY_NOT_ACTION ;
    }
    void user_key_scan(void)
    {
        U8 key_state = 1;                   // 按键未被触发时电平
        static U8 key_step = 0;
    
        key_state = GPIO_Read(GPIOA, 3);    // 按键端口赋值
    
        switch(key_step)
        {
            case 0:
                if(key_state)                                                    // 第0步,按键未被触发
                    clear_time_cnt(KEY_TRIGGER_TIMER);                           // 清除消抖时间
                else                                    
                    key_step++;                                                      // 按键触发 ,进入第1步
                break;
            case 1:
                if(key_state)                                                     // 再次确认按键是否按下 ,
                    key_step--;                                                   // 若没有,则返回第0步
                else                                                              // 如确认按键按下
                {
                    if(check_time_arrive(KEY_TRIGGER_TIMER, KEY_DEBOUNCE_TIME))  // 检查按键按下时间,是否超过设定消抖时间 ,若超过
                    {
                        clear_time_cnt(KEY_TRIGGER_TIMER);                        // 清除消抖时间
                        key_step++;                                                // 进入 第2步
                    } 
                }
                break;
            case 2:
                if(key_state)                                                    // 若超过设定消抖时间后,按键弹起
                {
                    clear_time_cnt(KEY_TRIGGER_TIMER);                            // 清除消抖时间
                    key_step++;                                                    // 进入第3部
                }
                else                                                            // 若超过设定消抖时间后,按键还未被释放
                {
                    if(check_time_arrive(KEY_TRIGGER_TIMER, KEY_LONG_PRESS_TIME)) //检查按键按下时间是否超过 长按设定时间 ,若超过
                    {
                        key_event_flag = KEY_LONG_PRESS_ACTION;                    // 发生长按 动作 按键按下
                        key_step += 2;                                            // 进入第4步
                    }
                }
                break;
            case 3:
                if(key_state)                                                    // 按键被释放
                {
                    if(check_time_arrive(KEY_TRIGGER_TIMER, KEY_DEBOUNCE_TIME)) // 检查释放时间是否满足 消抖时间 ,若满足
                    {
                        key_event_flag = KEY_CLICK_ACTION;                        // 则发生 单击 动作
                        key_step = 0;                                            // 返回 第 0 步
                    }
                }
                else                                                            // 若按键释放时间 未满足 消抖时间 ,则
                {
                    clear_time_cnt(KEY_TRIGGER_TIMER);                          // 清除消抖时间
                    key_step--;                                                    // 返回 第3步 ,继续判断按键按下时间,
                }
                break;
            case 4:
                if(key_state)                                                    // 长按 按键释放后
                {
                    if(check_time_arrive(KEY_TRIGGER_TIMER, KEY_DEBOUNCE_TIME)) //检查长按按键 释放 时间是否满足 按键消抖时间 
                    {
                        key_event_flag = KEY_LONG_RELEASE_ACTION;               // 则 发生 长按 动作释放按键
                        key_step = 0;                                           // 返回 第 0 步
                    }
                }
                break;
            default:
                break;
        }
    }
    uint8_t return_key_state() //返回按键 事件值  
    {
       return key_event_flag ;
    
    }
    
    
    void rest_key_state()   //按键释放
    {
      key_event_flag = KEY_NOT_ACTION ;
    }
    
    
    
     

    1.2 user_key.h

    ////============================================================
    //key
    //
    ////============================================================
    
    #define KEY_IO_INPUT    0
    #define KEY_IO_OUTPUT   1
    
    #define KEY_DEBOUNCE_TIME   8   //8MS
    #define KEY_LONG_PRESS_TIME 2300    //2s
    
    #define KEY_NOT_ACTION  0
    #define KEY_CLICK_ACTION   1
    #define KEY_LONG_PRESS_ACTION   3
    #define KEY_LONG_RELEASE_ACTION   4
    //============================================
    //user timer
    //============================================
    #define    USER_TIMER_AMOUNT    5
    
    #define    KEY_TRIGGER_TIMER    0
    #define VR_TIMEOUT_TIMER    1
    #define    RANDOM_TIMER        2
    #define KEY_CONTROL_TIMER     3
    #define USER_TIMER_0        4

    三、设置标志位

    1.1 user_flag.c

    #include "User_Flag.h"
    
    static idata uint8_t user_flag_array[USER_FLAG_AMOUNT_FLAG_NUMBER] = {0};
    
    
    void user_flag_init(void)
    {
        uint8_t i;
        for(i = 0; i < USER_FLAG_AMOUNT_FLAG_NUMBER; i++)
        {
            user_flag_array[i] = 0;
        }
        return;
    }
    
    //设置标志位
    void user_Set_flag( uint8_t flag_number , uint8_t flag_set_val )
    {
                user_flag_array[flag_number] = flag_set_val ;
    }
    
    
    //检测标志位是否是想要的数
    bit check_flag_arrive( uint8_t flag_number, uint8_t flag_dream_val  )
    {        
          if( user_flag_array[flag_number] == flag_dream_val )
                return 1;
            else
                return 0;
    }
    
    uint8_t get_arrive( uint8_t flag_number )   //返回标志位值
    {
    
      return user_flag_array[flag_number] ;
    
    
    }
    ////////////////////////////////////////////////////////////////////////////////////////////
    //void user_OTA_set_data( uint8_t flag_number , uint16_t flag_set_val )
    //{
    //  user_OTA_config[flag_number] = flag_set_val ;
    
    //}
    ////返回标志位数值
    //uint16_t return_dreanm_val( uint8_t  flag_number ) 
    //{
    
    // return user_OTA_config[flag_number];
    
    
    //}
    
    /////////////////////////////////////////////////////////////////////////////////////////

    1.2 user_flag.h

    #ifndef _User_Flag_H_
    #define _User_Flag_H_
    
    #include "includes.h"
    
    void user_flag_init(void);
    
    
    void user_Set_flag( uint8_t flag_number , uint8_t flag_set_val );
    
    bit check_flag_arrive( uint8_t flag_number,  uint8_t flag_dream_val );
    
    uint8_t get_arrive( uint8_t flag_number );
    
    
    //uint8_t return_dreanm_val( uint8_t  flag_number );
    
    
    //uint16_t return_dreanm_val( uint8_t  flag_number );
    
    //void user_OTA_set_data( uint8_t flag_number , uint16_t flag_set_val );
    
    
    
    
    
    #endif
  • 相关阅读:
    .NET开源系统
    DEDEcms二次开发数据表参数
    dede系统的pagebreak文章页面分页数量控制方法
    窗口最小化到托盘
    SEO项目各个阶段的工作分配
    scrollTop
    去除行内块间的间距
    jquery mobile
    nodejs学习
    cancelAnimationFrame无效
  • 原文地址:https://www.cnblogs.com/UPUPDay2152/p/10415090.html
Copyright © 2011-2022 走看看