独立按键扫描实现单击、双击、长按、组合等事件,使用FlexibleButton来实现
编译器平台及例程说明
编译器平台说明
1. Toolchain : MDK- ARM Community Version: 5.30 .0 .0 ( Kile V5)
2. Encoding : Encode in UTF- 8 without signature
3. Device Specific Packs : Keil. STM32H7xx_DFP. 2.7 .0 . pack
4. Preprocessor Symbols Define : USE_HAL_DRIVER, STM32H743xx
USE_HAL_DRIVER : 允许使用HAL库驱动
STM32H743xx : STM32H743xx芯片
5. Chip Type : STM32H743VIT6, Flash: 2 MByte, ROM: 1 MByte
6. 在stm32h7xx_hal_conf. h文件中HSE_VALUE为外部高速振荡器,默认25 MHZ。此值必须与硬件保持一致。
例程说明
1. 独立按键扫描实现单击、双击、长按、组合等事件,使用FlexibleButton来实现
一、宏定义说明
# define USER_KEY1_PIN USER_KEY1_Pin
# define USER_KEY2_PIN USER_KEY2_Pin
# define Read_Key1_State ( ) HAL_GPIO_ReadPin ( USER_KEY1_GPIO_Port, USER_KEY1_PIN)
# define Read_Key2_State ( ) HAL_GPIO_ReadPin ( USER_KEY2_GPIO_Port, USER_KEY2_PIN)
# define XTO_STR ( e) ( #e)
typedef enum
{
USER_BTN1 = 0 ,
USER_BTN2 = 1 ,
USER_BTN_MAX
} eUserBtn;
二、变量的定义
static flex_button_t UserButton[ USER_BTN_MAX] ;
static char * BTN_EVENT_STR[ FLEX_BTN_PRESS_NONE + 1 ] =
{
XTO_STR ( PressDown) ,
XTO_STR ( Click) ,
XTO_STR ( Double) ,
XTO_STR ( RepeatClick) ,
XTO_STR ( ShortStart) ,
XTO_STR ( ShortEnd) ,
XTO_STR ( LongStart) ,
XTO_STR ( LongEnd) ,
XTO_STR ( LongHold) ,
XTO_STR ( LongHoldEnd) ,
XTO_STR ( BtnEventMax) ,
XTO_STR ( BtnEventNone) ,
} ;
static char * BTN_ID_STR[ USER_BTN_MAX] =
{
XTO_STR ( BTN1) ,
XTO_STR ( BTN2) ,
} ;
三、读取按键状态
static u8 ubRead_Button_Value ( void * arg)
{
flex_button_t * btn = ( flex_button_t * ) arg;
switch ( btn-> id)
{
case USER_BTN1: return Read_Key1_State ( ) ;
case USER_BTN2: return Read_Key2_State ( ) ;
default : break ;
}
return 0 ;
}
四、按键事件回调
static void vButtonEvent_CallBack ( void * arg)
{
flex_button_t * btn = ( flex_button_t * ) arg;
dprintf ( "id:[%d-%s] event:[%d-%s]\r\n" , \
btn-> id, BTN_ID_STR[ btn-> id] , \
btn-> event, BTN_EVENT_STR[ btn-> event] ) ;
switch ( btn-> id)
{
case USER_BTN1:
{
switch ( btn-> event)
{
case FLEX_BTN_PRESS_CLICK :
dprintf ( "BTN1 Click...\r\n" ) ;
break ;
case FLEX_BTN_PRESS_DOUBLE_CLICK :
dprintf ( "BTN1 Double Click...\r\n" ) ;
break ;
case FLEX_BTN_PRESS_LONG_START :
dprintf ( "BTN1 Long Press...\r\n" ) ;
break ;
default : break ;
}
}
break ;
case USER_BTN2:
{
switch ( btn-> event)
{
case FLEX_BTN_PRESS_CLICK :
dprintf ( "BTN2 Click...\r\n" ) ;
break ;
case FLEX_BTN_PRESS_DOUBLE_CLICK :
dprintf ( "BTN2 Double Click...\r\n" ) ;
break ;
case FLEX_BTN_PRESS_LONG_START :
dprintf ( "BTN2 Long Press...\r\n" ) ;
break ;
default : break ;
}
}
break ;
default : break ;
}
if ( ( flex_button_event_read ( & UserButton[ USER_BTN1] ) == FLEX_BTN_PRESS_CLICK) && \
( flex_button_event_read ( & UserButton[ USER_BTN2] ) == FLEX_BTN_PRESS_CLICK) )
{
dprintf ( "BTN1 And BTN2 Click...\r\n" ) ;
}
if ( ( flex_button_event_read ( & UserButton[ USER_BTN1] ) == FLEX_BTN_PRESS_LONG_START) && \
( flex_button_event_read ( & UserButton[ USER_BTN2] ) == FLEX_BTN_PRESS_LONG_START) )
{
dprintf ( "BTN1 And BTN2 Long Press...\r\n" ) ;
}
}
五、初始化按键
static void vInit_Key_Input ( void )
{
GPIO_InitTypeDef GPIO_InitStruct = { 0 } ;
GPIO_InitStruct. Pin = USER_KEY1_Pin;
GPIO_InitStruct. Mode = GPIO_MODE_INPUT;
GPIO_InitStruct. Pull = GPIO_PULLUP;
GPIO_InitStruct. Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init ( USER_KEY1_GPIO_Port, & GPIO_InitStruct) ;
GPIO_InitStruct. Pin = USER_KEY2_Pin;
HAL_GPIO_Init ( USER_KEY2_GPIO_Port, & GPIO_InitStruct) ;
dprintf ( "5-STM32H743xx_CubeMx_KeyInput_FlexibleButton......\r\n" ) ;
}
void vInit_Flexible_Button ( void )
{
u8 i = 0 ;
memset ( & UserButton[ 0 ] , 0 , sizeof ( UserButton) ) ;
vInit_Key_Input ( ) ;
for ( i = 0 ; i < USER_BTN_MAX; i ++ )
{
UserButton[ i] . id = i;
UserButton[ i] . usr_button_read = ubRead_Button_Value;
UserButton[ i] . cb = vButtonEvent_CallBack;
UserButton[ i] . pressed_logic_level = 0 ;
UserButton[ i] . short_press_start_tick = FLEX_MS_TO_SCAN_CNT ( 1500 ) ;
UserButton[ i] . long_press_start_tick = FLEX_MS_TO_SCAN_CNT ( 3000 ) ;
UserButton[ i] . long_hold_start_tick = FLEX_MS_TO_SCAN_CNT ( 4500 ) ;
flex_button_register ( & UserButton[ i] ) ;
}
}
六、测试例程
int main ( void )
{
static u8 i = 0 ;
vStartUp_System ( ) ;
vInit_System_BSP ( ) ;
vShow_PlatformDevice_Info ( ) ;
vInit_Flexible_Button ( ) ;
while ( 1 )
{
flex_button_scan ( ) ;
HAL_Delay ( 20 ) ;
if ( ( ++ i) > 50 )
{
i = 0 ;
USER_LED_CPL ( ) ;
}
}
}
七、FlexibleButton源码说明
typedef enum
{
FLEX_BTN_PRESS_DOWN = 0 ,
FLEX_BTN_PRESS_CLICK,
FLEX_BTN_PRESS_DOUBLE_CLICK,
FLEX_BTN_PRESS_REPEAT_CLICK,
FLEX_BTN_PRESS_SHORT_START,
FLEX_BTN_PRESS_SHORT_UP,
FLEX_BTN_PRESS_LONG_START,
FLEX_BTN_PRESS_LONG_UP,
FLEX_BTN_PRESS_LONG_HOLD,
FLEX_BTN_PRESS_LONG_HOLD_UP,
FLEX_BTN_PRESS_MAX,
FLEX_BTN_PRESS_NONE,
} flex_button_event_t ;
typedef struct flex_button
{
struct flex_button * next;
uint8_t ( * usr_button_read) ( void * ) ;
flex_button_response_callback cb;
uint16_t scan_cnt;
uint16_t click_cnt;
uint16_t max_multiple_clicks_interval;
uint16_t debounce_tick;
uint16_t short_press_start_tick;
uint16_t long_press_start_tick;
uint16_t long_hold_start_tick;
uint8_t id;
uint8_t pressed_logic_level : 1 ;
uint8_t event : 4 ;
uint8_t status : 3 ;
} flex_button_t ;
八、运行效果
00 > Segger Rtt Init Ok. . .
00 > STM32H743VIT6 Start Running. . .
00 > 5 - STM32H743xx_CubeMx_KeyInput_FlexibleButton. . . . . .
00 > Debug Versions. . . . . .
00 > Compile Date : Mar 28 2022 22 : 35 : 35
00 >
00 > id: [ 0 - BTN1] event: [ 0 - PressDown]
00 > id: [ 0 - BTN1] event: [ 1 - Click]
00 > BTN1 Click. . .
00 > id: [ 1 - BTN2] event: [ 0 - PressDown]
00 > id: [ 1 - BTN2] event: [ 1 - Click]
00 > BTN2 Click. . .
00 > id: [ 0 - BTN1] event: [ 0 - PressDown]
00 > id: [ 0 - BTN1] event: [ 4 - ShortStart]
00 > id: [ 0 - BTN1] event: [ 6 - LongStart]
00 > BTN1 Long Press. . .
00 > id: [ 0 - BTN1] event: [ 7 - LongEnd]
00 > id: [ 1 - BTN2] event: [ 0 - PressDown]
00 > id: [ 1 - BTN2] event: [ 4 - ShortStart]
00 > id: [ 1 - BTN2] event: [ 6 - LongStart]
00 > BTN2 Long Press. . .
00 > id: [ 1 - BTN2] event: [ 7 - LongEnd]
00 > id: [ 1 - BTN2] event: [ 0 - PressDown]
00 > id: [ 0 - BTN1] event: [ 0 - PressDown]
00 > id: [ 1 - BTN2] event: [ 1 - Click]
00 > BTN2 Click. . .
00 > id: [ 0 - BTN1] event: [ 1 - Click]
00 > BTN1 Click. . .
00 > id: [ 0 - BTN1] event: [ 0 - PressDown]
00 > id: [ 1 - BTN2] event: [ 0 - PressDown]
00 > id: [ 0 - BTN1] event: [ 4 - ShortStart]
00 > id: [ 1 - BTN2] event: [ 4 - ShortStart]
00 > id: [ 0 - BTN1] event: [ 6 - LongStart]
00 > BTN1 Long Press. . .
00 > id: [ 1 - BTN2] event: [ 6 - LongStart]
00 > BTN2 Long Press. . .
00 > BTN1 And BTN2 Long Press. . .
00 > id: [ 0 - BTN1] event: [ 7 - LongEnd]
00 > id: [ 1 - BTN2] event: [ 7 - LongEnd]
00 > id: [ 1 - BTN2] event: [ 0 - PressDown]
00 > id: [ 0 - BTN1] event: [ 0 - PressDown]
00 > id: [ 1 - BTN2] event: [ 1 - Click]
00 > BTN2 Click. . .
00 > id: [ 0 - BTN1] event: [ 1 - Click]
00 > BTN1 Click. . .
00 > BTN1 And BTN2 Click. . .