-
準備工程,此例程在以下鏈接的例程的基礎上添加的按鍵掃描功能
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