LVGL V9增加实体按键 驱动层和应用层的处理

最近因为工作,也在学习了一些关于LVGL的内容,整体环境目前是:一个单片机,外接一个屏幕,目前屏幕是已经点亮和有触摸;但还希望在这个为基础,增加一些按键控制的环节,比如上下左右,进入返回这些的操作,所以有了这篇文章;

此贴目的:基于LVGL V9版本,在驱动层注册键盘keypad,初始化,将想要的引脚接口配置好,读到他的GPIO电平,当按键被按下后,触发,然后再讲这个值传输到上层AP层,AP层的UI做出相对应的反应。

以下为驱动层方面的处理:

做一个整体去初始化设备的函数lv_port_indev_init,在这个函数中对keypad做初始化和注册键盘,读取键盘的处理;

C 复制代码
void lv_port_indev_init(void)
{
	//此处只用键盘初始化做示例,如果对其他IO设备有需求的话,也可以增加,例如:鼠标,encoder,touchpad等
    keypad_init();
    indev_keypad = lv_indev_create();
    lv_indev_set_type(indev_keypad, LV_INDEV_TYPE_KEYPAD);
    lv_indev_set_read_cb(indev_keypad, keypad_read);
}

后续在keypad初始化中,对想要的GPIO口进行相应的处理:

C 复制代码
#define KEY_PIN1     "PD.2"

static void keypad_init(void)
{
    static u32 pin = 0;
    pin = gpio_pin_check(KEY_PIN1, GPIO_SET_MODE_FLAG);

    rt_pin_mode(pin, PIN_MODE_INPUT_PULLUP);

    rt_pin_attach_irq(pin, PIN_IRQ_MODE_RISING_FALLING,
                      gpio_input_irq_handler, &pin);

    rt_pin_irq_enable(pin, PIN_IRQ_ENABLE);
}

当然,不可或缺的还有keypad_read

C 复制代码
static void keypad_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
    static uint32_t last_key = 0;
    /*Get whether the a key is pressed and save the pressed key*/
    uint32_t act_key = keypad_get_key();
    if(act_key != 0) {
        data->state = LV_INDEV_STATE_PR;

        /*Translate the keys to LVGL control characters according to your key definitions*/
        switch(act_key) {
            case 1:
                act_key = LV_KEY_DOWN;
                break;
            case 2:
                act_key = LV_KEY_UP;
                break;
            case 3:
                act_key = LV_KEY_LEFT;
                break;
            case 4:
                act_key = LV_KEY_RIGHT;
                break;
            case 5:
                act_key = LV_KEY_ENTER;
                break;
        }

        last_key = act_key;
    }
    else {
        data->state = LV_INDEV_STATE_REL;
    }
    data->key = last_key;
}

随后的话,在get key的函数中也要做相对应的处理,实际上这些都是环环相扣的,初始化中会包含读,读中又包含获取,才能相对应上

C 复制代码
/*Get the currently being pressed key.  0 if no key is pressed*/
static uint32_t keypad_get_key(void)
{
    /*Your code comes here*/
    static uint8_t last_key = 0;
    uint8_t current_key = 0;
    if (key_trigger == 1) {
        key_trigger = 0;
        current_key = 1;  
    }

    if(current_key != 0) {
        last_key = current_key;
        return current_key;
    }
    
    return 0;
}

后续的话就是需要在应用层做处理,在keypad_read中已经把值返回到对应的LV_KEY_DOWN/LV_KEY_UP/LV_KEY_LEFT/LV_KEY_RIGHT,故在应用层中比较重要的就是需要去获取这个key,其中的步骤我们一步步来:

1、需要有一个lv_group_t *menu_group,并增加初始化;

C 复制代码
static lv_group_t *menu_group;

void lv_init_group()
{
    menu_group = lv_group_create();

    lv_group_set_editing(menu_group, false);
    lv_indev_set_group(indev_keypad,menu_group);
}

2、在你的组中增加obj,例如把btn加进这个group中;

C 复制代码
lv_group_add_obj(menu_group,btn);

3、给你的btn增加需要动的操作,并且增加focus属性!(最重要,没有这个属性将不会有任何响应)

然后才是对这个focus进行移动,例如lv_group_focus_next

C 复制代码
lv_obj_add_event_cb(btn, menu_key_cb, LV_EVENT_KEY, NULL);

lv_group_focus_obj(current_selected_btn); // 给当前选中的按钮增加focus

static void menu_key_cb(lv_event_t *e)
{
    lv_event_code_t event_code = lv_event_get_code(e);
    lv_obj_t * target = lv_event_get_target(e);

    printf("get_key :%d\n", event_code);
    if (event_code == LV_KEY_LEFT)
    {
        lv_group_focus_next(menu_group);
    }

}

4、最后就是大功告成,可以看到效果了!

总结:

整体的LVGL功能其实不难,但就是有几个需要注意的点,例如:必须把输入设备绑定 group、需要把按钮加入进group、按钮还需要增加focus、回调属性(类似qt的信号槽);

相关推荐
liulilittle8 小时前
TCP UCP:基于卡尔曼滤波的BBR增强型拥塞控制算法
linux·网络·c++·tcp/ip·算法·c·通讯
weixin_421725261 天前
C语言、C++与C#深度研究报告:从底层控制到现代企业级开发的演进
c语言·c++·c·内存管理·编译模型
不吃土豆的马铃薯3 天前
Spdlog 入门:日志记录器与日志槽基础详解
服务器·开发语言·c++·c·日志·spdlog
金创想4 天前
积木移动题目分析及解题思路——木块问题(1)
c++·算法·字符串·c·刷题·信息学奥赛·积木
不吃土豆的马铃薯7 天前
5.SGI STL 二级空间配置器 _S_chunk_alloc核心函数解析
开发语言·c++·vscode·c·内存池
一只小灿灿8 天前
深度详解计算机补码原理
c·补码
liulilittle8 天前
TCP UCP v1.0 拥塞控制算法(Linux Kernel CC-A)
linux·网络·网络协议·tcp/ip·c·通信·拥塞控制
weixin_421725268 天前
Linux 编程语言全解析:C、C++、Python、Go、Rust 谁更强?
linux·python·go·c·编程语言
REDcker8 天前
C++循环与编译器优化详解 别名不变量向量化与GCC Clang验证及perf实践
java·jvm·c++·c·clang·gcc
charlie11451419110 天前
通用GUI编程技术——图形渲染实战(四十三)——D3D12设计哲学:显式控制与性能解锁
学习·3d·c·图形渲染·win32