美文网首页
伍:按键驱动(短按、长按、双击)

伍:按键驱动(短按、长按、双击)

作者: 恰冯同学年少 | 来源:发表于2016-07-06 17:04 被阅读304次

    按键扫描驱动,支持按键的长按和短按事件(未实现双击事件),key_Scan()函数得到相应的键值,主程序根据键值进行动作。
    三个按键:Key_SPA Key_ZER Key_MEN



    Key_Board.h

    #ifndef Key_Board
    #define Key_Board
    
    #include <SH79F1611.h>
    #include "Timer_Init.h"
    
    typedef struct 
    {
        unsigned char Short_Press:1;      //短按
        unsigned char Long_Press:1;       //长按
        unsigned char Double_Press:1;     //双击
    }Key_State;
    
    extern xdata Key_State Key_SPA,Key_ZER,Key_MEN;
    void Key_Init(void);
    void Key_Scan(void);
    #endif
    

    key_Board.c

    #include "Key_Board.h"
    
    sbit SPA = P4^3;
    sbit ZER = P4^2;
    
    ////按键状态结构体定义 三个按键 SPA/ZER/MEN
     xdata Key_State Key_SPA = {0,0,0};
     xdata Key_State Key_ZER = {0,0,0};
     xdata Key_State Key_MEN = {0,0,0};
    
    //按键初始化
    void Key_Init(void)
    {
        P4CR &= ~0x0c;  //P4^2 P4^3 设置为输入接口 
        P4PCR |= 0x0c;  //输入上拉  
        P4CR |= 0x02;   //P4.1输出  作为按键地
        P4 &= ~0x02;
    }
    
    bit Key_Down_SPA_Short = 1;
    bit Key_Down_ZER_Short = 1;
    bit Key_Down_MEN_Short = 1; 
    
    bit Key_Down_SPA_Long = 1;
    bit Key_Down_ZER_Long = 1;
    bit Key_Down_MEN_Long = 1;
    
    /*****************************************************************************
    *1:按键扫描函数  三个按键公用两个IO口 先扫描SPA/ZER按键 再扫描MOD按键
    *2:程序支持按键短按和长按 短按按键在按键抬起后取值 长按按键在按键按下时可取值
    *3:按键长按后抬起,取得长按键值,短按键值被屏蔽 
    ******************************************************************************/
    void Key_Scan(void)
    {
        static xdata char cnt = 0;
        if((SPA==0) && (ZER==0))               //不支持同时按键
        {
            return ;                         
        } 
        
        if(SPA == 0)                                   //当SPA按键按下 
        {
            if((Key_Down_SPA_Short == 1)&&(Key_Down_SPA_Long == 1))
            {
                if(cnt++ >= 1)               //20ms防抖
                {
                    cnt = 0;
                    Key_Down_SPA_Short = 0; 
                    Key_Timing = 0;                  //按键计数变量清0 
                }
            }
            else
            if(Key_Down_SPA_Long == 1)
            {
                if(Key_Timing >= 300)
                {
                    Key_Timing = 0;
                    Key_Down_SPA_Long = 0;
                    Key_SPA.Long_Press = 1;    
                    Key_Down_SPA_Short = 1;
                }
            }
        }
        else
        if(ZER == 0)                            //当ZER按键按下 
        {
            if((Key_Down_ZER_Short == 1)&&(Key_Down_ZER_Long == 1))
            {
                if(cnt++ >= 1)                     //20ms防抖
                {
                    cnt = 0;
                    Key_Down_ZER_Short = 0; 
                    Key_Timing = 0;                  //按键计数变量清0 
                }
            }
            else
            if(Key_Down_ZER_Long == 1)
            {
                if(Key_Timing >= 200)
                {
                    Key_Timing = 0;
                    Key_Down_ZER_Long = 0;
                    Key_ZER.Long_Press = 1;    
                    Key_Down_ZER_Short = 1;
                }
            }
        }
        else                                          
        {
            P4CR |= 0x04;                          //设置ZER按键对应的IO口为输出 输出为0  
            ZER = 0;                               
            if(SPA == 0)                           //当MOD按键按下 
            {
                if((Key_Down_MEN_Short == 1)&&(Key_Down_MEN_Long == 1))
                {
                    if(cnt++ >= 1)                     //20ms防抖
                    {
                        cnt = 0;
                        Key_Down_MEN_Short = 0; 
                        Key_Timing = 0;                  //按键计数变量清0 
                    }
                }
                else
                if(Key_Down_MEN_Long == 1)
                {
                    if(Key_Timing >= 200)
                    {
                        Key_Timing = 0;
                        Key_Down_MEN_Long = 0;
                        Key_MEN.Long_Press = 1;    
                        Key_Down_MEN_Short = 1;
                    }
                }
            }
            else
            if((SPA == 1) && ((Key_Down_MEN_Short == 0) || (Key_Down_MEN_Long == 0)))
            {
                if(Key_Down_MEN_Short == 0) 
                {
                    Key_Down_MEN_Short = 1;
                    Key_MEN.Short_Press = 1;         //MEN短按
                }
                if(Key_Down_MEN_Long == 0)
                {
                    Key_Down_MEN_Long = 1;
                    Key_MEN.Long_Press = 0;
                }
            }
            P4CR &= ~0x04;       //设置ZER按键对应的IO口为输入 
            P4PCR |= 0x04;       //输入上拉
        }
        
        if(SPA == 1) 
        { 
            if(Key_Down_SPA_Short == 0)
            {
                Key_Down_SPA_Short = 1; 
                Key_SPA.Short_Press = 1;   
            }
            if(Key_Down_SPA_Long == 0) 
            {
                Key_Down_SPA_Long = 1;
                Key_SPA.Long_Press = 0;
            }
        } 
        
        if(ZER == 1) 
        {
            if(Key_Down_ZER_Short == 0) 
            {
                Key_Down_ZER_Short = 1;
                Key_ZER.Short_Press = 1;   
            }
            if(Key_Down_ZER_Long == 0) 
            {
                Key_Down_ZER_Long = 1;
                Key_ZER.Long_Press = 0;
            }
        } 
        
        if(Key_ZER.Long_Press==1 || Key_ZER.Short_Press==1 || Key_SPA.Long_Press==1 || Key_SPA.Short_Press==1 || Key_MEN.Long_Press==1 ||Key_MEN.Short_Press==1)
        {
            Set_Menu_Timeouy_5s = 0;         //有按键按下 菜单计数清0
        }
    }
    

    相关文章

      网友评论

          本文标题:伍:按键驱动(短按、长按、双击)

          本文链接:https://www.haomeiwen.com/subject/wjmkjttx.html