按键实现短按,长按(按下多少秒触发)等功能

实现流程

1:定义了7个按键对象,并且给这7个按键分配的了对应的7个触发事件(同一个按键的单
击和长按都属于不同按键对象)
2:按下按键->进入防抖->判断计数器返回的计数时间->根据时间来判断按键按下事件对应标志置1
3:process函数根据置 1 的事件,进入完成对应功能,把标志归 0 ,让按键的state = KEY_RESET或其他

.H

#ifndef  __KEY_H
#define  __KEY_H
#include "HAL_device.h" 
#include "HAL_conf.h"



typedef unsigned char 		uint8_t;
typedef unsigned short int 	uint16_t;
typedef unsigned int   		uint32_t;

#define  PIN_STATE(n)  GPIO_ReadInputDataBit(GPIOA, n)

enum key_state{  //定义按键状态
	UP	 = 0,
	DOWN = 1,
	KEY_RESET = 2,
	KEY_LONG_PRESS = 3,
	KEY_LOCK = 4
};

typedef struct event{  //按键需要触发的情况
	
	uint8_t set_click;  //当按键触发之后,就将此标志置1,代表此按键或者组合按键被触发
	uint8_t set_press_2s;
	uint8_t set_redc_press_3s;
	uint8_t set_redc_press_7s;
	uint8_t set_redc_click;
	uint8_t set_add_click;
	uint8_t freeze_clicked;
	uint8_t defrost_press_2s;
	uint8_t add_redc_press_3s;

}s_key_event;

typedef struct key_menber{  //按键对象类型
	uint16_t id;
	uint8_t state;
}s_key_m;

typedef struct key{  //按键的对象
	s_key_m key_1;
	s_key_m key_2;
	s_key_m key_3;
	s_key_m key_4;
	s_key_m key_23;
	s_key_m key_24;
	s_key_m key_34;
}s_key;


/******************************************/
void key_init(void);

void key_process(void);


#endif

#include  "key.h"
#include "counter_delay.h"
#include "stdio.h"

#define  ENTER_WAIT   60  //触发防抖延时
#define  BACK_WAIT    60  //退出防抖延时

#if 1
#define KEY_NUM  7  //定义按键数量
s_key key;  //按键结构体,存放所有按键
s_key_event 			key_event = {0}; //按键需要触发的事件

void key_state(void);

void key_init(void){	
	uint8_t i;
	s_key_m * ptr = NULL;
	ptr = (s_key_m *)&key;
	
	for(i = 0;i < KEY_NUM ;i++){  ///给按键分配Id
		(ptr+i)->id = (0xF1 + i);
		(ptr+i)->state = UP;
	}
	
}

void key_state(void){
//**************按键1	
	if( !PIN_STATE(GPIO_Pin_4)){
		//防抖延时
		if(key.key_1.state != KEY_RESET){
			if( timer_state(key.key_1.id) == TIMING_END){

				start_once_timer(DEFROST_PRESS_2S_ID , 8000, LOCK_TIMNG);
				key.key_1.state = DOWN;
			}
			else{
				start_timer(key.key_1.id,ENTER_WAIT,LOCK_TIMNG);
			}
		}
		if(key.key_1.state == DOWN){
			u32 count_value = timer_count_value(DEFROST_PRESS_2S_ID);
			if((count_value >= 2000)&&(count_value <= 8000)&&(show_state == Normal_show_state)){
				key_event.defrost_press_2s = 1;  //触发事件
				printf("按键2秒");
				BUZZER_ON(KEY_S);
				close_timer(DEFROST_PRESS_2S_ID, DESTROYED);
			}
		}
	}
	else{
		if(key.key_1.state == DOWN){ //松开按键,判断事件类型
			u32 counter = timer_count_value(DEFROST_PRESS_2S_ID);
			if(counter <= 500){
				key_event.freeze_clicked = 1; //触发事件
				BUZZER_ON(KEY_S)
				printf("制冷");
			}
			close_timer(DEFROST_PRESS_2S_ID,DESTROYED);
			key.key_1.state = UP;
		}

		key.key_1.state = UP;
		close_timer(key.key_1.id ,DESTROYED);  //挂起定时器
	}
//**************单点按键2
	if((!PIN_STATE(GPIO_Pin_5))&&(PIN_STATE(GPIO_Pin_6))&&(PIN_STATE(GPIO_Pin_7))){
		//设置防抖延时
		if(key.key_2.state != KEY_RESET){
			if( timer_state(key.key_2.id) == TIMING_END){ //进入事件计时
				start_once_timer(SET_KEY_EVENT_ID, 8000, LOCK_TIMNG);
				key.key_2.state = DOWN;
			}
			else{
				start_timer(key.key_2.id,ENTER_WAIT,LOCK_TIMNG);
			}
		}
		if(key.key_2.state == DOWN){
			u32 count_value = timer_count_value(SET_KEY_EVENT_ID);
			if((count_value >= 2000)&&(count_value <= 8000)&&(show_state == Normal_show_state)){
				key_event.set_press_2s = 1; //触发事件
				printf("仅设置键2S");
				BUZZER_ON(KEY_S)
				close_timer(SET_KEY_EVENT_ID, DESTROYED);
			}
		}
	}
	else{
		if((key.key_2.state == DOWN)&&(PIN_STATE(GPIO_Pin_6))&&(timer_state(BACK_PROTECT_TIME_ID) == DESTROYED)){ //松开按键,判断事件类型
			u32 count_value = timer_count_value(SET_KEY_EVENT_ID);
			if(count_value <= 500U){
				key_event.set_click = 1; //触发事件
				BUZZER_ON(KEY_S);
				printf("单击设置键");
			}
			close_timer(SET_KEY_EVENT_ID, DESTROYED);
		}
		key.key_2.state = UP;
		close_timer(key.key_2.id ,DESTROYED);  //挂起定时器
	}
#if 1
/****************/
	if( (!PIN_STATE(GPIO_Pin_5))&&(!PIN_STATE(GPIO_Pin_6))&&(PIN_STATE(GPIO_Pin_7))){
		//设置 (-) 防抖延时
		if(key.key_23.state != KEY_RESET){
			if( timer_state(key.key_23.id) == TIMING_END){ //进入事件计时
					start_once_timer(SET_REDC_PRESS_7S, 15000 , LOCK_TIMNG);
					key.key_23.state = DOWN;
			}
			else{
				start_timer(key.key_23.id,ENTER_WAIT,LOCK_TIMNG);
			}
		}
		if(key.key_23.state == DOWN){
			u32 counter = timer_count_value(SET_REDC_PRESS_7S);
			if((counter >= 3000)&&(counter <= 7000)&&(show_state == Normal_show_state)){
				key_event.set_redc_press_3s = 1; //触发事件
				printf("SET- 3");
				BUZZER_ON(KEY_S);
				close_timer(SET_REDC_PRESS_7S,DESTROYED);
			}
			else if((counter >= 7000)&&(show_state == Menu_show_state)){
				key_event.set_redc_press_7s = 1; //触发事件
				printf("SET- 7");
				BUZZER_ON(KEY_S);
				close_timer(SET_REDC_PRESS_7S,DESTROYED);
			}
		}
	}
	else{
		if(key.key_23.state == DOWN){ //松开按键,判断事件类型
			u32 counter = timer_count_value(SET_REDC_PRESS_7S);
			if(counter <= 500){
				key_event.set_redc_click = 1; //触发事件
				BUZZER_ON(KEY_S);
				printf("SET-");
			}
			close_timer(SET_REDC_PRESS_7S,DESTROYED);
			key.key_23.state = UP;
			start_once_timer(BACK_PROTECT_TIME_ID, 200, LOCK_TIMNG);
		}
		key.key_23.state = UP;
		close_timer(key.key_23.id ,DESTROYED);  //挂起定时器
	}
/****************/
	if( (!PIN_STATE(GPIO_Pin_5))&&(PIN_STATE(GPIO_Pin_6)&&(!PIN_STATE(GPIO_Pin_7)))){
		//设置 (+) 防抖延时
		if( timer_state(key.key_24.id) == TIMING_END){ //进入事件计时
				key.key_24.state = DOWN;
		}
		else{
			start_timer(key.key_24.id,ENTER_WAIT,LOCK_TIMNG);
		}
	}
	else{
		if(key.key_24.state == DOWN){ //松开按键,判断事件类型
				key_event.set_add_click = 1; //触发事件
				printf("SET+");
				BUZZER_ON(KEY_S);
				start_once_timer(BACK_PROTECT_TIME_ID, 200, LOCK_TIMNG);
		}
		key.key_24.state = UP;
		close_timer(key.key_24.id ,DESTROYED);  //挂起定时器
	}
#endif
//**************按键3	
	if( (!PIN_STATE(GPIO_Pin_6))&&(PIN_STATE(GPIO_Pin_5))){
		//减少防抖延时
		if((key.key_3.state != KEY_RESET)&&(key.key_3.state != KEY_LONG_PRESS)){
			if( timer_state(key.key_3.id) == TIMING_END){
				key.key_3.state = DOWN;
				BUZZER_ON(KEY_S);
				close_timer(key.key_3.id ,DESTROYED);  //挂起定时器
			}
			else{
				start_timer(key.key_3.id,ENTER_WAIT,LOCK_TIMNG);
			}
		}
		else if(key.key_3.state == KEY_RESET){
			if(timer_state(RDC_LONG_PRESS_ID) == TIMING_END){
				if((show_state == Set_show_state)||(show_state == Set_temp_show_state)){  //只有设置数值才支持长按
					key.key_3.state = KEY_LONG_PRESS;
				}
				close_timer(RDC_LONG_PRESS_ID,DESTROYED);
			}
			else{
				start_timer(RDC_LONG_PRESS_ID, 700, LOCK_TIMNG);
			}
		}
		else if(key.key_3.state == KEY_LONG_PRESS){
			delay_ms(90);
		}
	}
	else{
		key.key_3.state = UP;
		close_timer(RDC_LONG_PRESS_ID,DESTROYED);
		close_timer(key.key_3.id ,DESTROYED);  //挂起定时器
	}
//**************按键4	
	if( (!PIN_STATE(GPIO_Pin_7))&&(PIN_STATE(GPIO_Pin_5))){
		//增加防抖延时
		if((key.key_4.state != KEY_RESET)&&(key.key_4.state != KEY_LONG_PRESS)){
			if( timer_state(key.key_4.id) == TIMING_END){
				key.key_4.state = DOWN;
				BUZZER_ON(KEY_S);
				close_timer(key.key_4.id ,DESTROYED);  //销毁定时器
			}
			else{
				start_timer(key.key_4.id,ENTER_WAIT,LOCK_TIMNG);
			}
		}
		else if(key.key_4.state == KEY_RESET){
			if(timer_state(ADD_LONG_PRESS_ID) == TIMING_END){
				if((show_state == Set_show_state)||(show_state == Set_temp_show_state)){  //只有设置数值才支持长按
					key.key_4.state = KEY_LONG_PRESS;
				}
				close_timer(ADD_LONG_PRESS_ID,DESTROYED);
			}
			else{
				start_timer(ADD_LONG_PRESS_ID, 700, LOCK_TIMNG);
			}
		}
		else  if(key.key_4.state == KEY_LONG_PRESS){
			delay_ms(90);
		}
	}
	else{
		key.key_4.state = UP;
		close_timer(ADD_LONG_PRESS_ID,DESTROYED);
		close_timer(key.key_4.id ,DESTROYED);  //销毁定时器
	}
/******锁屏按键组合********/
	if((!PIN_STATE(GPIO_Pin_6))&&(!PIN_STATE(GPIO_Pin_7))&&(PIN_STATE(GPIO_Pin_5))){
		if(timer_state(key.key_34.id) == TIMING_END){
			start_once_timer(ADD_REDC_PRESS_ID,3400,LOCK_TIMNG);
			key.key_34.state = DOWN;
		}
		else{
			start_timer(key.key_34.id, ENTER_WAIT, LOCK_TIMNG);
		}
		if(key.key_34.state == DOWN){
			u32 count = timer_count_value(ADD_REDC_PRESS_ID);
			if(count >=3000){
				key_event.add_redc_press_3s = 1; //触发事件
				BUZZER_ON(KEY_S);
				close_timer(ADD_REDC_PRESS_ID, DESTROYED);
			}
		}
	}
	else{
		key.key_34.state = UP;
		close_timer(key.key_34.id, DESTROYED);
		close_timer(ADD_REDC_PRESS_ID, DESTROYED);
	}
}

void key_process(void){
	key_state(); //按键状态读取
	//进入按键任务
#if 1
	if((key.key_4.state == DOWN)||(key.key_4.state == KEY_LONG_PRESS)){  //支持数字长按连续切换的按键
		//printf("+键 ");
		/**功能代码区-BEGAIN-**/
		
		/**功能代码区-END-**/
		if(key.key_4.state != KEY_LONG_PRESS){
			key.key_4.state = KEY_RESET;
		}
		start_timer(key.key_4.id,BACK_WAIT,LOCK_TIMNG); //退出防抖
	}
	if((key.key_3.state == DOWN)||(key.key_3.state == KEY_LONG_PRESS)){  //支持数字长按连续切换的按键
		//printf("-键 ");
		/**功能代码区-BEGAIN-**/
		
		/**功能代码区-END-**/
		if(key.key_3.state != KEY_LONG_PRESS){
			key.key_3.state = KEY_RESET;
		}
		start_timer(key.key_3.id,BACK_WAIT,LOCK_TIMNG); //退出防抖
	}

	
#endif

	
#if 1

//设置按键------------------------------------------------------------------------/
	if(key_event.set_click){  //点击事件
		/**功能代码区-BEGAIN-**/

		/**功能代码区-END-**/

		key.key_2.state = KEY_RESET;//防止连续触发		
		key_event.set_click = 0;
		close_timer(BACK_NORMAL_ID, TIM_SUSPEND); //关掉无响应退出定时器
	}
	if(key_event.set_press_2s){
		/**功能代码区-BEGAIN-**/

		/**功能代码区-END-**/

		key.key_2.state = KEY_RESET;//防止连续触发		
		key_event.set_press_2s = 0;
		close_timer(BACK_NORMAL_ID, TIM_SUSPEND); //关掉无响应退出定时器
	}
	if(key_event.set_redc_press_3s){
		/**功能代码区-BEGAIN-**/

		/**功能代码区-END-**/

		key.key_23.state = KEY_RESET;
		key_event.set_redc_press_3s = 0;
		close_timer(BACK_NORMAL_ID, TIM_SUSPEND); //关掉无响应退出定时器
	}
	if(key_event.set_redc_press_7s){
		/**功能代码区-BEGAIN-**/

		/**功能代码区-END-**/

		key.key_23.state = KEY_RESET;
		key_event.set_redc_press_7s = 0;
		close_timer(BACK_NORMAL_ID, TIM_SUSPEND); //关掉无响应退出定时器
	}
	if(key_event.set_redc_click){
		/**功能代码区-BEGAIN-**/

		/**功能代码区-END-**/

		key.key_23.state = KEY_RESET;
		key_event.set_redc_click = 0;
		close_timer(BACK_NORMAL_ID, TIM_SUSPEND); //关掉无响应退出定时器
	}
	if(key_event.set_add_click){
		/**功能代码区-BEGAIN-**/

		/**功能代码区-END-**/

		key.key_24.state = KEY_RESET;
		key_event.set_add_click = 0;
	}
/*---------------------------------------------------------*/	

#endif
	if(key_event.freeze_clicked == 1){
		//printf("制冷键 ");
		/**功能代码区-BEGAIN-**/
		
		/**功能代码区-END-**/
		key_event.freeze_clicked = 0;
		key.key_1.state = KEY_RESET;
		start_timer(key.key_1.id,BACK_WAIT,LOCK_TIMNG); //退出防抖
	}
	if(key_event.defrost_press_2s == 1){
		/**功能代码区-BEGAIN-**/

		/**功能代码区-END-**/
		key_event.defrost_press_2s = 0;
		key.key_1.state = KEY_RESET;
		start_timer(key.key_1.id,BACK_WAIT,LOCK_TIMNG); //退出防抖
	}
	if(key_event.add_redc_press_3s){
		/**功能代码区-BEGAIN-**/

		/**功能代码区-END-**/
		key_event.add_redc_press_3s = 0;
		key.key_34.state = KEY_RESET;
	}
}

#endif

文章中的 start_timer()等接口是我的其它文章中的代码,可以参考我的文章,单片机软件定时器V2.0

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于Python中同一个按键短按按的实现,可以使用模块`keyboard`来完成。具体实现如下: 首先,需要安装`keyboard`模块,可以通过以下命令来安装: ``` pip install keyboard ``` 然后,可以使用`keyboard`模块中的`add_hotkey`函数来注册快捷键,并设置不同的按键事件回调函数来实现按键短按事件。例如,下面的代码实现按下'A'键短按按的不同效果: ``` import keyboard import time def short_press(): print('short press') def long_press(): print('long press') keyboard.add_hotkey('a', short_press) keyboard.add_hotkey('a', long_press, args=[], trigger_on_release=True, long_press_duration=0.5) while True: time.sleep(1) ``` 在上面的代码中,我们首先定义了两个回调函数`short_press`和`long_press`,分别用于处理'A'键的短按事件。然后,通过`keyboard`模块中的`add_hotkey`函数来注册快捷键,第一个参数为要监听的按键,第二个参数为按键事件回调函数。其中,`short_press`函数是默认的短按事件回调函数,`long_press`函数是事件回调函数,`args=[]`用于传递额外的参数给回调函数,`trigger_on_release=True`表示事件按键松开时触发,`long_press_duration=0.5`表示按键按下超过0.5触发事件。 最后,通过一个无限循环来保持程序的运行。这样,当用户按下'A'键时,根据按下的时间短,就会调用不同的事件回调函数来处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漏洞百出

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值