STM32独立按键之长按、短按

内容如题:

1. 独立按键(软件消抖)
芯片引脚初始化为上拉输入

#define KEY_L_STATE					LL_GPIO_IsInputPinSet(KEY_L_PORT, KEY_L_PIN)					
#define KEY_R_STATE					LL_GPIO_IsInputPinSet(KEY_R_PORT, KEY_R_PIN)
#define KEY_ENTER_STATE			LL_GPIO_IsInputPinSet(KEY_ENTER_PORT, KEY_ENTER_PIN)

uint8_t Key_Scan(void)
{
	static uint8_t Up_Flag=1;
	if((Up_Flag)&&((KEY_L_STATE==0)||(KEY_R_STATE==0)||(KEY_ENTER_STATE==0)))//在按键抬起的状态下有按键按下
	{
		LL_mDelay(50);//消抖
		Up_Flag=0;//标记有按键已经按下,只有等待再次抬起才能触发
		if(KEY_L_STATE==0)return 1;
		else if(KEY_R_STATE==0)return 2;
		else if(KEY_ENTER_STATE==0)return 3;
	}
	else if((KEY_L_STATE==1)&&(KEY_R_STATE==1)&&(KEY_ENTER_STATE==1))
		Up_Flag=1;//只有当所有按键都是默认状态,再置位按键抬起标志
	return 0;
}

int main(void)
{
	key=Key_Scan();
	if(key==1)
	{
		//...
	}
	else if(key==2)
	{
		//....
	}
}

2. 按键长按、短按:

首先初始化一个TIM作为长按时间的计数器

void MX_TIM4_Init(void)
{
  LL_TIM_InitTypeDef TIM_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);

  /* TIM4 interrupt Init */
  NVIC_SetPriority(TIM4_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),2, 0));
  NVIC_EnableIRQ(TIM4_IRQn);

  TIM_InitStruct.Prescaler = 3600;
  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = 1000;
  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  LL_TIM_Init(TIM4, &TIM_InitStruct);
  LL_TIM_DisableARRPreload(TIM4);
  LL_TIM_SetClockSource(TIM4, LL_TIM_CLOCKSOURCE_INTERNAL);
  LL_TIM_SetTriggerOutput(TIM4, LL_TIM_TRGO_UPDATE);
  LL_TIM_DisableMasterSlaveMode(TIM4);

}

定义一个结构体,把按键引脚定义为上拉输入

typedef struct{
	uint8_t Key_Press;		//按键按下标志
	uint8_t L1_S_Flag;		//Key1短按标志
	uint8_t L1_L_Flag;		//Key1长按标志
	uint8_t L1_C_Flag;		//Key1点击标志
	uint8_t L2_S_Flag;		//Key2短按标志
	uint8_t L2_L_Flag;		//Key2长按标志
	uint8_t L2_C_Flag;		//Key2点击标志
	uint8_t L12_L_Flag;		//Key1和2长按标志
	uint8_t KeyUp_Flag;		//判断点击事件时按键松开标志
}Key_State;

在TIM4中断中处理按键的长按、短按

void TIM4_IRQHandler(void)
{
  /* USER CODE BEGIN TIM4_IRQn 0 */
	if(LL_TIM_IsActiveFlag_UPDATE(TIM4))											//5ms进入中断一次
	{
		LL_TIM_ClearFlag_UPDATE(TIM4);													//清除更新中断
		
		/*****************************KEY1长短按处理*****************************************/
		if(LL_GPIO_IsInputPinSet(GPIOE, KEY1_Pin)==0)						//按键按下
		{
			Press_Times1++;
			printf("Press_Times1-->%d
",Press_Times1);
		}
		else																										//松开按键
		{
			if((Press_Times1>1)&&(Press_Times1<20))		//按键按下时长  5ms<t<100ms
			{
				KeyState.L2_S_Flag=1;											//标记为短按
				KeyState.L2_L_Flag=0;
			}
			else if(Press_Times1>20)										//按键按下时长超过100ms
			{
				KeyState.L2_S_Flag=0;											//标记为长按
				KeyState.L2_L_Flag=1;
				if(KeyState.L1_L_Flag)
				{
					KeyState.L12_L_Flag=1;
					KeyState.L1_L_Flag=0;
					KeyState.L2_L_Flag=0;
				}
			}
			else
			{
				KeyState.L2_S_Flag=0;											//忽略
				KeyState.L2_L_Flag=0;
			}
			Press_Times1=0;															//清空计数
		}
		
		/*****************************KEY0长短按处理*****************************************/
		if(LL_GPIO_IsInputPinSet(GPIOE, KEY0_Pin)==0)						//按键按下
		{
			Press_Times0++;
			printf("Press_Times0-->%d
",Press_Times0);
		}
		else											//松开按键
		{
			if((Press_Times0>1)&&(Press_Times0<20))		//按键按下时长  5ms<t<100ms
			{
				KeyState.L1_S_Flag=1;											//标记为短按
				KeyState.L1_L_Flag=0;
			}
			else if(Press_Times0>20)										//按键按下时长超过100ms
			{
				KeyState.L1_S_Flag=0;											//标记为长按
				KeyState.L1_L_Flag=1;
				if(KeyState.L2_L_Flag)
				{
					KeyState.L12_L_Flag=1;
					KeyState.L1_L_Flag=0;
					KeyState.L2_L_Flag=0;
				}
			}
			else
			{
				KeyState.L1_S_Flag=0;											//忽略
				KeyState.L1_L_Flag=0;
			}
			Press_Times0=0;															//清空计数
		}
		/****************************KEY1和KEY2同时长按**************************************/
	}
  /* USER CODE END TIM4_IRQn 0 */
  /* USER CODE BEGIN TIM4_IRQn 1 */

  /* USER CODE END TIM4_IRQn 1 */
}

使用:

while (1)
  {
    /* USER CODE END WHILE */

		if(KeyState.L1_S_Flag)
		{
			printf("KEY2短按事件...
");
			KeyState.L1_S_Flag=0;
		}
		else if(KeyState.L1_L_Flag)
		{
			printf("KEY2长按事件...
");
			KeyState.L1_L_Flag=0;
		}
		//else if()。。。。。
}

ProjectLink

原文地址:https://www.cnblogs.com/hhsxy/p/14018388.html