stm32 按键短按、长按、双击

整体思路:现在有4个按键

写一个获取按键值的函数,把函数放在定时器中,每10ms进行一次采集,采集到的按键值进行各种操作(不要太复杂,一般只加入某些变量和标志位的修改 以及一些条件判断),按键值在松开按键后进行清零。

工程文件结构

gpio.c   获取按键值

tim.c     每10ms进行一次按键处理程序

user.c   按键处理程序

main.c  各种函数运行包括按键处理程序

代码文件

gpio.c

/* USER CODE BEGIN 2 */
uint8_t key_val,key_val_last  ,flag_shuangJi;

uint8_t get_key (){
	static uint16_t key_count ;
	static uint16_t shuangJi_count ;
	
	if(!key_count)key_val=0;
	
	
	if(  !key1_io ||!key2_io ||!key3_io ||!key4_io){			//按键按下事件
		key_count++;
		if( !key1_io) key_val=91;
		if( !key2_io) key_val=92;
		if( !key3_io) key_val=93;
		if( !key4_io) key_val=94;
//		printf("OK\r\n");
	}
	/*双击*/
	if(flag_shuangJi) shuangJi_count ++;
	if(shuangJi_count>60 ){
		shuangJi_count=flag_shuangJi=0;
	}
	if(key_count<=2 && key1_io &&key2_io &&key3_io &&key4_io)	key_count= 	key_val=0;//抖动事件
	else if(key_count>2 && key1_io &&key2_io &&key3_io &&key4_io){//按键松开事件
		
		if(key_count<100){			//短按
			switch (key_val)
			{
				case 91:key_val =1;
					break;
				case 92:key_val =2;
					break;
				case 93:key_val =3;
					break;
				case 94:key_val =4;
					break;
			}
			/*双击*/
			if(key_val_last!=key_val){			//
				flag_shuangJi =shuangJi_count=0;		
			}
			if(key_val_last==key_val && shuangJi_count<60  && flag_shuangJi==1){		//双击按键第二次按下
				switch (key_val)
				{
					case 1:key_val =21;
						break;
					case 2:key_val =22;
						break;
					case 3:key_val =23;
						break;
					case 4:key_val =24;
						break;
				}
				flag_shuangJi =shuangJi_count=0;			
			}
			else if(!flag_shuangJi) {		//双击按键第一次按下
				flag_shuangJi =1;
				key_val_last = key_val ;		//记录
			}
		}
		
		/**/
		if(key_count>200){			//长按
			switch (key_val)
			{
				case 91:key_val =11;
					break;
				case 92:key_val =12;
					break;
				case 93:key_val =13;
					break;
				case 94:key_val =14;
					break;
			}
		}
//		printf("key:%d,%d\r\n",flag_shuangJi,shuangJi_count);
		key_count= 0;
	}
	
	return key_val;
}
/* USER CODE END 2 */

user.c  注意删改

void key_run ()
{
	/*0:数据   1 :参数   2:统计*/ 
//	printf("key:%d\r\n",key_val);
	switch ( get_key())
    {
    	case 1:flag.lcd++;
				LCD_Clear(Black);
    		break;
    	case 2:if(!flag.lcd  && !flag.tim_5s){
					flag.M_H^=1;
					value.NN++;
					value.tim_5s_count=tim4_count=0;
					flag.tim_5s = 1;
				}
				if(flag.lcd==1){
					flag.R_K^=1;
				}
    		break;
		case 3:(!flag.R_K)?(value.RR++):(value.KK++);
    		break;
		case 4:if(flag.lcd==1)(!flag.R_K)?(value.RR--):(value.KK--);
				if(!flag.lcd)flag.shuo_ding=0;
    		break;
		case 14:flag.shuo_ding=1;
				
    		break;
    }
	if(flag.lcd==3)flag.lcd=0;
	
	
	if(flag.tim_5s){
		value.tim_5s_count ++;
//		printf("OK");
		if(value.tim_5s_count>=500)flag.tim_5s=value.tim_5s_count =0;
	}
//	printf("tim:%d,%d\r\n",value.tim_5s_count,flag.tim_5s);
}

tim.c

 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim==&htim4){
		key_run();
		tim4_count ++ ;
		if(tim4_count>=60000)tim4_count=0;
	}
}

文章只提供思路,代码没有黏贴完成

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32HAL库提供了一些函数和方法来实现按键按、短按双击功能。下面是一种常见的实现方式: 1. 首先,需要初始化按键引脚和相关的外部中断。可以使用HAL库提供的GPIO_Init()函数来初始化按键引脚,并使用HAL库提供的HAL_GPIO_EXTI_Callback()函数来处理外部中断的回调函数。 2. 在回调函数中,可以使用HAL库提供的HAL_GetTick()函数获取当前系统的滴答计数值,用于计算按键的按下时间。 3. 当按键按下时,记录下按下的时间,并在松开按键时计算按键按下的时间差。根据时间差的不同,可以判断出是按、短按还是双击。 4. 根据判断结果,执行相应的操作。例如,如果是按,则执行按操作;如果是短按,则执行短按操作;如果是双击,则执行双击操作。 下面是一个示例代码,演示了如何使用STM32HAL库实现按键按、短按双击功能: ```c #include "stm32f4xx_hal.h" #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_PORT GPIOA #define LONG_PRESS_TIME 1000 // 按时间阈值 #define DOUBLE_CLICK_TIME 300 // 双击时间阈值 uint32_t buttonPressTime = 0; uint8_t buttonClickCount = 0; void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == BUTTON_PIN) { if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) == GPIO_PIN_SET) { // 按键按下 buttonPressTime = HAL_GetTick(); } else { // 按键松开 uint32_t buttonReleaseTime = HAL_GetTick(); uint32_t buttonPressDuration = buttonReleaseTime - buttonPressTime; if (buttonPressDuration >= LONG_PRESS_TIME) { // 按 // 执行按操作 } else if (buttonPressDuration <= DOUBLE_CLICK_TIME) { // 短按 buttonClickCount++; if (buttonClickCount == 2) { // 双击 // 执行双击操作 buttonClickCount = 0; } } else { // 单击 // 执行单击操作 buttonClickCount = 0; } } } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值