蓝桥杯嵌入式开发-按键长按_单击_双击

蓝桥杯嵌入式开发-按键长按_单击_双击

interrupt.h

#ifndef __BSP_INT
#define __BSP_INT
#include "main.h"

struct key{
  uint8_t key_single_flag;//短按
  uint8_t key_double_flag;//双击
  uint8_t key_long_flag;//长按
  uint8_t key_status;//按键状态
  uint8_t key_judge;//用于消抖、判断
  uint8_t key_time;//用于长按键的判定
  uint8_t double_time;//用于双击间隔时间计时
  uint8_t double_scan_en;//用于启动双击计数的标识
};
//struct key keys[4]={0};
#endif

interrupt.c

#include "interrput.h"

struct key keys[4]={0};

/*定时器中断回调函数,用于每10ms扫描一次按键*/
/*
  @note:短按、长按、双击
  长按:按键被按下1000ms
  双击:第一次按键按下松开后进行检测
  单击:没有发生双击事件,单击触发
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim->Instance == TIM2){// 首先进行电平检测,其次进行消抖、按键判断
    /*PA0、PB0~PB2,按键按下时检测到的电平为低*/
    keys[0].key_status = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
    keys[1].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
    keys[2].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
    keys[3].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
    for(int i=0 ;i<4 ;i++){
      switch(keys[i].key_judge){
        case 0:
        {
          if(keys[i].double_scan_en){
            keys[i].double_time++;
            if(keys[i].double_time>=20){//单击触发
              keys[i].key_single_flag =1;
              keys[i].double_time=0;
              keys[i].double_scan_en = 0;//关闭双击判定
              break;
            }
          }
          if(keys[i].key_status == 0){
            keys[i].key_judge = 1;
          }
          break;
        }
        case 1://消抖检测
        {
          if(keys[i].double_scan_en && (keys[i].key_status == 0) && (keys[i].double_time<30)){//双击触发
              keys[i].double_time = 0;
              keys[i].double_scan_en = 0;
              keys[i].key_double_flag = 1;
              keys[i].key_judge = 3;//等待按键松开
              break;
          }
          
          if(keys[i].key_status == 0){//按键确定被按下:需要处理三种情况:按实现难易程度进行处理:先判断长按键->双击->单击
            keys[i].key_time = 0;
            keys[i].key_judge = 2;
          }else{//按键抖动
            keys[i].key_judge = 0;//重新检测
          }
          break;
        }
        case 2:
        {
          //长按键:每进入一次中断key_time++
          if(keys[i].key_status == 0){//按键仍被按住
            keys[i].key_time++;
            if(keys[i].key_time>=50){//长按触发
              keys[i].key_long_flag = 1;
              keys[i].key_time = 0;
              keys[i].key_judge = 3;//等待此按键松开
              break;
            }
          }else{//按键松开:判断是双击还是单击
            keys[i].double_scan_en = 1;//启动双击检测
            keys[i].key_judge = 0;//重新检测
          }
          break;
        }
        case 3:
        {
          if(keys[i].key_status == 1){
            keys[i].key_judge = 0;//按键松开,重新检测
          }
        }
      }
    }
  }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值