Melis4.0[D1s]:7.lvgl добавить физические кнопки

Справочные материалы:
1. Видео станции B учителя Вэй Дуншаня: 3-3-1 Используйте физические кнопки вместо сенсорных (группы)
2. Автор: zhbi98, статья: lvgl8.x док-станция, драйвер физической кнопки
3. Baiwen.com lvgl Китайский документ: Клавиатура и энкодер (клавиатура и энкодер)

Поработав 2 дня, не смог достать драйвер I2c (сенсорный экран gt911) D1s под Мелис. Сначала проверьте физические кнопки.

1. lvgl зарегистрировать драйвер клавиатуры

1.1 Отправить сообщение в кнопку ADC мелис

В предыдущей статье, Melis4.0[D1s]: 1. Процесс запуска (часть, связанная с инициализацией кнопки adc) трассировка отмечает , драйвер кнопки ADC завершен, и сообщение отправлено напрямую в драйвере.
Как использовать очередь сообщений для отправки сообщений в rt-потоке, смотрите в официальной информации: Справочное руководство по API RT-Thread — Очередь сообщений .

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. Проверьте действие физических кнопок в графическом интерфейсе.

Применение физических кнопок (групп) в графическом интерфейсе требует 3 шагов:

1. Создать группу (Группы): lv_group_t * g = lv_group_create()
2. Затем добавить объект в группу (Группы): lv_group_add_obj(g, obj) Также можно указать группу по умолчанию: lv_group_set_default(g) 3.
Наконец, свяжите группы с устройствами ввода: 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 Результаты испытаний

вставьте сюда описание изображения

Guess you like

Origin blog.csdn.net/hwd00001/article/details/130106367