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

2016-07-06  本文已影响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
    }
}
上一篇下一篇

猜你喜欢

热点阅读