按键检测 短按、长按

#define KEY_UP  1
#define KEY_DOWN 2
//
u8 key_type=0;      //按键类型
u8 f_longkey=0;  //长按按键有效
void KeyScan(void)
{
    static u8 key_scan=0;       //按键 扫描
    static u8 key_value = 0;   //按键值
    static u8 key_ValueTmp=0;  //按键值暂存
    static u8 f_onkey=0;       //判断按键是否释放

    static u8 key_longtime; //长按按键基准时间1
    static u8 key_longtime1;//长按按键时间 总时间=key_longtime*key_longtime1*2ms+10ms(10ms为清抖时间)


    if((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8))||(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3))||(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14))||(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13)))        //有按键操作
    {
        GPIO_ResetBits(GPIOB, GPIO_Pin_5) ;
        GPIO_SetBits(GPIOB, GPIO_Pin_4);

        __nop();
        __nop();
        if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8))
        {
            key_value |=0x04;    //上
        }
        if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3))
        {
            key_value |=0x20;    //分闸
        }
        if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13))
        {
            key_value |=0x10;    //复位
        }

        GPIO_ResetBits(GPIOB, GPIO_Pin_4) ;
        GPIO_SetBits(GPIOB, GPIO_Pin_5);

        __nop();
        __nop();

        if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8))
        {
            key_value |=0x02;    //确认
        }
        if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3))
        {
            key_value |=0x80;    //down
        }
        if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14))
        {
            key_value |=0x40;    //left
        }
        if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13))
        {
            key_value |=0x08;    //右
        }
    }
    else  key_value = 0;

    GPIO_SetBits(GPIOB, GPIO_Pin_4) ;
    GPIO_SetBits(GPIOB, GPIO_Pin_5) ;

    if(key_ValueTmp == key_value)//如不相等,保存当前按键值,清抖
    {
        if (key_scan > 5)//抖动处理
        {
            if(key_value>0)//无按键按下确认,等于0时表示无按键,清释放标识位
            {
                if(!f_onkey)//判断按键是否释放
                {
                    f_onkey=1;
                    switch(key_value)
                    {
                    case 128:
                        key_type = KEY_DOWN;//SW1有效执行内容
                        break;
                    case 4:
                        key_type = KEY_UP;//SW2有效执行内容
                        break;
                    default:
                        break;
                    }
                }
                else
                {
                    if(++key_longtime>90)
                    {
                        key_longtime=0;
                        if(++key_longtime1>6)
                        {
                            key_longtime1=0;
                            f_longkey=1;//长按按键有效
                        }
                    }
                }
            }
            else//按键释放
            {
                f_onkey=0;
                f_longkey=0;
            }
        }
        else
        {
            key_scan ++;
        }

    }
    else
    {
        key_ValueTmp = key_value;
        key_scan = 0;
    }
}
  

 

你可能感兴趣的:(模块程序)