按键KEY 单击、双击、长按检测

/**************************************************************************
函数功能:按键扫描
入口参数:双击等待时间
返回 值:按键状态 0:无动作 1:单击 2:双击
*************************************************************************/
/

3个计数值:只要按键按下 ,Forever_count就会计数,松开就清零
第一次按键按下之后,count_single才会计数
count_key像是为了协助,能在一次按键按下之后同时实现 1.double++ 以及 double_key是否等于2
按键按下一次之后,double_key = 1,再次进入循环的时候,count_single就会一直累加,当count_single加到time值时(即超过了设定的时间间隔)
那么就判定为单击。如果在count_single累加且未到time的过程中,再次松开按下,则认为按下两次,双击。每次按下就会有Forever_count累加
一松开就为0,所以如果Forever_count加到了我们设定的值,就是长按,就返回0

*/

u8 click_N_Double (u8 time)
{
static u8 flag_key,count_key,double_key; //按键按下一次标志位,按下的次数计数值,两次标志位
static u16 count_single,Forever_count; //按键按下一次之后一直计数值, 每次按键按下之后一直计数值,按键一旦松开就清0
// count_single是从按键按下第一次之后才计数,按键,Forever_count是只要
if(KEY0 == 0) Forever_count++;
else Forever_count = 0;
if(KEY0 == 0 && flag_key == 0) flag_key = 1;//则为按键按下

if(count_key == 0)     //按键按下的次数计数    如果按键松开了(上一次检测时只要按键松开了,这个标志位就清零,说明松开的)
{
	if(flag_key == 1)   								//单击一次进去一次
	{
		double_key++;
		count_key = 1;
	}	
	//按键松开时,double_key是2说明按下了两次
	if(double_key == 2)									 //判断双击
	{
		double_key = 0;
		count_single = 0;
		return 2;
	}
}
if(KEY0 == 1)	flag_key=0 , count_key=0;//在进行判断有没有按下第二次时要先判断有没有松开,松开则清除标志位和计数值

if(double_key == 1)
{
	count_single++;    //按键按下一次以后就一直计数
	//判断设定的时间间隔与计数值
	if(count_single > time && Forever_count < time) 	//中间间隔时间太长 判断为的单击   Forever_count<time<count_single
	{
		double_key=0;
		flag_key=0;
		return 1;
	}
	//如果按键按下的值已经超过了我们设定的时间
	if(Forever_count > time)                             //长按不放
	{
		double_key=0;
		count_single=0;	
	}
}
return 0;

}

/**************************************************************************
函数功能:按键扫描
入口参数:无
返回 值:按键状态 0:无动作 1:单击
**************************************************************************/
u8 click(void)
{
static u8 key_up_flag; //按键松开标志
if(key_up_flag==1 && KEY0 == 0)
{
delay_ms(10);
if(KEY0 == 0)
{
key_up_flag = 0;
return 1;
}
else if(1 == KEY0) key_up_flag =1;
return 0;
}
}

/**************************************************************************
函数功能:长按检测
入口参数:无
返回 值:按键状态 0:无动作 1:长按2s
**************************************************************************/
u8 Long_Press(void)
{
static u16 Long_Press_count,Long_Press;
if(Long_Press == 0 && KEY0 == 0)
{
delay_ms(10);
if(KEY0 == 0)
{
Long_Press_count++;
}

}
	
else    
	Long_Press_count = 0;
if(Long_Press_count > 200)
{
	Long_Press_count = 0; 
	Long_Press = 1;
	return 1;
}
if(Long_Press == 1)
	Long_Press = 0;
return 0;

}

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C 语言中,实现按键单击双击按可以通过轮询检测按键状态和计时器来实现。具体的实现步骤如下: 1. 定义按键状态枚举值: ```c typedef enum { KEY_IDLE, // 按键空闲状态 KEY_DOWN, // 按键按下状态 KEY_UP, // 按键松开状态 KEY_LONG, // 按状态 KEY_DOUBLE, // 双击状态 } key_state_t; ``` 2. 定义按键结构体: ```c typedef struct { key_state_t state; // 当前按键状态 uint32_t time; // 当前按键计时器值 uint8_t click_count; // 点击次数 } key_t; ``` 3. 实现按键扫描函数,该函数会返回按键状态: ```c key_state_t scan_key() { static key_t key = {KEY_IDLE, 0, 0}; key_state_t state = KEY_IDLE; uint8_t key_value = get_key_value(); // 获取按键值 switch (key.state) { case KEY_IDLE: if (key_value == 0) { key.state = KEY_DOWN; key.time = get_tick_count(); } break; case KEY_DOWN: if (key_value == 0) { uint32_t elapsed_time = get_tick_count() - key.time; if (elapsed_time >= LONG_PRESS_TIME) { key.state = KEY_LONG; state = KEY_LONG; } } else { key.state = KEY_UP; key.time = get_tick_count(); } break; case KEY_UP: if (key_value == 0) { uint32_t elapsed_time = get_tick_count() - key.time; if (elapsed_time <= DOUBLE_PRESS_TIME) { key.click_count++; if (key.click_count == 2) { key.state = KEY_DOUBLE; state = KEY_DOUBLE; } else { key.state = KEY_DOWN; key.time = get_tick_count(); } } else { key.state = KEY_DOWN; key.time = get_tick_count(); } } else { key.state = KEY_IDLE; key.click_count = 0; } break; case KEY_LONG: if (key_value == 1) { key.state = KEY_IDLE; } break; case KEY_DOUBLE: if (key_value == 1) { key.state = KEY_IDLE; } break; } return state; } ``` 4. 在主程序中轮询检测按键状态: ```c while (1) { key_state_t state = scan_key(); switch (state) { case KEY_DOWN: // 处理按键单击事件 break; case KEY_LONG: // 处理按键按事件 break; case KEY_DOUBLE: // 处理按键双击事件 break; } } ``` 其中,`get_key_value()` 函数用于获取当前按键状态(按下或松开),`get_tick_count()` 函数用于获取当前的计时器值。`LONG_PRESS_TIME` 和 `DOUBLE_PRESS_TIME` 分别表示按时间和双击时间的阈值,可以根据实际需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值