当前位置: 首页 > news >正文

RT-thread的MultiButton按键库的使用

前言

这个按键库还不错,学习一波,以后有关按键的逻辑就可以借用啦~~~~!!!
(我为了工程结构的完整,会比较啰嗦,会建立一系列文件夹。大家如果只是想看这个库怎么用,可以挑重要的地方看~)
在这里插入图片描述

一、新建工程

在这里插入图片描述

二、main.c中这么写

/*
 * Copyright (c) 2006-2025, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-26     RT-Thread    first version
 */

#include "system_deal.h"

int main(void)
{
    SystemStartInit();

    return RT_EOK;
}

在这里插入图片描述

三、在applications下创建system_deal文件夹,再在system_deal文件夹下创建:system_config.hsystem_deal.csystem_deal.h这三个文件

在这里插入图片描述

四、包含system_deal.h头文件

在这里插入图片描述

五、在system_deal.h文件里写入如下代码

在这里插入图片描述

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-26     Administrator       the first version
 */
#ifndef APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_
#define APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_


#include <rtdevice.h>
#include <rtthread.h>
#include "board.h"
#include "stdio.h"

#include "system_config.h"
#include "button_deal.h"

/* thread information */
#define SYS_THREAD_STACK 1024
#define SYS_THREAD_PRO 15
#define SYS_THREAD_TICK 10

/* system io */
#define SYS_LED             GET_PIN(G, 13)

extern void SystemStartInit(void);

#endif /* APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_ */

六、搜索添加MultiButto软件包

在这里插入图片描述

七、在system_deal.c文件里写入如下代码

在这里插入图片描述

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-26     Administrator       the first version
 */
#ifndef APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_C_
#define APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_C_

#include "system_deal.h"

/*********************************************************************************************************
 ** Function name:       SystemLedRun
 ** Descriptions:        System Led Run
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
static void SystemLedRun(void)
{
    static uint8_t l_ucmode = 0;
    if (l_ucmode == 0)
    {
        rt_pin_write(SYS_LED, PIN_HIGH);
        l_ucmode = 1;
    }
    else if (l_ucmode == 1)
    {
        rt_pin_write(SYS_LED, PIN_LOW);
        l_ucmode = 0;
    }
}

/*********************************************************************************************************
 ** Function name:       SysDeal_thread
 ** Descriptions:        SysDeal thread
 ** input parameters:    parameter
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
static void SysDeal_thread(void* parameter)
{

    // set pin
    rt_pin_mode(SYS_LED, PIN_MODE_OUTPUT);
    rt_pin_write(SYS_LED, PIN_HIGH);
    while (1)
    {
        SystemLedRun();
        rt_thread_mdelay(500);
    }
}

/*********************************************************************************************************
 ** Function name:       SystemDealTaskInit
 ** Descriptions:        System Task Init
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
void SystemDealTaskInit(void)
{
    rt_thread_t SysDeal_tid;
    SysDeal_tid = rt_thread_create("sys_ctl", SysDeal_thread, RT_NULL, SYS_THREAD_STACK, SYS_THREAD_PRO, SYS_THREAD_TICK);
    if (SysDeal_tid != RT_NULL)
    {
        rt_thread_startup(SysDeal_tid);
    }
    else
    {
#if DEBUG_LOG_ENABLE
        rt_kprintf("/--> SysDeal create failed!\n");
#endif
    }
}

/*********************************************************************************************************
 ** Function name:       SystemSemaphoreInit
 ** Descriptions:        System Semaphore Init
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
static void SystemSemaphoreInit(void)
{
#if BUTTON_CONTROL_ENABLE
    HmiButtonSemaphoreInit();
#endif

}


/*********************************************************************************************************
 ** Function name:       SystemTaskInit
 ** Descriptions:        System Task Init
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
static void SystemTaskInit(void)
{

    SystemDealTaskInit();  // 15

#if BUTTON_CONTROL_ENABLE
    HmiButtonDealTaskInit(); // 15
#endif



}

/*********************************************************************************************************
 ** Function name:       SystemStartInit
 ** Descriptions:        System Start Init
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
void SystemStartInit(void)
{
    SystemSemaphoreInit();
    SystemTaskInit();
}


#endif /* APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_C_ */

八、在system_config.h文件里写入如下代码

在这里插入图片描述

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-27     Administrator       the first version
 */
#ifndef APPLICATIONS_SYSTEM_DEAL_SYSTEM_CONFIG_H_
#define APPLICATIONS_SYSTEM_DEAL_SYSTEM_CONFIG_H_

/* button config */
#define BUTTON_CONTROL_ENABLE 1

#endif /* APPLICATIONS_SYSTEM_DEAL_SYSTEM_CONFIG_H_ */

九、在applications文件夹下新建button_deal文件,再在button_deal文件下新建button_deal.cbutton_deal.h文件

在这里插入图片描述

十、包含button_deal.h头文件

在这里插入图片描述

十一、在button_deal.c中写入如下代码

在这里插入图片描述

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-27     Administrator       the first version
 */

#include "button_deal.h"

HmiButtonDev_t s_tHmiButtonDev;
static struct rt_semaphore s_tHmiButtonCtrSem;

/********************************************************************************************************
 ** Function name:       HmiButtonSemaphoreInit
 ** Descriptions:        Hmi Button Semaphore Init
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      rt_err_t
 *********************************************************************************************************/
rt_err_t HmiButtonSemaphoreInit(void)
{
    rt_err_t res;

    res = rt_sem_init(&s_tHmiButtonCtrSem, "HmiButtonCtrSem", 0, RT_IPC_FLAG_PRIO);
    if (res != RT_EOK)
    {
#if DEBUG_LOG_ENABLE
        rt_kprintf("Hmi Button Ctr Sem init failed!\n");
#endif
        return res;
    }

    return RT_EOK;
}


/*********************************************************************************************************
 ** Function name:       HmiButtonHwTimoutCallback
 ** Descriptions:        Hmi Button Hw Timout Callback
 ** input parameters:    dev : hw operation handle; size : hw msg size
 ** output parameters:   NONE
 ** Returned value:      rt_err_t
 *********************************************************************************************************/
static rt_err_t HmiButtonHwTimoutCallback(rt_device_t dev, rt_size_t size)
{
    //    rt_kprintf("ms: %d\n", rt_tick_get());
    rt_sem_release(&s_tHmiButtonCtrSem);
    return RT_EOK;
}


/*********************************************************************************************************
 ** Function name:       DrcTestBtnSingleClickHandler
 ** Descriptions:        Drv Test Button Single Click Handler
 ** input parameters:    button
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
static void DrcTestBtnSingleClickHandler(void* btn)
{
    rt_kprintf("DrcTestBtnSingle Enter!!!\r\n");
}


/*********************************************************************************************************
 ** Function name:       DrvTestPinRead
 ** Descriptions:        Drv Test Btn Pin Read
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
static uint8_t DrvTestPinRead(void) { return (rt_pin_read(HMI_BUTTON_TEST_PIN)); }


/*********************************************************************************************************
 ** Function name:       HmiButtonDealInit
 ** Descriptions:        Hmi Button Deal Init
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      pHmiButtonDev_t
 *********************************************************************************************************/
static pHmiButtonDev_t HmiButtonDealInit(void)
{
    rt_err_t res;
    pHmiButtonDev_t pHmiButtonDev = (pHmiButtonDev_t)&s_tHmiButtonDev;
    rt_memset((uint8_t*)&pHmiButtonDev->HwDev, 0, sizeof(HmiButtonDev_t));

    // set pin
    rt_pin_mode(HMI_BUTTON_TEST_PIN, PIN_MODE_INPUT_PULLUP);    //测试按键

    // button init
    button_init(&pHmiButtonDev->Test_Btn, DrvTestPinRead, PIN_LOW);

    // attach button
    button_attach(&pHmiButtonDev->Test_Btn, PRESS_DOWN, DrcTestBtnSingleClickHandler);

    // set timer
    pHmiButtonDev->HwDev = rt_device_find(HMI_BUTTON_HWTIMER_DEV_NAME);
    if (!pHmiButtonDev->HwDev)
    {
       rt_kprintf("/--> %s find failed! \n", HMI_BUTTON_HWTIMER_DEV_NAME);
    }
    res = rt_device_open(pHmiButtonDev->HwDev, RT_DEVICE_OFLAG_RDWR);
    if (RT_EOK != res)
    {
       rt_kprintf("/--> %s open err ...\n", HMI_BUTTON_HWTIMER_DEV_NAME);
    }

    pHmiButtonDev->HwFreq = HMI_BUTTON_HWTIMER_DEV_FREQ;
    res = rt_device_control(pHmiButtonDev->HwDev, HWTIMER_CTRL_FREQ_SET, &pHmiButtonDev->HwFreq);
    if (RT_EOK != res)
    {
       rt_kprintf("/--> %s freq set err ...\n", HMI_BUTTON_HWTIMER_DEV_NAME);
    }
    pHmiButtonDev->HwMode = HWTIMER_MODE_PERIOD;
    res = rt_device_control(pHmiButtonDev->HwDev, HWTIMER_CTRL_MODE_SET, &pHmiButtonDev->HwMode);
    if (RT_EOK != res)
    {
       rt_kprintf("/--> %s mode set err ...\n", HMI_BUTTON_HWTIMER_DEV_NAME);
    }
    pHmiButtonDev->HwTimeout.sec = HMI_BUTTON_HWTIMER_DEV_SEC;
    pHmiButtonDev->HwTimeout.usec = HMI_BUTTON_HWTIMER_DEV_USEC;



    if (rt_device_write(pHmiButtonDev->HwDev, 0, &pHmiButtonDev->HwTimeout, sizeof(rt_hwtimerval_t)) !=
        sizeof(rt_hwtimerval_t))
    {
       rt_kprintf("/--> %s set timeout err ...\n", HMI_BUTTON_HWTIMER_DEV_NAME);
    }
    rt_device_set_rx_indicate(pHmiButtonDev->HwDev, HmiButtonHwTimoutCallback);

    button_start(&pHmiButtonDev->Test_Btn);

    return pHmiButtonDev;
}


/*********************************************************************************************************
 ** Function name:       HmiButtonDeal
 ** Descriptions:        Hmi Button Deal
 ** input parameters:    pHmiButtonDev_t
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
static void HmiButtonDeal(pHmiButtonDev_t pHmiButtonDev)
{
    rt_err_t l_tErr;

    l_tErr = rt_sem_take(&s_tHmiButtonCtrSem, RT_WAITING_FOREVER);
    if (RT_EOK == l_tErr)
    {
        button_ticks();
    }
}

/*********************************************************************************************************
 ** Function name:       HmiButtonDeal_thread
 ** Descriptions:        Hmi Button Deal thread
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
static void HmiButtonDeal_thread(void* parameter)
{
    pHmiButtonDev_t l_ptHmiButtonDev = HmiButtonDealInit();
    while (1)
    {
       HmiButtonDeal(l_ptHmiButtonDev);
    }
}


/*********************************************************************************************************
 ** Function name:       HmiButtonDealTaskInit
 ** Descriptions:        Lift Moto Deal Task Init
 ** input parameters:    NONE
 ** output parameters:   NONE
 ** Returned value:      NONE
 *********************************************************************************************************/
void HmiButtonDealTaskInit(void)
{
    rt_thread_t HmiButtonDeal_tid;

    HmiButtonDeal_tid = rt_thread_create("btn_ctl", HmiButtonDeal_thread, RT_NULL, HMI_BUTTON_THREAD_STACK, HMI_BUTTON_THREAD_PRO,HMI_BUTTON_THREAD_TICK);
    if (HmiButtonDeal_tid != RT_NULL)
    {
        rt_thread_startup(HmiButtonDeal_tid);
    }
    else
    {
#if DEBUG_LOG_ENABLE
        rt_kprintf("/--> HmiButtonDeal_tid create failed!\n");
#endif
    }
}

十二、在button_deal.h文件中写入如下代码

在这里插入图片描述

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-27     Administrator       the first version
 */
#ifndef APPLICATIONS_BUTTON_DEAL_BUTTON_DEAL_H_
#define APPLICATIONS_BUTTON_DEAL_BUTTON_DEAL_H_

#include <rtdevice.h>
#include <rtthread.h>
#include "board.h"
#include "drv_common.h"

#include "multi_button.h"

#define HMI_BUTTON_THREAD_STACK 1024
#define HMI_BUTTON_THREAD_PRO 15
#define HMI_BUTTON_THREAD_TICK 10


#define HMI_BUTTON_TEST_PIN   GET_PIN(F, 3)          //测试按键


/* button hw time param */
#define HMI_BUTTON_HWTIMER_DEV_NAME "timer7"
#define HMI_BUTTON_HWTIMER_DEV_FREQ 1000000

#define HMI_BUTTON_HWTIMER_DEV_SEC 0
#define HMI_BUTTON_HWTIMER_DEV_USEC 5 * 1000

typedef struct
{
    rt_device_t HwDev;
    rt_hwtimerval_t HwTimeout;
    rt_uint32_t HwFreq;
    rt_hwtimer_mode_t HwMode;

    button Test_Btn;

} HmiButtonDev_t, *pHmiButtonDev_t;


rt_err_t HmiButtonSemaphoreInit(void);
void HmiButtonDealTaskInit(void);

#endif /* APPLICATIONS_BUTTON_DEAL_BUTTON_DEAL_H_ */

十三、打开CubeMX

在这里插入图片描述

十四、配置时钟源

在这里插入图片描述

十五、配置下载口

在这里插入图片描述

十六、打开定时器7,该定时器用来给按键库的周期调用函数用的

在这里插入图片描述

十七、打开串口一

在这里插入图片描述

十八、配置时钟线

在这里插入图片描述

十九、选择MDK-ARM

在这里插入图片描述

二十、选择生成.c和.h文件

在这里插入图片描述

二十一、生成代码

在这里插入图片描述

二十二、打开定时器设备驱动程序

在这里插入图片描述

二十三、打开定时器7宏定义

在这里插入图片描述

二十四、在tim_config.h文件中新增TIM7

在这里插入图片描述

二十五、在drv_hwtimer.c文件中新增TIM7_IRQHandler

在这里插入图片描述

二十六、继续在drv_hwtimer.c文件中按以下格式新增,TIM7中断相关的代码

在这里插入图片描述

二十七、编译一波,通过

在这里插入图片描述

二十八、再把这个工程编译脚本改一下

在这里插入图片描述

二十九、打开CubeMX重新生成一下代码

在这里插入图片描述

三十、这样就可以把这个CubeMX配置的定时器初始化单独提出来,方便我们查看修改

在这里插入图片描述

三十一、在TIM7初始化里添加TIM7中断优先级以及使能

在这里插入图片描述

三十二、按下按键,成功进入中断,收工!

在这里插入图片描述

三十三、最后,介绍一下代码中比较重要的地方

1、这里做了一个闪灯,这样可以目测板子有没有跑飞,想要对应到自己的板子,只需要改system_deal.h中的这个引脚宏定义即可

在这里插入图片描述
在这里插入图片描述

2、这里是设置按键中断事件的触发模式,对应按键触发枚举如下图,需要怎样的触发模式进按键事件中断修改这里即可。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关文章:

  • Windows 系统下 Android 开发常用快捷键‌的整理
  • CentOS 7.9 上安装 Docker Compose
  • cmake、CMakeLists.txt、make、ninja
  • 【Flink银行反欺诈系统设计方案】5.反欺诈系统全生命周期设计
  • 深入浅出:UniApp 从入门到精通全指南
  • nacos和Eureka的学习
  • python量化交易——金融数据管理最佳实践——使用qteasy大批量自动拉取金融数据
  • 《谈判力》核心原则解读
  • “RStudio UI“快速指南
  • MiniMind用极低的成本训练属于自己的大模型
  • 前后分离文件上传案例,前端HTML,后端Net6开发的webapi(完整源代码)下载
  • 【 <一> 炼丹初探:JavaWeb 的起源与基础】之 Servlet 与 JSP 的协作:MVC 模式的雏形
  • 《ARM64体系结构编程与实践》学习笔记(五)
  • 电脑的系统版本是windows7的,下载pycharm的哪个版本比较好呢?
  • 组合逻辑和时序逻辑
  • 每日一题----------匿名内部类的注意事项
  • SpringCloud注册中心-eureka
  • 【深度学习CV】【图像分类】从CNN(卷积神经网络)、ResNet迁移学习到GPU高效训练优化【案例代码】详解
  • YOLOv8 自定义目标检测
  • 【原创】C# HttpClient 读取流数据的问题
  • 以色列在加沙发起新一轮强攻,同步与哈马斯展开无条件谈判
  • 国际博物馆日|航海博物馆:穿梭于海洋神话与明代造船工艺间
  • 解读|战国子弹库帛书漂泊海外79年今归国,追索仍将继续
  • 新任重庆市垫江县委副书记刘振已任县政府党组书记
  • 《五行令》《攻守占》,2个月后国博见
  • 科普|认识谵妄:它有哪些表现?患者怎样走出“迷雾”?