STM32G431RBT6按键判断(定时器实现)(单击,长按和双击)

sssssw

单次响应:

        我们在使用stm32的时候,常常会用到按键操作,用按键实现我们逻辑功能。但开发板上的机械按键常常会遇到机械抖动,我们都知道要用到HAL_Delay操作实现按键消抖,但这样在循环中使用延时操作,使单片机在主循环中的运行效率大大下降,不利于程序的运行。所以我们采用定时器的操作实现,按键消抖。

struct keys{
	bool key_sta;
	bool key_judge_sta;
	bool key_single_press;
};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM6)
	{
		key[0].key_sta = KEY1;
		key[1].key_sta = KEY2;
		key[2].key_sta = KEY3;
		key[3].key_sta = KEY4;
		for(int i=0;i<4;i++)
		{
			switch(key[i].judge_sta)
			{
				case 0:
					if(key[i].key_sta == 0) key[i].judge_sta=1;
                    break;
				case 1:
					if(key[i].key_sta == 0) key[i].single_flag = 1, key[i].judge_sta = 0;
                    break;
			}
		}
	}
}

        将定时器设置为10ms的中断,每进入一次循环,都会将四个按键的状态获取一遍,进入for循环,将四个按键的所有状态遍历,当key[1].key_sta=0时,意味着按键被按下,但此时我们并不确定是不是,抖动所致,所以设置了key[1].judge_sta变量,用于判断按键是否在下一个10ms中,是否还为0,如果是,那么key[1].single_sta置1,此次按键被响应。

长按响应:

        在使用中,通常会出现,多个不同的响应,而我们的按键数量有限,如果只用单次响应,无法实现一个按键控制多个任务。这里我们想要实现长按响应,顾名思义,它的意思是通过长时间按键控制所要控制的事情。

struct keys{
	unsigned char judge_sta;
	bool key_sta;
    bool single_down_flag;
	bool long_flag;
	int key_time;
};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM6)
	{
		key[0].key_sta = KEY1;
		key[1].key_sta = KEY2;
		key[2].key_sta = KEY3;
		key[3].key_sta = KEY4;
		
		for(int i=0;i<4;i++)
		{
			switch(key[i].judge_sta)
			{
				case 0:
					if(key[i].key_sta == 0) key[i].judge_sta=1;
				    break;
				case 1:
					if(key[i].key_sta == 0)
					{
						key[i].single_down_flag = 1;
						key[i].judge_sta = 2;
					}
					break;
				case 2:
					if(key[i].key_sta == 1)
					{
						if(key[i].key_time > 70){key[i].long_flag = 1;}
						key[i].key_time = 0;
						key[i].judge_sta = 0;
					}
					else key[i].key_time++;
					break;
			}
		}
	}
}

        在数组里面,我们定义了key_time和long_flag变量,其中key_time用来计我们按下去的时间,long_flag用来标记我们长按的标志位。在我们按下按键时,首先会进入到case 0 和 case 1,当我们按键未被抬起的时候,则会进入到case 2的else分支,key[i].key_time++。每10ms执行一次。当按键抬起后, 进入if分支后,判断key[i].key_time是否 > 70,如果大于70,则意味着按下的时间大于700ms,我们判断为长按。key[i].long_flag置1。

双击响应:

双击响应的核心在于要记录按下和下次按下的时间,只有两次按下的时间差满足一定条件的时候,双击响应才会触发。

struct keys{
	unsigned char judge_sta;
	bool key_sta;
	bool double_key_flag;
	uint32_t key_double_time;
};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM6)
	{
		key[0].key_sta = KEY1;
		key[1].key_sta = KEY2;
		key[2].key_sta = KEY3;
		key[3].key_sta = KEY4;
		
		for(int i=0;i<4;i++)
		{
			switch(key[i].judge_sta)
			{
				case 0:
					if(key[i].key_sta == 0) key[i].judge_sta=1;
				    break;
				case 1:
					if(key[i].key_sta == 0)
					{
						key[i].single_down_flag = 1;
						key[i].judge_sta = 2;
						if(key[i].key_double_time < 30) key[i].double_key_flag= 1;
						key[i].key_double_time = 0;
					}else key[i].judge_sta = 0;
					break;
				case 2:
					if(key[i].key_sta == 1)
					{				
						key[i].judge_sta = 0;
					}
					break;
			}
		key[i].key_double_time++;
		}
	}
}

我们定义了key_double_time和double_key_flag两个变量,分别用来表示,双击空闲时间和双击是否被触发。 每遍历一次循环,key[i].key_double_time++,每当按键按下的时候,key[i].key_double_time会置为0,如果下次按键按下时,两次的时间间隔不超过300ms,就意味着双击按键被响应,double_key_flag置1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值