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.h、system_deal.c、system_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.c和button_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、这里是设置按键中断事件的触发模式,对应按键触发枚举如下图,需要怎样的触发模式进按键事件中断修改这里即可。