IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 独立按键扫描实现单击、双击、长按、组合等事件,使用FlexibleButton来实现 -> 正文阅读

[嵌入式]独立按键扫描实现单击、双击、长按、组合等事件,使用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:2MByte, ROM:1MByte
6. 在stm32h7xx_hal_conf.h文件中HSE_VALUE为外部高速振荡器,默认25MHZ。此值必须与硬件保持一致。

例程说明

1. 独立按键扫描实现单击、双击、长按、组合等事件,使用FlexibleButton来实现

一、宏定义说明

// PE3  -- User Key1 -- 用户按键1
// PC5  -- User Key2 -- 用户按键2
#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),
};


/* 按键ID字符串 */
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)
{
    // PC5  -- User Key1 -- 用户按键1
    // PE3  -- User Key2 -- 用户按键2

    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;// 按键的ID号
        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); // 设置短按事件触发的起始 tick
        UserButton[i].long_press_start_tick  = FLEX_MS_TO_SCAN_CNT(3000); // 设置长按事件触发的起始 tick
        UserButton[i].long_hold_start_tick   = FLEX_MS_TO_SCAN_CNT(4500); // 设置长按保持事件触发的起始 tick

        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;            /* 设置短按事件触发的起始 tick */
    uint16_t long_press_start_tick;             /* 设置长按事件触发的起始 tick */
    uint16_t long_hold_start_tick;              /* 设置长按保持事件触发的起始 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...

在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:41:35  更:2022-03-30 18:42:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:41:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码