STM32 自动识别单击和连续按键

程序设计500ms一下为单击按键 500ms以上为连续按键 实验开发板为正点原子mini板,设计思想是,当按键按下是启动定时器计数,抬起按键定时器停止计数,如果在设定的500ms以内提起按键则视为单击一次,如果定时器计数时间超过500ms则视为长按。

  1. 设置按键引脚
#define KEY0        HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_5)  //KEY0按键PC5
#define KEY1        HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_15) //KEY1按键PA15
#define WK_UP       HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)  //WKUP按键PA0

#define KEY0_PRES 		1
#define KEY1_PRES		2
#define WKUP_PRES   	3

//按键初始化函数
void KEY_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟
    
    GPIO_Initure.Pin=GPIO_PIN_0;            //PA0
    GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入
    GPIO_Initure.Pull=GPIO_PULLDOWN;        //下拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    
		GPIO_Initure.Pin=GPIO_PIN_15; 			//PA15
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    
		GPIO_Initure.Pin=GPIO_PIN_5; 			//PC5
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
}
  1. 开启一个定时器(timer3) 定时器定时时间为1ms。
HAL_TIM_Base_Start_IT(&htim3);	// 开启定时器
  1. 按键扫描程序
// 按键按下触发条件
void Set_Press_Flag(void)
{
	timer3_start_flag = 1;
	key_press_flag = 1;
}

// 自动支持点击和长按按键 单击抬起生效
uint8_t KEY_Scan(void)
{
	static uint8_t key_num = 200;
	
	if(key_press_flag == 0)
	{
		if(KEY0==0||KEY1==0||WK_UP==1)		// 有按键触发
		{
			HAL_Delay(10);
			if(KEY0 == 0)		// KEY0被按下
			{
				key_num = 0;
				Set_Press_Flag();
				
			}
			else if(KEY1 == 0)		// KEY1被按下
			{
				key_num = 1;
				Set_Press_Flag();
			}
			else if(WK_UP == 1)		// WK_UP被按下
			{
				key_num = 2;
				Set_Press_Flag();
			}
			else
			{
				key_num = 200;
			}
			return 0;			
		}
		else
		{
			return 0;
		}
	}
	else
	{
		if(KEY0==1&&KEY1==1&&WK_UP==0)
		{
			key_press_flag = 0;
			switch(key_num)
			{
				case 0:
					timer3_start_flag = 0;
					return KEY0_PRES;
				
				case 1:
					timer3_start_flag = 0;
					return KEY1_PRES;
				
				case 2:
					timer3_start_flag = 0;
					return WKUP_PRES;
			}
		}
	}
	return 0;
}
  1. 定时器处理函数
uint8_t timer3_start_flag = 0; 
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim == &htim3)
	{
		if(timer3_start_flag)
		{
			timer3_count ++;
			if(timer3_count > 500)
			{
				timer3_count = 2000;
				HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);
			}
			
		}
		else
		{
			timer3_count = 0;
		}
	}
}
  1. 测试程序
void User_Sys_Init(void)
{  
	HAL_TIM_Base_Start_IT(&htim2);
	HAL_TIM_Base_Start_IT(&htim3);	
	KEY_Init();
}


void Key_Handle()
{
	static uint8_t key = 0;
	key = KEY_Scan();
	switch(key)
	{
		case KEY0_PRES:
			printf("KEY0_PRES\r\n");
			HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
			break;
		
		case KEY1_PRES:
			printf("KEY1_PRES\r\n");
			HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
			break;
		
		case WKUP_PRES:
			printf("WKUP_PRES\r\n");
			HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
			break;
	}
	
}

int main()
{
	User_Sys_Init();
	while(1)
	{
		Key_Handle();
	}
	
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值