按键检测 短按、长按

#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;
    }
}
  

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以通过一个定时器来检测按键按和短按,具体实现方法如下: 1. 定义一个计数器变量count和一个标志位flag。 2. 在按键按下时,将count清零,并将flag置为1。 3. 启动定时器,在定时器中每隔一定时间检测一次按键状态。 4. 如果按键被松开,则将flag置为0,同时停止定时器。 5. 如果计数器变量count的值达到了按的时间阈值,就认为是按,执行按操作。 6. 如果计数器变量count的值没有达到按阈值,就认为是短按,执行短按操作。 下面是一个示例代码: ```c #define LONG_PRESS_TIME 1000 //按时间阈值,单位为ms #define TIMER_PERIOD 10 //定时器周期,单位为ms int count = 0; //计数器变量 int flag = 0; //标志位 void timer_isr() //定时器中断服务函数 { if (flag) { count += TIMER_PERIOD; //计数器加上定时器周期 if (count >= LONG_PRESS_TIME) //如果计数器达到了按时间阈值 { //执行按操作 } } } void button_isr() //按键中断服务函数 { if (button_is_pressed()) { count = 0; //计数器清零 flag = 1; //标志位置1 start_timer(TIMER_PERIOD); //启动定时器 } else { flag = 0; //标志位清零 stop_timer(); //停止定时器 if (count < LONG_PRESS_TIME) //如果计数器没有达到按时间阈值 { //执行短按操作 } count = 0; //计数器清零 } } ``` 需要注意的是,以上代码仅为示例,具体实现还需要根据具体硬件平台和按键接口进行相应的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值