zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    第三章 AjaxPro框架
    第一章 ASP.NET XML与JSON
    第二章 ASP.NET Ajax核心对象
    第五次作业
    第四次作业
    第三周笔记
    第二周笔记
    Java作业
    日期顺时,自动跳过节假日
    利用java实现excel转pdf文件
  • 原文地址:https://www.cnblogs.com/hhsxy/p/14018388.html
Copyright © 2011-2022 走看看