基于定时器中断扫描检测按键状态(单击,双击,长按),已消抖,不需延时等待,带详细注释

您所在的位置:网站首页 怎么判断键盘有没有灯 基于定时器中断扫描检测按键状态(单击,双击,长按),已消抖,不需延时等待,带详细注释

基于定时器中断扫描检测按键状态(单击,双击,长按),已消抖,不需延时等待,带详细注释

2023-12-20 18:53| 来源: 网络整理| 查看: 265

代码:

按键状态结构体声明

typedef struct{ uint8_t key_up; uint8_t key_down; uint8_t key_left; uint8_t key_right; }KEY_STATE;

按键状态结构体声明

KEY_STATE Key={0}; //定义时将整个结构体初始化为0

四个按键的扫描检测程序,在10ms的定时器中断里执行该函数即可

void KEY_DETECTION(KEY_STATE* key){ static uint16_t up_cnt=0,down_cnt=0,left_cnt=0,right_cnt=0; static uint8_t up_bit=0,down_bit=0,left_bit=0,right_bit=0; if(key->key_up==0){ if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET && up_bit==0){ //首次检测按下 up_bit=1; up_cnt=0; } else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==GPIO_PIN_SET && up_bit==1){ //消抖阶段 up_cnt++; if(up_cnt==3){ up_cnt=0; up_bit=2; } } else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==GPIO_PIN_RESET && up_bit==1){//干扰 up_cnt=0; up_bit=0; } else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==GPIO_PIN_SET && up_bit==2){ //检测首次按下时长 up_cnt++; if(up_cnt > 65){ //按下大于650ms未抬起 up_cnt=0; up_bit=5; } } else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==GPIO_PIN_RESET && up_bit==5){ //长按后等待松开 up_cnt=0; up_bit=0; key->key_up=3; //长按 printf("up长按\r\n"); } else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==GPIO_PIN_RESET && up_bit==2 && up_cnt //监测首次按下抬起后250ms内按键是否再次按下 up_cnt++; if(up_cnt > 25){ //距离首次按下抬起 大于250ms 没有动作 up_bit=0; up_cnt=0; key->key_up=1; //单击 printf("up单击\r\n"); } } else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==GPIO_PIN_SET && up_bit==3 && up_cnt //双击后等待松开 up_bit=0; up_cnt=0; key->key_up=2; //双击 printf("up双击\r\n"); } } if(key->key_down==0){ if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET && down_bit==0){ //首次检测按下 down_bit=1; down_cnt=0; } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3)==GPIO_PIN_RESET && down_bit==1){ //消抖阶段 down_cnt++; if(down_cnt==3){ down_cnt=0; down_bit=2; } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3)==GPIO_PIN_SET && down_bit==1){//干扰 down_cnt=0; down_bit=0; } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3)==GPIO_PIN_RESET && down_bit==2){ //检测首次按下时长 down_cnt++; if(down_cnt > 65){ //按下大于650ms未抬起 down_cnt=0; down_bit=5; } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3)==GPIO_PIN_SET && down_bit==5){ //长按后等待松开 down_cnt=0; down_bit=0; key->key_down=3; //长按 printf("down长按\r\n"); } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3)==GPIO_PIN_SET && down_bit==2 && down_cnt //监测首次按下抬起后250ms内按键是否再次按下 down_cnt++; if(down_cnt > 25){ //距离首次按下抬起 大于250ms 没有动作 down_bit=0; down_cnt=0; key->key_down=1; //单击 printf("down单击\r\n"); } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3)==GPIO_PIN_RESET && down_bit==3 && down_cnt //双击后等待松开 down_bit=0; down_cnt=0; key->key_down=2; //双击 printf("down双击\r\n"); } } if(key->key_left==0){ if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == GPIO_PIN_RESET && left_bit==0){ //首次检测按下 left_bit=1; left_cnt=0; } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2)==GPIO_PIN_RESET && left_bit==1){ //消抖阶段 left_cnt++; if(left_cnt==3){ left_cnt=0; left_bit=2; } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2)==GPIO_PIN_SET && left_bit==1){//干扰 left_cnt=0; left_bit=0; } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2)==GPIO_PIN_RESET && left_bit==2){ //检测首次按下时长 left_cnt++; if(left_cnt > 65){ //按下大于650ms未抬起 left_cnt=0; left_bit=5; } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2)==GPIO_PIN_SET && left_bit==5){ //长按后等待松开 left_cnt=0; left_bit=0; key->key_left=3; //长按 printf("left长按\r\n"); } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2)==GPIO_PIN_SET && left_bit==2 && left_cnt //监测首次按下抬起后250ms内按键是否再次按下 left_cnt++; if(left_cnt > 25){ //距离首次按下抬起 大于250ms 没有动作 left_bit=0; left_cnt=0; key->key_left=1; //单击 printf("left单击\r\n"); } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2)==GPIO_PIN_RESET && left_bit==3 && left_cnt //双击后等待松开 left_bit=0; left_cnt=0; key->key_left=2; //双击 printf("left双击\r\n"); } } if(key->key_right==0){ if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4) == GPIO_PIN_RESET && right_bit==0){ //首次检测按下 right_bit=1; right_cnt=0; } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)==GPIO_PIN_RESET && right_bit==1){ //消抖阶段 right_cnt++; if(right_cnt==3){ right_cnt=0; right_bit=2; } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)==GPIO_PIN_SET && right_bit==1){//干扰 right_cnt=0; right_bit=0; } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)==GPIO_PIN_RESET && right_bit==2){ //检测首次按下时长 right_cnt++; if(right_cnt > 65){ //按下大于650ms未抬起 right_cnt=0; right_bit=5; } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)==GPIO_PIN_SET && right_bit==5){ //长按后等待松开 right_cnt=0; right_bit=0; key->key_right=3; //长按 printf("right长按\r\n"); } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)==GPIO_PIN_SET && right_bit==2 && right_cnt //监测首次按下抬起后250ms内按键是否再次按下 right_cnt++; if(right_cnt > 25){ //距离首次按下抬起 大于250ms 没有动作 right_bit=0; right_cnt=0; key->key_right=1; //单击 printf("right单击\r\n"); } } else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)==GPIO_PIN_RESET && right_bit==3 && right_cnt //双击后等待松开 right_bit=0; right_cnt=0; key->key_right=2; //双击 printf("right双击\r\n"); } } }

按键的状态存储到按键状态结构中 各状态对应值为: 0:没有任何事件发生 1:单击 2:双击 3:长按

使用时判断该结构体中各按键对应的变量值即可 如果有相应按键事件触发,请务必将结构体中相对应的按键状态值及时清零,否则不会再次触发该按键的状态检测



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3