新闻  |   论坛  |   博客  |   在线研讨会
长按键C语言程序
zhchxgh | 2009-07-04 01:46:51    阅读:9420   发布文章

一共用了四个按钮.

#define _KEYDOWN_TEST_TIME      (20)
unsigned char IsKeyDown(volatile unsigned char Value, unsigned char pin)
{
    unsigned long CurState = 0, i;
    for(i = 0; i < _KEYDOWN_TEST_TIME; ++i)
        CurState += _GET_BIT(Value, pin)? 0:1;     //键盘接了上拉电阻,低电平才是按下

    if(CurState == _KEYDOWN_TEST_TIME)
        return 1;

    return 0;
}


//以下所有值均是以 DealWithKey函数的调用频率为基础的,该频率是定时器2的定时值决定的
//短按键的计数值,只有当按键检测计数器计数大于等于此值时才认为是一次短按
#define _KEY_SHORT_CNTR             (2)
//长按键的计数值,只有当按键检测计数器计数大于等于此值时才认为是一次长按
#define _KEY_LONG_CNTR              (_KEY_SHORT_CNTR * 3)
//无按键按下时的按键检测间隔,用于按键消抖动
#define _KEY_NORMAL_DEVIDER         (2)
                 
//此值用于按钮长按后,按钮检测函数的执行频率                 
#define _ADDMIN_FAST_DEVIDER        (15)
//此值用于按钮短按后,按钮检测函数的执行频率
#define _ADDMIN_LONG_DEVIDER        (_ADDMIN_FAST_DEVIDER * 3)
//此值用于设置蜂鸣器鸣响时间
#define _BEEPER_DEVIDER             (10)
void DealWithKey(void)
{
    static unsigned int AddCntr = 0;
    static unsigned int MinCntr = 0;
    static unsigned int UnitCntr = 0;
    static unsigned int RunCntr = 0;
    
    static unsigned char BeepCntr = 0;
    
    static unsigned int DevCntr = 0;
    
    static unsigned char LastRunState = 0;
    
    unsigned char temp;
    
    if(g_State != Setting)  //运行状态, 所有按键都无效
        return;
            
    if(BeepCntr > 0)        //处理蜂鸣器
        --BeepCntr;
    else
        _BEEPER_OFF;
     

    if(DevCntr)           //按键处理分频器
    {
        --DevCntr;
        return;
    }
        
    //这个按钮是可以重复进入的, 长按后先低频率动作, 当动作几次后再高频率动作
    AddCntr = IsKeyDown(_PIN(_TO_KEY_ADD), _KEY_ADD)? AddCntr + 1 : 0;
    if((temp = (AddCntr >= _KEY_LONG_CNTR)) || AddCntr >= _KEY_SHORT_CNTR)
    {
 ...
    }
     
    //同上
    MinCntr = IsKeyDown(_PIN(_TO_KEY_MIN), _KEY_MIN)? MinCntr + 1 : 0;
    if((temp = (MinCntr >= _KEY_LONG_CNTR)) || MinCntr >= _KEY_SHORT_CNTR)
    {
        ...
    }

    //这个按钮是不可重复进入的, 就是说只有抬起后再按下才动作
    UnitCntr = IsKeyDown(_PIN(_TO_KEY_UNIT), _KEY_UNIT)? UnitCntr + 1 : 0;
    if(UnitCntr == _KEY_SHORT_CNTR)
    {
 ...
    }
    else if(UnitCntr > _KEY_SHORT_CNTR)
    {
        UnitCntr = _KEY_SHORT_CNTR + 1; //禁止重复执行
    }
    
    //这个按钮是要在按钮抬起后才执行其他函数的
    if(IsKeyDown(_PIN(_TO_KEY_RUN), _KEY_RUN))
    {
        ++RunCntr;
    }
    else
    {
        RunCntr = 0;
        if(LastRunState)            //表明键已经按下后才抬起的
        {
            LastRunState = 0;
            g_State = EmptyInflatting;
        }
    }
    if(RunCntr == _KEY_SHORT_CNTR)
    {
        BeepCntr = _BEEPER_DEVIDER;
        _BEEPER_ON;
        LastRunState = 1;       //此键是抬起时生效.
    }
    else if(RunCntr > _KEY_SHORT_CNTR)
    {
        RunCntr = _KEY_SHORT_CNTR + 1;  //禁止重复执行
    }
    
    DevCntr = _KEY_NORMAL_DEVIDER;
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客