玩转RT-Thread系列教程(5)--MultiButton-可以无限拓展按键的组件


玩转RT-Thread系列教程(5)–MultiButton-可以无限拓展按键的组件

一、MultiButton介绍

MultiButton设计思想

1.1:面向对象思想

MultiButton中每个按键都抽象为了一个按键对象,每个按键对象是独立的,系统中所有的按键对象使用单链表串起来。

其中在变量后面跟冒号的语法称为位域,使用位域的优势是节省内存。

第一次插入时,因为head_hanler 为 NULL,所以只需要执行while之后的代码.

如果再插入一个buuton2按键对象:

1.2:状态机处理思想

  1. 读取当前引脚状态

  1. 读取之后,判断当前状态机的状态,如果有功能正在执行(state不为0),则按键对象的tick值加1(后续一切功能的基础)

  1. 按键消抖(连续读取3次,15ms,如果引脚状态一直与之前不同,则改变按键对象中的引脚状态)

  1. 状态机

—MultiButton参考Mculover666教程,感谢大佬让我学习到很多。

二、添加软件包

1.menuconfig

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.更新下载软件包

在这里插入图片描述

3.生成mdk工程

在这里插入图片描述

4.添加button_app.c

在这里插入图片描述

三、示例使用

1.查看电路原理图

在这里插入图片描述

在这里插入图片描述

2.在Button_APP.c中添加按键驱动

#include "button_app.h"

extern struct key_state_type key0;
extern struct key_state_type key1;

static Button_t button_0;
static Button_t button_1;

//read button 0 level
uint8_t button0_read_level(void)
{
    return rt_pin_read(KEY_0);
}

//button 0 down callback
void button0_down_callback(void *btn)
{
    key0.down_state = KEY_PRESS;
}

// button 0 long callback
void button0_double_callback(void *btn)
{
    key0.double_state = KEY_PRESS;
}

// button 0 long callback
void button0_long_callback(void *btn)
{
    key0.long_state = KEY_PRESS;
}

//read button 1 level
uint8_t button1_read_level(void)
{
    return rt_pin_read(KEY_1);
}
//button1 down callback
void button1_down_callback(void *btn)
{
    key1.down_state = KEY_PRESS;
}
// button1 long callback
void button1_double_callback(void *btn)
{
    key1.double_state = KEY_PRESS;
}
// button 1 long callback
void button1_long_callback(void *btn)
{
    key1.long_state = KEY_PRESS;
}

void key_process(void)
{
    Button_Process();
}

int    key_init(void)
{
    //button gpio init
    rt_pin_mode(KEY_0, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(KEY_1, PIN_MODE_INPUT_PULLUP);

    //button create
    Button_Create("button_0", &button_0, button0_read_level, PIN_LOW);
    Button_Create("button_1", &button_1, button1_read_level, PIN_LOW);

    //set button callback
    Button_Attach(&button_0, BUTTON_DOWM, button0_down_callback);
    Button_Attach(&button_0, BUTTON_DOUBLE, button0_double_callback);
    Button_Attach(&button_0, BUTTON_LONG, button0_long_callback);

    Button_Attach(&button_1, BUTTON_DOWM, button1_down_callback);
    Button_Attach(&button_1, BUTTON_DOUBLE, button1_double_callback);
    Button_Attach(&button_1, BUTTON_LONG, button1_long_callback);

    return RT_EOK;
}

INIT_APP_EXPORT(key_init);

3.按键功能编写

//定义key 控制块
struct key_state_type key0 = { 0 };
struct key_state_type key1 = { 0 };

int main(void)
{
    while(1)
    {
        key_process();

        if(key0.double_state == KEY_PRESS)
        {
            rt_kprintf("key0 is double_pass\n");
                        key0.double_state = KEY_RELEASE;
        }
        else if (key0.long_state == KEY_PRESS)
        {
            rt_kprintf("key0 is long_pass\n");
                        key0.long_state = KEY_RELEASE;
        }

        if(key1.double_state == KEY_PRESS)
        {
            rt_kprintf("key1 is double_pass\n");
                        key1.double_state = KEY_RELEASE;
        }
        else if (key1.long_state == KEY_PRESS)
        {
            rt_kprintf("key1 is long_pass\n");
                        key1.long_state = KEY_RELEASE;
        }

                rt_thread_mdelay(10);
    }
}

4.编译、下载、查看

可以看到我们的按键双击,长按释放事件已经得到响应。


文章作者: Rb菌
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rb菌 !
  目录