Melis4.0[D1s]:7.lvgl添加物理按键

这篇具有很好参考价值的文章主要介绍了Melis4.0[D1s]:7.lvgl添加物理按键。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考资料:
1.韦东山老师B站视频:3-3-1使用物理按键代替触摸(groups)
2.作者:zhbi98,文章:lvgl8.x 对接实体按键驱动
3.百问网lvgl中文文档:Keypad and encoder(键盘和编码器)

搞了2天,没有搞定D1s在Melis下的I2c驱动(gt911触摸屏)。先测试物理按键。

1.lvgl注册keypad驱动

1.1 在melis的ADC按键中发送消息

在前面的文章中Melis4.0[D1s]:1.启动流程(与adc按键初始化相关部分)跟踪笔记,已经做好ADC按键的驱动,直接在驱动中发送消息。
如何在rt-thread中使用消息队列发送消息,请参考官方资料: RT-Thread API参考手册-消息队列。

1.1.1 创建消息队列,并初始化

相关代码在 《D1s-Melis/ekernel/drivers/drv/source/input/keyboard/sunxi_keyboard.c》 中。完整内容点击链接 sunxi_keyboard.c。

/* 消息队列控制块 */
 struct rt_messagequeue mq;
/* 消息队列中用到的放置消息的内存池 */
static rt_uint8_t msg_pool[2048];
int sunxi_keyboard_init(void)
{
......
    rt_err_t result;
    /* 初始化消息队列 */
    result = rt_mq_init(&mq,
                        "mqt",
                        &msg_pool[0],               /* 内存池指向msg_pool */
                        1,                          /* 每个消息的大小是 1 字节 */
                        sizeof(msg_pool),           /* 内存池的大小是msg_pool的大小 */
                        RT_IPC_FLAG_FIFO);          /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
    if (result != RT_EOK)
    {
        rt_kprintf("init message queue failed.\n");
        return -1;
    }
    return 0;
}

1.1.2 扫描按键时,发送按下和松开消息

这部分代码也在 sunxi_keyboard.c 中。

int keyboard_irq_callback(uint32_t data_type, uint32_t data)
{
    if (data_type == GPADC_UP && key_flag == 1)
    {
......
                            /* 发送按键松开消息到消息队列中 */
                            key_data->compare_later = 0xf6;
                            result = rt_mq_send(&mq, &(key_data->compare_later), 1);
                            if (result != RT_EOK)
                            {
                                rt_kprintf("rt_mq_send ERR\n");
                            }
    }
    .......
                            __log("key: %d",key_data->compare_before);
                            /* 发送按键按下消息到消息队列中 */
                            result = rt_mq_send(&mq, &(key_data->compare_before), 1);
                            if (result != RT_EOK)
                            {
                                rt_kprintf("rt_mq_send ERR\n");
                            } 
    return 0;
}

1.2 编写读取按键的回调函数

这里只是通过消息队列读取按键按下和松开的消息。

收到按键按下的消息值为0,1,2,3,4;
收到按键松开的消息值为0xF6.

extern   struct rt_messagequeue mq;
uint8_t   msgbyte;
static void melis_keypad_driver_read_cb(lv_indev_drv_t* indev_drv,    lv_indev_data_t* data)
{
    /* 从消息队列中接收消息 */
    if (rt_mq_recv(&mq, (void *)&msgbyte, sizeof(msgbyte), RT_WAITING_NO) == RT_EOK)
    {
        rt_kprintf("read_cb: recv msg:%d\n", msgbyte);
        data->state = LV_INDEV_STATE_PR;
        switch (msgbyte)
        {
        case 0:
            data->key = LV_KEY_PREV;            break;
        case 1:
            data->key = LV_KEY_NEXT;            break;
        case 2:
            data->key = LV_KEY_ENTER;            break;
        case 3:
            data->key = LV_KEY_ENTER;            break;
        case 4:
            data->key = LV_KEY_ESC;            break;
        case 0xf6:
          data->state = LV_INDEV_STATE_REL;	break;
        default:
            break;
        }
    }
}

1.3 lvgl按键驱动注册

完成前面的准备工作后,就可以在 lv_main()中注册按键驱动,完成lvgl物理按键的初始化。
直接拷贝韦东山老师在windows下键盘的驱动,00_lv_100ask_sim_codeblocks_win/lv_drivers/win32drv/win32drv.c完整代码点击链接:

    static lv_indev_drv_t keypad_driver;
    lv_indev_drv_init(&keypad_driver);
    keypad_driver.type = LV_INDEV_TYPE_KEYPAD;
    keypad_driver.read_cb = lv_win32_keypad_driver_read_callback;
    lv_win32_keypad_device_object = lv_indev_drv_register(&keypad_driver);

把上面的代码稍作改动。

lv_win32_keypad_driver_read_callback --> melis_keypad_driver_read_cb
lv_win32_keypad_device_object --> g_keypad_device_object 【 说明:这个变量其他文件需要用到】

于是,改动后的代码如下(完整代码点击链接 lv_main.c):

#define   LV_USE_GPADC    1
lv_indev_t* g_keypad_device_object ;
static lv_disp_t * hal_init(void  )
{
......
#if   LV_USE_GPADC    
    static lv_indev_drv_t keypad_driver;
    lv_indev_drv_init(&keypad_driver);
    keypad_driver.type = LV_INDEV_TYPE_KEYPAD;
    keypad_driver.read_cb = melis_keypad_driver_read_cb;
    g_keypad_device_object = lv_indev_drv_register(&keypad_driver);
#endif
	lv_disp_t * disp = NULL;
  return disp;
}

2.在gui中测试物理按键效果

在gui中应用物理按键(groups)需要3个步骤:

1.要创建一个 组(Groups) : lv_group_t * g = lv_group_create();
2.然后将一个对象添加到 组(Groups) 中: lv_group_add_obj(g, obj); 也可以指定默认组:lv_group_set_default(g);
3.最后要将组(Groups)与输入设备相关联: lv_indev_set_group(g_keypad_device_object , g);

物理按键中有3个必备的按键消息,这3个消息就可以实现焦点切换和触发焦点对象:

消息名称 含义
LV_KEY_NEXT 聚焦到下一个对象
LV_KEY_PREV 聚焦到上一个对象
LV_KEY_ENTER 触发 LV_EVENT_PRESSED/CLICKED/LONG_PRESSED 等事件

其他消息:

消息名称 含义
LV_KEY_UP 增加值或向上移动
LV_KEY_DOWN 减少值或向下移动
LV_KEY_RIGHT 增加值或向右移动
LV_KEY_LEFT 减少值或向左移动
LV_KEY_ESC 关闭或退出(例如关闭 下拉列表)
LV_KEY_DEL 删除(例如 文本区域 中右侧的字符)
LV_KEY_BACKSPACE 删除左边的一个字符(例如在文本区域)
LV_KEY_HOME 跳到开头/顶部(例如在 文本区域)
LV_KEY_END 跳到最后(例如在 文本区域))

这里我使用了官方例程 lv_example_btn_1.c。

extern lv_indev_t* g_keypad_device_object ;
static void event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);

    if(code == LV_EVENT_CLICKED) {
        LV_LOG_USER("Clicked");
    }
    else if(code == LV_EVENT_VALUE_CHANGED) {
        LV_LOG_USER("Toggled");
    }
}

void lv_example_btn_1(void)
{
    lv_obj_t * label;

    // 创建一个组,稍后将需要使用键盘或编码器或按钮控制的部件(对象)添加进去,并且将输入设备和组关联
    // 如果将这个组设置为默认组,那么对于那些在创建时会添加到默认组的部件(对象)就可以省略 lv_group_add_obj()
    lv_group_t * g = lv_group_create();

    // 将上面创建的组设置为默认组
    // 如果稍后创建的部件(对象),使用默认组那必须要在其创建之前设置好默认组,否则不生效
    lv_group_set_default(g);

    lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
    lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_ALL, NULL);
    lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);

    label = lv_label_create(btn1);
    lv_label_set_text(label, "Button");
    lv_obj_center(label);

    lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
    lv_obj_add_event_cb(btn2, event_handler, LV_EVENT_ALL, NULL);
    lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40);
    lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
    lv_obj_set_height(btn2, LV_SIZE_CONTENT);

    label = lv_label_create(btn2);
    lv_label_set_text(label, "Toggle");
    lv_obj_center(label);

    lv_indev_set_group(g_keypad_device_object, g);
}

2.1 测试效果

Melis4.0[D1s]:7.lvgl添加物理按键文章来源地址https://www.toymoban.com/news/detail-419210.html

到了这里,关于Melis4.0[D1s]:7.lvgl添加物理按键的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 全志 Tina Linux LCD显示屏调试指南 支持MIPI DSI RGB LVDS I8080 SPI等接口,开发板支持百问网T113 D1-H哪吒 DongshanPI-D1s V853

    编写目的 本文档将介绍sunxi 平台Display Engine 模块中LCD 的调试方法。 LCD 调试方法,调试手段。 LCD 驱动编写。 lcd0 节点下各个属性的解释。 典型LCD 接口配置。 适用范围:sunxi 平台DE1.0/DE2.0 中LCD 屏幕参数设置。 表2-1: LCD 相关术语 术语 解释说明 SUNXI Allwinner 一系列SoC 硬件平台

    2024年02月02日
    浏览(45)
  • 简单的LVGL按键例程

    以下是一个简单的LVGL按键例程,使用LVGL的按键事件来处理按钮的单击和长按操作。 在这个例程中,我们创建了一个名为 btn 的按钮对象,并将其添加到当前活动屏幕上。然后,在按钮上创建了一个标签并设置了文本内容。接着,我们使用 lv_obj_set_event_cb() 函数注册了按钮事件

    2024年02月03日
    浏览(32)
  • lvgl8.x 对接实体按键驱动

    实体按键属于 lvgl 的输入设备中的一种,所以对接外部的硬件实体按键实际上就是为 lvgl 添加输入设备。为 lvgl 添加输入设备需要在 lv_port_indev.c 这个 c 文件中完成, 注意这个文件并不存在于 lvgl src 源码文件夹下,而是位于 examples/porting 文件夹下,在这个目录下官方为我们准

    2024年02月11日
    浏览(36)
  • Android物理按键事件处理

    当处理物理按钮事件的时候提供的回调方法有 onKeyDown() onKeyUp() onKeyLongPress() 如下是例子:返回键被按下,提示退出程序 按键名 中文名 code KEYCODE_POWER 电源键 26 KEYCODE_HOME HOME键 3 KEYCODE_BACK 返回键 4 KEYCODE_MENU 菜单键 82 KEYCODE_CAMERA 拍照键 27 KEYCODE_VOLUME_UP 音量增加键 24 KEYCODE_VOL

    2023年04月11日
    浏览(39)
  • 基于Quartus Prime平台FPGA关于VGA显示的模块化设计:VGA八种单色屏1s切换显示、横条纹、竖条纹、棋盘格显示、显示模式按键可调、数码管显示单色屏序号

    VGA(Video Graphics Array)是一种显示接口标准,它最初由IBM于1987年推出。VGA协议定义了计算机视频输出信号的格式和特性。它主要用于连接计算机和显示器之间的传输,实现图像和视频的显示。 VGA协议支持最高分辨率为640x480像素,色彩深度为16位色(即65,536种颜色)。它使用模

    2024年02月03日
    浏览(50)
  • UE4 添加按键输入事件 并在蓝图中使用按键输入节点

    选择Edit/ProjectSettings/Engine/Input 在bindings中可以选择添加ActionMappings或则AxisMappings ActionMappings:按键事件,有按下和抬起两个事件,需要分别用两个键触发 AxisMappings:输入事件,返回值为float,对于键盘,值为0和1 ,对于摇杆为0-1 新建一个事件 : 点击ActionMappings或AxisMappings后的

    2024年01月20日
    浏览(43)
  • 网络参考资料汇总(1)

    将这段时间参考的各路大佬的资料加以汇总分类: (1)FFmpeg: 基于FFmpeg进行rtsp推流及拉流(详细教程) Linux 编译安装 FFmpeg 步骤(带ffplay) Jetson 环境安装(三):jetson nano配置ffmpeg和nginx(亲测) Linux编译FFmpeg libx264 libx265 libfdk-aac libmp3lame libvpx libopus等 ffmpeg推流时报错 Unknown encod

    2024年02月07日
    浏览(43)
  • Flutter参考资料

    Flutter 官网 : https://flutter.dev/ Flutter 插件下载地址 : https://pub.dev/packages Flutter 开发文档 : https://flutter.cn/docs ( 强烈推荐 ) 官方 GitHub 地址 : https://github.com/flutter Flutter 中文社区 : https://flutter.cn/ Flutter 实用教程 : https://flutter.cn/docs/cookbook Flutter CodeLab : https://codelabs.flutter-io.cn/ Dart 中

    2024年02月13日
    浏览(42)
  • webgis开发参考资料

    http://zhihu.geoscene.cn/article/1038 2、arcgis server 紧促(bundle)格式缓存文件的读取 https://blog.csdn.net/abc553226713/article/details/8668839 3、ArcGIS 10.0紧凑型切片读写方法 https://www.cnblogs.com/yuantf/p/3320876.html 4、发布地图服务时导入已有的tpk切片包作为缓存 https://blog.csdn.net/hellfire2007/article/de

    2024年02月08日
    浏览(49)
  • 【Linux上创建一个LVM卷组,将多个物理卷添加到卷组中使用】

    实现在Linux上创建一个LVM卷组,将多个物理卷添加到卷组中,创建一个逻辑卷,格式化该逻辑卷并将其挂载到指定目录,扩展逻辑卷的大小并调整文件系统大小以适应扩展 使用命令: 使用命令: 过程如下: fdisk /dev/sdb :这条命令打开了一个名为 /dev/sdb 的设备的分区表编辑模

    2024年01月21日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包