基于STM32F030R8Tx实现按键扫描

  • 准备工程,此例程在以下链接的例程的基础上添加的按键扫描功能

https://blog.csdn.net/mygod2008ok/article/details/106954917

  • 新建BSP_key.c和BSP_key.h并加入到工程

 

  • BSP_key.c的内容如下

/**
* @file BSP_key.c
* @author jzhou
* @version V1.0
* @date 11-Nov-2019
* @copyright Chileaf LTD
* @brief 按键扫描模块
*   实现单按键或多按键的短按,长按,短按松开,长按松开等键值
*/


#include "BSP_key.h"
#include "BSP_pwm.h"


//###############################################################################################################################
/** @file
*
* @defgroup BSP_key file:BSP_key文件
* @{
* @ingroup BSP_key file
* @brief 按键扫描模块
* @details 按键功能处理,主要是产生按键键值
*/
//###############################################################################################################################

//-----------------------以下为按键引脚配置及初时化--------------------------
/**
*
* @brief 按键引脚配置信息初时化
*/
static const SCAN_KEY_INFO scan_key[] = {
	{GPIOA,GPIO_PIN_12},
	{GPIOA,GPIO_PIN_11},
};



/**
* @brief 获取键值
*/
static KEY_TYPE_VAR get_key_value(void)
{
	KEY_TYPE_VAR KeyTemp = 0;
	
	// 读按键IO电平状态
  for(KEY_TYPE_VAR i=0; i<TOTAL_KEY_NUM;i++)
  {
		
	if(HAL_GPIO_ReadPin(scan_key[i].control_port,scan_key[i].enable_pin) == 0)
	{
		KeyTemp |= 1<<i;
	}	
  }
	return KeyTemp;
}

/**
* @brief 按键引脚初时化配置
*/
static void key_pin_init(void)
{
	__HAL_RCC_GPIOA_CLK_ENABLE();  
	GPIO_InitTypeDef  GPIO_InitStruct;
  /* -2- Configure IOs in output push-pull mode to drive external LEDs */
  GPIO_InitStruct.Mode  = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull  = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;

	for(uint8_t i=0; i<TOTAL_KEY_NUM; i++)
	{
			GPIO_InitStruct.Pin = scan_key[i].enable_pin;
			HAL_GPIO_Init(scan_key[i].control_port, &GPIO_InitStruct);
	}
}
//----------------------------------------------------------------------------



//-----------------------变量定义----------------------------------------------

static KEY_TYPE_VAR KeyBuffer;
static keyFunc keyFunctionHandler = NULL;



/**
* @brief 按键键值扫描
*  扫描按键状态返回对应的键值
* @param None
* @retval uint8_t
*  - 返回按键键值
*/
static KEY_TYPE_VAR OSReadKey(void)
{
	static E_KEY_SCAN_STATUS KeyEventCnt;
	static KEY_TYPE_VAR KeySampleCnt;
  KEY_TYPE_VAR KeyTemp = get_key_value();

	switch(KeyEventCnt )
	{
		case CHECK_HAS_KEY_DOWN:         // 有键按下
			if(KeyTemp != 0)
			{
				KeySampleCnt=0;
				KeyBuffer=KeyTemp;
				KeyEventCnt = KEY_EVENT_CHECK; 
			}	
			break;
		case KEY_EVENT_CHECK:  //按键事件检测
			if(KeyTemp == KeyBuffer )
			{
				KeyBuffer |= KEY_OFF;
				return KeyTemp ;  //返回短按事件
			}
			else if(KeyTemp == (KeyBuffer & ~(KEY_OFF | KEY_LONG_ON)))
			{
					if(++KeySampleCnt>LONG_ON_DITHERING_COUNTER)  //长按时间大于2秒,此时间可以重定义
					{
						KeySampleCnt = LONG_ON_DITHERING_COUNTER-SYS_TICK_COUNTER/8;   // 重复触发长按事件阀值
						KeyBuffer |= KEY_LONG_ON;
						return  KeyTemp | KEY_LONG_ON ; //返回长按事件
					}
			}
			else if(KeyTemp ==0)	
			{
				KeyEventCnt = CHECK_HAS_KEY_DOWN;
                                if((KeyBuffer & KEY_OFF) != KEY_OFF)
				    return 0;   //无效键
#if LONG_KEY_OFF_EVENT_ENABLED
				return KeyBuffer & ~KEY_BLOCK_FLAG;   //返回短按松开和长按松开事件
#else
				return KeyBuffer & ~(KEY_BLOCK_FLAG | KEY_LONG_ON);   //返回松开事件
#endif
			}		
			else if(((KeyBuffer & KEY_LONG_ON)==0) &&(KeySampleCnt < 5)) //多键同时按下,允许的按下时间,超过此时间检测到多键将无效
			{
					KeyEventCnt = CHECK_HAS_KEY_DOWN;
			}
			break;
		}
	return 0;
	
}


void DisLongKeyContinueResponse(void)
{
	KeyBuffer |= KEY_BLOCK_EVENT;   //长按键仅响应一次事件
}

//#####################################################################################################


/**
* @brief 按键事件注册
*/
void key_init(keyFunc fun)
{
	key_pin_init(); 
	keyFunctionHandler = fun;
}




/** 
* @brief 按键事件处理,此函数中定时事件中调用,此例程在25Hz中调用
*/
void keyProcessHandler(void)
{
	 KEY_TYPE_VAR event = OSReadKey();
	if(event == NO_KEY_EVENT)
		return;
	
//	NRF_LOG_INFO("KEY=%x",event);
	if(keyFunctionHandler != NULL)
	{
		keyFunctionHandler((E_KEY_VALUE)event);
	}

}





/**@}*/
  • BSP_key.h的内容如下: 

#ifndef BSP_KEY__H
#define BSP_KEY__H
#include "sdk_config.h"
#include "stm32f0xx.h"

/** @file
*
* @defgroup BSP_key file:BSP_key文件
* @{
* @ingroup BSP_key file
* @brief 按键扫描模块
* @details 按键功能处理,主要是产生按键键值
*/
#ifdef __cplusplus
extern "C" {
#endif

#define LONG_KEY_OFF_EVENT_ENABLED   1   //区分长按松开事件,否则短按松开和长按松开事件统一为松开事件


/**
* @brief 按键引脚配置结构体
*
*/
typedef struct 
{
	GPIO_TypeDef *control_port;   //!< IO端口地址
	uint16_t enable_pin;          //!< 引脚序号
}SCAN_KEY_INFO;

/************************************************************************/


#define TOTAL_KEY_NUM		sizeof(scan_key)/sizeof(SCAN_KEY_INFO)  //!< 按键总个数
#define LONG_ON_DITHERING_COUNTER (SYS_TICK_COUNTER*2) //!< 定义长按按下确认需要的时间,如果是每40毫秒调用一次OSReadKey()


//-------选择支持按键最大的键个数,默认支持5个按键-----------
//#define KEY_NUM_MAX_13
#ifdef  KEY_NUM_MAX_13
#define  KEY_TYPE_VAR		uint16_t
#define LONG_KEY_FLAG			0X8000
#define OFF_KEY_FLAG      0X4000
#define BLOCK_LONG_FLAG   0X2000
#else
#define  KEY_TYPE_VAR		uint8_t
#define LONG_KEY_FLAG			0X80
#define OFF_KEY_FLAG      0X40
#define BLOCK_LONG_FLAG   0X20
#endif

//##################################################################################
/**
* @brief 按键键值定义
*/
typedef enum
{
	 NO_KEY_EVENT = 0,
   KEY_LONG_ON	=	LONG_KEY_FLAG,           //!< 长按MASK值
   KEY_OFF	=		  OFF_KEY_FLAG,           //!< 松开MASK值
	 KEY_BLOCK_FLAG = BLOCK_LONG_FLAG,     // !<阻塞标记>
   KEY_BLOCK_EVENT =	KEY_LONG_ON | KEY_OFF | BLOCK_LONG_FLAG,    //!< 阻塞长按键
//-----------------------------------------------------------------------------------------
	 UP_KEY_SHORT = 0x01,						                     // KEY1短按键值
	 UP_KEY_LONG = UP_KEY_SHORT | KEY_LONG_ON,           // KEY1长按键值
	 UP_KEY_OFF = UP_KEY_SHORT | KEY_OFF,                // KEY1短按松开键值
	 UP_KEY_LONG_OFF = UP_KEY_LONG | KEY_OFF,            // KEY1长按松开键值
	
	 DOWN_KEY_SHORT = 0x02,                              // KEY2短按键值
	 DOWN_KEY_LONG = DOWN_KEY_SHORT |  KEY_LONG_ON,			// KEY2长按键值
	 DOWN_KEY_OFF = DOWN_KEY_SHORT | KEY_OFF,           // KEY2短按松开键值
	 DOWN_KEY_LONG_OFF = DOWN_KEY_LONG | KEY_OFF,       // KEY2长按松开键值
	
	 UP_DOWN_KEY_SHORT = UP_KEY_SHORT | DOWN_KEY_SHORT,    // KEY1+KEY2短按键值
	 UP_DOWN_KEY_LONG = UP_DOWN_KEY_SHORT | KEY_LONG_ON,   // KEY1+KEY2长按键值
	 UP_DOWN_KEY_OFF = UP_DOWN_KEY_SHORT | KEY_OFF,        // KEY1+KEY2短按松开键值  
	 UP_DOWN_KEY_LONG_OFF = UP_DOWN_KEY_LONG | KEY_OFF,    // KEY1+KEY2长按松开键值
}E_KEY_VALUE;



typedef enum
{
	CHECK_HAS_KEY_DOWN,
	KEY_EVENT_CHECK,
}E_KEY_SCAN_STATUS;

/**
* @brief 按键处理功能函数指针
*/

typedef void (*keyFunc)(E_KEY_VALUE keyValue);




//#####################################################################################
/**
*  @defgroup BSP_KEY_API 按键功能API
*  @{
*/
//############################ API ####################################################
/** 
*  @brief 按键引脚初时化
*  @param [in] keyFunc fun 按键处理函函数指针
*  @return 
* - None
*/
void key_init(keyFunc fun);

/** 
*  @brief 按键扫描处理
*  @param None
*  @return 
* - None
* @note 此函数需要在系统嘀嗒事件中调用
*/
void keyProcessHandler(void);




/**
* @brief 长按键阻止
*	Routine Name:	DisLongKeyContinueResponse
*	Form:		void DisLongKeyContinueResponse(void)	
*	Parameters:	void
*	Return Value:	void
*	Description: if call this function in the key process function,so it keep 
*	 continue long key msg to generate
*
* @param None
* @return None
*/
void DisLongKeyContinueResponse(void);

//####################################################################################
/**@}*/
#ifdef __cplusplus
  }
#endif
/**@}*/
#endif
  • 在main函数中调用key_init函数初时化注册按键事件

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	RTT_INIT();
  HAL_Init();
  SystemClock_Config();
 
	BSP_adc_init();
	
      BSP_wdt_init(IWDG_OVER_TIME);
   
	delay_init();
  
	//--------初时化串口------------------------------------
  
        BSP_uart_init();
	
	 MX_RTC_Init();
	
	 BSP_start_adc_count(8);
	
	start_buzzer_beep_sound();
	
	reply_stm32_version();
	
	 //-------------按键初时化-------------------------------		
	key_init(key_event_handler);
	
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		if(s_wakeup_flag)  //任务处理模式
		{
			BSP_wdt_feed();
			tick_25hz_handler();
			tick_1hz_handler();
			uart_data_handler();
		}
		else  // 省电模式
		{
			HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
		}
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  • key_event_handler函数实现键值处理


/**
* @brief 按键功能处理
*   分配ID及获取历史数据按键功能响应处理
* @param [in] E_KEY_VALUE 按键键值
* @retval 
* - None
*/
static void key_event_handler(E_KEY_VALUE keyValue)
{
	
	
	switch(keyValue)
	{
		case UP_KEY_SHORT:
			NRF_LOG_INFO("UP_KEY_SHORT=%x",keyValue);
			break;
		case DOWN_KEY_SHORT:
			NRF_LOG_INFO("DOWN_KEY_SHORT=%x",keyValue);
			break;
		case UP_DOWN_KEY_SHORT:
			NRF_LOG_INFO("UP_DOWN_KEY_SHORT=%x",keyValue);
			break;
		case UP_KEY_OFF:      
			
			  NRF_LOG_INFO("UP_KEY_OFF=%x",keyValue);
				break;
		case DOWN_KEY_OFF: 
			   NRF_LOG_INFO("DOWN_KEY_OFF=%x",keyValue);
				
			break;
		case UP_DOWN_KEY_OFF:
			 NRF_LOG_INFO("UP_DOWN_KEY_OFF=%x",keyValue);
			break;
	
	 case UP_KEY_LONG:    //此事件未调用阻止长按键,此事件会不停触发,直到按键松开
		 NRF_LOG_INFO("UP_KEY_LONG=%x",keyValue);
		 break;
	 case UP_KEY_LONG_OFF:
		 NRF_LOG_INFO("UP_KEY_LONG_OFF=%x",keyValue);
		 break;
	 case DOWN_KEY_LONG:
		   NRF_LOG_INFO("DOWN_KEY_LONG=%x",keyValue);
			 DisLongKeyContinueResponse();  //阻止长按键,仅触发一次
			break;
	 case DOWN_KEY_LONG_OFF:
		  NRF_LOG_INFO("DOWN_KEY_LONG_OFF=%x",keyValue);
		 break;
	 case UP_DOWN_KEY_LONG:
		NRF_LOG_INFO("UP_DOWN_KEY_LONG=%x",keyValue);
		 DisLongKeyContinueResponse();  //阻止长按键,仅触发一次
		 break;
	 case UP_DOWN_KEY_LONG_OFF:
		 NRF_LOG_INFO("UP_DOWN_KEY_LONG_OFF=%x",keyValue);
		 break;
		default:
			break;
	}
	
}
  • 在tick_25hz_handler函数中调用keyProcessHandler函数进行按键扫描 


/**
* @brief 25Hz handler
*
*/
static void tick_25hz_handler(void)
{
	if((s_wakeup_flag & TICK_FOR_25HZ) == 0)
	  return;
	s_wakeup_flag &= CLEAR_TICK_FOR_25HZ;
//####################################################################################
	//---------TODO this to add 25hz event handler-----------
	BSP_adc_convert_handler();
        buzzer_beep_sound_handler();
	uart1_rec_timeout();
	keyProcessHandler();
}
  • 分析下按键扫描原理实现

1. 按键列表变量,此例程只使用了2个IO作为按键,实现更多按键只需在scan_key数组中添加IO信息即可


/**
* @brief 按键引脚配置结构体
*
*/
typedef struct 
{
	GPIO_TypeDef *control_port;   //!< IO端口地址
	uint16_t enable_pin;          //!< 引脚序号
}SCAN_KEY_INFO;

//-----------------------以下为按键引脚配置及初时化--------------------------
/**
*
* @brief 按键引脚配置信息初时化
*/
static const SCAN_KEY_INFO scan_key[] = {
	{GPIOA,GPIO_PIN_12},
	{GPIOA,GPIO_PIN_11},
};

2.按键初时化函数,对scan_key数组中的IO配置成输入上拉,即按键低电平为按下

/**
* @brief 按键引脚初时化配置
*/
static void key_pin_init(void)
{
	__HAL_RCC_GPIOA_CLK_ENABLE();  
	GPIO_InitTypeDef  GPIO_InitStruct;
  /* -2- Configure IOs in output push-pull mode to drive external LEDs */
  GPIO_InitStruct.Mode  = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull  = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;

	for(uint8_t i=0; i<TOTAL_KEY_NUM; i++)
	{
		GPIO_InitStruct.Pin = scan_key[i].enable_pin;
		HAL_GPIO_Init(scan_key[i].control_port, &GPIO_InitStruct);
	}
}

3.get_key_value函数获取IO电平值,对scan_key数组中的IO从下标0开始读取IO电平值,如有按键按下,将相应位置1,例如下标0的IO被按下,则键值的第0位置1,依此类推,下标1的IO被按下,则键值的第1位置1,如果没有任何键按下,则键值为0,也就是说,可以通过判断键值不为0说明有键按下


/**
* @brief 获取键值
*/
static KEY_TYPE_VAR get_key_value(void)
{
	KEY_TYPE_VAR KeyTemp = 0;
	
	// 读按键IO电平状态
   for(KEY_TYPE_VAR i=0; i<TOTAL_KEY_NUM;i++)
   {
		
	if(HAL_GPIO_ReadPin(scan_key[i].control_port,scan_key[i].enable_pin) == 0)
	{
		KeyTemp |= 1<<i;
	}	
   }
   return KeyTemp;
}

4.OSReadKey函数实现键值事件,此函数是按键扫描的核心,按键去抖,短按,长按,短按松开,长按松开,多键等都是由此函数实现

/**
* @brief 按键键值扫描
*  扫描按键状态返回对应的键值
* @param None
* @retval uint8_t
*  - 返回按键键值
*/
static KEY_TYPE_VAR OSReadKey(void)
{
	static E_KEY_SCAN_STATUS KeyEventCnt;
	static KEY_TYPE_VAR KeySampleCnt;
  KEY_TYPE_VAR KeyTemp = get_key_value();

	switch(KeyEventCnt )
	{
		case CHECK_HAS_KEY_DOWN:         // 有键按下
			if(KeyTemp != 0)
			{
				KeySampleCnt=0;
				KeyBuffer=KeyTemp;
				KeyEventCnt = KEY_EVENT_CHECK; 
			}	
			break;
		case KEY_EVENT_CHECK:  //按键事件检测
			if(KeyTemp == KeyBuffer )
			{
				KeyBuffer |= KEY_OFF;
				return KeyTemp ;  //返回短按事件
			}
			else if(KeyTemp == (KeyBuffer & ~(KEY_OFF | KEY_LONG_ON)))
			{
					if(++KeySampleCnt>LONG_ON_DITHERING_COUNTER)  //长按时间大于2秒,此时间可以重定义
					{
						KeySampleCnt = LONG_ON_DITHERING_COUNTER-SYS_TICK_COUNTER/8;   // 重复触发长按事件阀值
						KeyBuffer |= KEY_LONG_ON;
						return  KeyTemp | KEY_LONG_ON ; //返回长按事件
					}
			}
			else if(KeyTemp ==0)	
			{
				KeyEventCnt = CHECK_HAS_KEY_DOWN;
                                if((KeyBuffer & KEY_OFF) != KEY_OFF)
				    return 0;   //无效键
#if LONG_KEY_OFF_EVENT_ENABLED
				return KeyBuffer & ~KEY_BLOCK_FLAG;   //返回短按松开和长按松开事件
#else
				return KeyBuffer & ~(KEY_BLOCK_FLAG | KEY_LONG_ON);   //返回松开事件
#endif
			}		
			else if(((KeyBuffer & KEY_LONG_ON)==0) &&(KeySampleCnt < 5)) //多键同时按下,允许的按下时间,超过此时间检测到多键将无效
			{
					KeyEventCnt = CHECK_HAS_KEY_DOWN;
			}
			break;
		}
	return 0;
	
}

 4.1  以第1个按键(scan_key[0]对应的IO)为例 

    4.11 短按事件

     a. 按住第1个按键,OSReadKey函数每25Hz调用一次,函数中调用了 get_key_value获取IO键值,第1个键对应的BIT0会置位,其它的位为0,则IO键值为1

            KEY_TYPE_VAR KeyTemp = get_key_value();

   b. KeyTemp的值为1,KeyEventCnt状态机初时值为CHECK_HAS_KEY_DOWN,则进入分支CHECK_HAS_KEY_DOWN,

   由于KeyTemp为1,条件if(KeyTemp != 0)满足,执行按键计数清0,暂存键值到KeyBuffer,KeyBuffer值变成1,状态机

   KeyEventCnt迁移到KEY_EVENT_CHECK状态

c. 第2次25Hz时间到,再次调用 OSReadKey函数,再次获取IO键值,如果IO还是被按下,那么BIT0仍然保持为1,否则为0

         KEY_TYPE_VAR KeyTemp = get_key_value();

 c.1 先看第2次按键仍然按下的情况,KeyTemp为1,KeyEventCnt状态值为KEY_EVENT_CHECK,则进入此分支执行,KeyBuffer的值第1次扫描的时候预存为1,那么if(KeyTemp == KeyBuffer )条件满足,则将KeyBuffer的值与KEY_OFF的值按位或

运算,最后返回KeyTemp的值,此值为1,正好是短按键键值

 

c.2 如果第2次扫描到按键为松开,则 KEY_TYPE_VAR KeyTemp = get_key_value(); KeyTemp的值为0,那么返回无效键值0

 

5.短按松开,产生短按事件后,第3次或2秒以内扫描按键是松开,KeyTemp为0,KeyBuffer有KEY_OFF标志,则返回松开键值

            KeyBuffer & ~KEY_BLOCK_FLAG; 

6.长按事件,如果第1个按键一直按下且时间超过2秒,由于KeyBuffer在短按事件产生时被加上了KEY_OFF标记,所以此条件不成立,这条分KeyTemp == (KeyBuffer & ~(KEY_OFF | KEY_LONG_ON))会成立,原因是将KEY_OFF,KEY_LONG_ON标志屏蔽了,由于按键按住时间超过LONG_ON_DITHERING_COUNTER的次数(2秒),则返回长按键值KeyTemp | KEY_LONG_ON,如果一直按下,会每隔LONG_ON_DITHERING_COUNTER-SYS_TICK_COUNTER/8时间再次触发长按事件

 

7.长按松开事件,如果产生了长按事件后,按键松开后,则KeyBuffer值中有长按键值和KEY_OFF标志,返回了长按事件

8.多键事件,如果第1个和第2个按键都被按下,第0位和第1位都被置1,则KeyTemp 的值为3,

     KEY_TYPE_VAR KeyTemp = get_key_value(); 

那么其短按事件为

  

其它键值和单键产生类似,多键的允许接收时间如下条件

9.长按键阻塞,即仅触发一次长按事件,在长按事件中调用DisLongKeyContinueResponse函数会阻赛长按事件被重复触发

void DisLongKeyContinueResponse(void)
{
	KeyBuffer |= KEY_BLOCK_EVENT;   //长按键仅响应一次事件
}

函数调用后,由于KeyBuffer被添加了KEY_BLOCK_EVENT标志,则以下

(((KeyBuffer & KEY_LONG_ON)==0) &&(KeySampleCnt < 5))分支将不再满足条件,即进行了长按阻塞

 

  • keyProcessHandler函数 


/** 
* @brief 按键事件处理,此函数中定时事件中调用,此例程在25Hz中调用
*/
void keyProcessHandler(void)
{
	 KEY_TYPE_VAR event = OSReadKey();
	if(event == NO_KEY_EVENT)
		return;
	
//	NRF_LOG_INFO("KEY=%x",event);
	if(keyFunctionHandler != NULL)
	{
		keyFunctionHandler((E_KEY_VALUE)event);
	}

}

此函数在25Hz函数中调用(40毫秒调用一次),event为NO_KEY_EVENT将不将任何处理,如果有键值产生,则调用函数指针keyFunctionHandler进行事件回调

  • key_event_handler回调函数,此函数由使用者编写,由初时化函数key_init进行注册 


/**
* @brief 按键功能处理
*   分配ID及获取历史数据按键功能响应处理
* @param [in] E_KEY_VALUE 按键键值
* @retval 
* - None
*/
static void key_event_handler(E_KEY_VALUE keyValue)
{
	
	
	switch(keyValue)
	{
		case UP_KEY_SHORT:  // UP 短按
			NRF_LOG_INFO("UP_KEY_SHORT=%x",keyValue); 
			break;
		case DOWN_KEY_SHORT:   // DOWN 短按
			NRF_LOG_INFO("DOWN_KEY_SHORT=%x",keyValue);
			break;
		case UP_DOWN_KEY_SHORT:  // UP+DOWN 短按
			NRF_LOG_INFO("UP_DOWN_KEY_SHORT=%x",keyValue);
			break;
		case UP_KEY_OFF:      // UP 短按松开
			
			  NRF_LOG_INFO("UP_KEY_OFF=%x",keyValue);
				break;
		case DOWN_KEY_OFF:   // DWON 短按松开
			   NRF_LOG_INFO("DOWN_KEY_OFF=%x",keyValue);
				
			break;
		case UP_DOWN_KEY_OFF:  // UP + DOWN 短按松开
			 NRF_LOG_INFO("UP_DOWN_KEY_OFF=%x",keyValue);
			break;
	
	 case UP_KEY_LONG:    //UP长按,此事件未调用阻止长按键,此事件会不停触发,直到按键松开
		 NRF_LOG_INFO("UP_KEY_LONG=%x",keyValue);
		 break;
	 case UP_KEY_LONG_OFF:  //UP长按松开
		 NRF_LOG_INFO("UP_KEY_LONG_OFF=%x",keyValue);
		 break;
	 case DOWN_KEY_LONG: //DOWN长按
		   NRF_LOG_INFO("DOWN_KEY_LONG=%x",keyValue);
			 DisLongKeyContinueResponse();  //阻止长按键,仅触发一次
			break;
	 case DOWN_KEY_LONG_OFF: // DOWN长按松开
		  NRF_LOG_INFO("DOWN_KEY_LONG_OFF=%x",keyValue);
		 break;
	 case UP_DOWN_KEY_LONG:  // UP+DOWN长按
		NRF_LOG_INFO("UP_DOWN_KEY_LONG=%x",keyValue);
		 DisLongKeyContinueResponse();  //阻止长按键,仅触发一次
		 break;
	 case UP_DOWN_KEY_LONG_OFF:  // UP+DOWN长按松开
		 NRF_LOG_INFO("UP_DOWN_KEY_LONG_OFF=%x",keyValue);
		 break;
		default:
			break;
	}
	
}
  • Demo运行结果

  • Demo下载地址:

https://download.csdn.net/download/mygod2008ok/12554839

 

 

 

 

 

 

         

 

 

 

 

 

 

 


 

 

   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章