一种多按键扫描方法(短按、长按、组合键)

**前言:**本文仅为个人简单记录,文章格式不做处理(等有时间再整理吧)。文章内容仅供参考,若有更好的想法,或者有疑问欢迎在评论留言。

正片:
关于按键扫描、按键处理网上有很多文章,本文提供了一个不同IO、按键判断方法不同的多按键扫描处理方法(有缺陷)。

应用场景:
1、按键数量不多,如4、5个。
2、按键IO口分布在不同P口(如P1、P2、PA、PB等)。
3、按键识别方式不一(上拉、下拉、ADC检测)。
4、按键短按、短按释放、长按、长按释放判断。
5、组合键判断。
如上述情景下,矩阵按键扫描显然不适用,每个按键单独消抖判段,程序又会庞杂,不精炼。

整体思想:
1、为每个按键定义一个键码值。键码值以8、4、2、1形式编码,
2、使用定时器,定时扫描按键,多次扫描消抖。
3、由于是定时扫描,则在按键扫描函数里计数,即可用来做按键按下时长判断,从而判断按键长按、短按。

下面提供按键处理参考代码(懒得区分文件了)。

//枚举按键键码
typedef enum ENUM_KEY_CODE
{
  E_KEY_CODE_NONE = 0,
  E_KEY_CODE_MENU = 0x01,
  E_KEY_CODE_INC = 0x02,//加-上
  E_KEY_CODE_DEC = 0x04,//减-下
  E_KEY_CODE_OK = 0x08,
  E_KEY_CODE_POWER = 0x10,
  //。。。
} E_KEY_CODE;
//枚举按键状态
typedef enum ENUM_KEY_EVENT
{
  E_KEY_EVT_NONE = 0,
  E_KEY_EVT_SHORT_PRESS,
  E_KEY_EVT_SHORT_RELEASE,
  E_KEY_EVT_LONG_PRESS,
  E_KEY_EVT_LONG_RELEASE,
  E_KEY_EVT_TIMEOUT,	//按键超时
} E_KEY_EVENT;

//全局变量
uint8_t KEY_Code = E_KEY_CODE_NONE;	//按键键码
uint8_t KEY_Evt = E_KEY_EVT_NONE;	//按键状态


void KeyScan()
{
	// 20ms进行按键扫描
	static uint8_t KeyCode_New = E_KEY_CODE_NONE; //新的按键值
	static uint8_t KeyCode_Old = E_KEY_CODE_NONE; //旧的按键值
	static uint8_t Key_count = 0;	 //消抖计数
	static uint8_t KeyTimeCnt = 0; //按键按下时间计数

	/*
	对应按键按下或释放判断,可根据实际情况(上拉下拉,或者时ADC口),
	按键按下则 对应键码置1,
	按键释放则 对应键码清零
	*/
	//菜单键
	if (MENU_KEY_TRUE)
		KeyCode_New |= E_KEY_CODE_MENU;
	else
		KeyCode_New &= ~E_KEY_CODE_MENU;
	// OK键
	if (KEY_OK_TRUE)
		KeyCode_New |= E_KEY_CODE_PTT;
	else
		KeyCode_New &= ~E_KEY_CODE_PTT;
	//下
	if (KEY_DOWN_TRUE)
		KeyCode_New |= E_KEY_CODE_DEC;
	else
		KeyCode_New &= ~E_KEY_CODE_DEC;
	//上
	if (KEY_UP_TRUE)
		KeyCode_New |= E_KEY_CODE_INC;
	else
		KeyCode_New &= ~E_KEY_CODE_INC;
	// Power
	if (KEY_POWER_TRUE)
		KeyCode_New |= E_KEY_CODE_POWER;
	else
		KeyCode_New &= ~E_KEY_CODE_POWER;

	//通过判断当前键码与上一次保存的键码是否相同来消抖,
	//如果不同则更新键码值,清除计数变量,
	if (KeyCode_New != KeyCode_Old)
	{
		KeyCode_Old = KeyCode_New;
		Key_count = 0;
		// KeyTimeCnt = 0;
	}
	else	//键码值相同
	{
		Key_count++; //消抖计数

		if (Key_count >= 3) //按键值相同,且连加3次   消抖时间3*20mS =60mS
		{
			Key_count = 3;

			if (KeyCode_Old != E_KEY_CODE_NONE) //按键值不为空
			{
				if (KeyTimeCnt < 250)
					KeyTimeCnt++; //按键时间计数

				if (KeyTimeCnt == 1) // 立马指示按下,KEY_Evt 只置位一次
				{
					ioKeyEvt = 1;
					KEY_Code = KeyCode_Old;
					KEY_Evt = E_KEY_EVT_SHORT_PRESS; //按下
				}
				else
				{
					if (KeyTimeCnt == 33) //指示长按,KEY_Evt只置位一次
					{
						ioKeyEvt = 2;
						KEY_Evt = E_KEY_EVT_LONG_PRESS; //长按
					}
				}
			}
			else //所有按键释放
			{
				if (ioKeyEvt == 1)
				{
					KEY_Evt = E_KEY_EVT_SHORT_RELEASE; //短按释放
				}
				else 
				{
					if (ioKeyEvt == 2)
						KEY_Evt = E_KEY_EVT_LONG_RELEASE; //长按释放
				}
				ioKeyEvt = 0;
				KeyTimeCnt = 0;
			}
		}
	}
}
//按键处理函数
void KEY_FUN()
{
	switch (KEY_Code)
	{
	case E_KEY_CODE_NONE:

		break;
	case E_KEY_CODE_POWER:
		if (KEY_Evt == E_KEY_EVT_SHORT_PRESS) 		
		{
		}
		else if (KEY_Evt == E_KEY_EVT_SHORT_RELEASE) //按键短按释放
		{
		}
		else if (KEY_Evt == E_KEY_EVT_LONG_PRESS) 	//按键长按
		{
		}
		else //按键长按释放
		{
		}
		break;
	case E_KEY_CODE_MENU:
		//同上
		break;
	case E_KEY_CODE_INC:
		//同上上
		break;
	case E_KEY_CODE_DEC:
		//同上上上
		break;
	case E_KEY_CODE_PTT:
		//同上上上上
		break;

	default: //组合键,组合键功能可根据需要自行设置,可增加组合键的键码

		if (KEY_Evt == E_KEY_EVT_SHORT_PRESS) 		//按键按下
		{
		}
		else if (KEY_Evt == E_KEY_EVT_SHORT_RELEASE) //按键短按释放
		{
		}
		else if (KEY_Evt == E_KEY_EVT_LONG_PRESS) 	//按键长按
		{
		}
		else //按键长按释放
		{
		}
		break;
	}
}
uint8_t TIME_20MS_FLAG = 0;
//伪代码
void TIME_20mS_IRQ()	//定时器中断函数
{
	TIME_20MS_FLAG = 1;
}

void main()
{
	//定时器初始化
	while(1)
	{
	//定时中断中将标志置1,按键扫描一次时间 20MS
		if(TIME_20MS_FLAG == 1)
		{
			KeyScan();
			if (KEY_Evt != E_KEY_EVT_NONE)
			{
				KEY_FUN();
				KEY_Evt = E_KEY_EVT_NONE;
			}
			TIME_20MS_FLAG = 0;
		}
	}
}

//上述方法还是有些缺陷的,不过已经能满足基本的按键长短按判断,及简单组合键的判断。

//最后,希望对看到本文的你有些帮助。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: stm32是一款嵌入式微控制器,具有多达数十个GPIO口。在使用它来控制花样彩灯时,可以利用这些GPIO口来实现单击、双击、短按按和组合键等多种控制方式。 对于单击和双击的控制方式,可以通过对GPIO口进行中断编程的方式来实现。当单击或双击时,通过读取GPIO口的状态来判断按键的动作并做出相应的操作。 短按按的控制方式可以利用定时器产生定时中断实现。通过设置定时器的计数周期和中断时间,来判断按键按下的时间短,从而分别实现短按按的控制。 除了以上基本的控制方式,还可以通过组合键的方式实现更多的控制方法。例如,通过同时按下两个或多个按键,来实现多种操作的组合键控制。 最终在程序设计时,需要将以上所有的控制方式进行整合,使其结合起来,来实现更加灵活、多样的花样彩灯控制。因此,对于单击、双击、短按按和组合键等控制方式的实现,需要在编程设计中将它们有机地结合起来,以实现更加丰富和灵活的控制。 ### 回答2: STM32是一款微控制器,其支持多种按键控制方式,包括单击、双击、短按按和组合键等。利用这些控制方式,我们可以在STM32上实现花样彩灯的控制。 单击控制可以让灯在各种颜色之间切换,双击控制可以让灯的颜色快速变化,短按控制可以让灯的亮度调节,按控制则可以开启或关闭灯。 同时,我们还可以实现组合键控制,例如:双击+短按可以让灯维持在某一特定的颜色,按+短按可以将灯的颜色复位等。 通过这些控制方式的运用,可以让花样彩灯实现更加多样化的效果,丰富了灯的功能性和趣味性。同时,STM32作为一款高性能的微控制器,还可以实现更加复杂的功能控制,根据实际需要,我们可以利用其提供的功能,加入更多有趣的控制方式,让灯的效果更加丰富多彩。 ### 回答3: STM32是一种单片微控制器,它具有丰富的功能和灵活的控制能力。在进行花样彩灯的控制时,可以利用STM32的不同点击方式来实现不同的操作。其中,单击可以控制灯的开关,双击可以切换灯的颜色,短按可以调节亮度,按可以切换灯的模式,组合键可以实现更为复杂的操作。 要实现这些控制功能,需要在STM32中编写相应的程序。具体实现步骤如下: 1. 定义输入引脚:首先需要设置花样彩灯的各种控制引脚。可以将单击、双击、短按按和组合键分别定义为不同的输入引脚。 2. 编写中断程序:在STM32中,可以利用中断程序来处理各种输入事件。可以编写不同的中断程序来处理单击、双击、短按按和组合键等事件。 3. 实现各种控制功能:根据不同的输入事件,可以实现各种不同的控制功能。比如,单击可以控制灯的开关,双击可以切换灯的颜色,短按可以调节亮度,按可以切换灯的模式,组合键可以实现更为复杂的操作。 4. 调试和优化:在实现控制功能后,需要进行调试和优化,确保程序能够正常运行,并且能够满足各种不同的控制需求。 总体来说,STM32单击、双击、短按按和组合键控制花样彩灯,可以实现非常灵活、多样化的控制效果,使得控制更为智能化、便捷化。同时,也需要对STM32的编程技能有一定的了解和掌握,才能够实现各种功能的控制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值