LVGL从按键按下到回调函数触发的完整流程
以下是LVGL从检测到物理按键按下,到最终执行注册的回调函数的详细步骤分解:
1. 硬件输入检测
- 物理按键按下:用户按下硬件上的按键,触发中断或轮询检测。
- 输入设备驱动:LVGL通过注册的输入设备驱动(如
lv_indev_drv_t)获取原始输入。// 示例:初始化按键输入设备 lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_KEYPAD; indev_drv.read_cb = keypad_read; // 自定义读取函数 lv_indev_t *keypad_indev = lv_indev_drv_register(&indev_drv);
2. 输入事件处理
- 驱动上报事件:在
read_cb函数中,驱动将按键状态(按下/释放)和键值(如LV_KEY_ENTER)上报给LVGL。static void keypad_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { data->key = get_key(); // 获取键值(如LV_KEY_ENTER) data->state = get_state(); // 获取状态(LV_INDEV_STATE_PRESSED/RELEASED) }
3. LVGL事件检测
- 事件类型识别:LVGL根据输入状态和时间判断事件类型:
- 短按:按下后立即释放 →
LV_EVENT_CLICKED - 长按:按下持续时间超过阈值(默认
LV_INDEV_DEF_LONG_PRESS_TIME,通常1秒) →LV_EVENT_LONG_PRESSED - 持续按压:按住不放 →
LV_EVENT_LONG_PRESSED_REPEAT - 释放 →
LV_EVENT_RELEASED
- 短按:按下后立即释放 →
4. 确定目标对象
- 焦点对象:LVGL通过输入设备的
group机制确定当前聚焦的对象(如按钮)。// 将输入设备与对象组关联 lv_group_t *group = lv_group_create(); lv_group_add_obj(group, btn); // 将按钮加入组 lv_indev_set_group(keypad_indev, group);
5. 事件分发流程
-
生成事件包:创建
lv_event_t结构体,包含事件类型、目标对象等信息。lv_event_t e; e.code = LV_EVENT_CLICKED; e.target = btn; e.current_target = btn; -
遍历回调链表:从目标对象的回调链表中查找匹配的事件处理函数。
btn的事件回调链表: [回调1] → 监听LV_EVENT_ALL [回调2] → 监听LV_EVENT_CLICKED [回调3] → 监听LV_EVENT_LONG_PRESSED
6. 执行回调函数
- 按顺序执行:遍历链表,对每个回调检查事件掩码是否匹配。
// 伪代码:事件分发逻辑 for (lv_event_cb_t *cb = btn->event_cb_list; cb != NULL; cb = cb->next) { if (cb->filter & e.code) { // 检查事件掩码 cb->cb(&e); // 执行回调函数 if (e.stop_processing) break; // 如果事件被停止,终止遍历 } }
7. 回调函数响应
- 处理事件:在回调函数中执行具体操作,如改变按钮颜色或跳转页面。
void btn_event_handler(lv_event_t *e) { lv_event_code_t code = lv_event_get_code(e); lv_obj_t *btn = lv_event_get_target(e); if (code == LV_EVENT_CLICKED) { lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_RED), 0); } }
完整流程图示
按键按下 → 驱动上报 → LVGL检测事件类型 → 确定目标对象 → 遍历回调链表 → 执行匹配的回调
关键机制总结
| 步骤 | 关键操作 | 耗时 |
|---|---|---|
| 硬件输入 | 通过中断或轮询检测按键状态 | 微秒级 |
| 事件检测 | 计时器判断长按/短按 |


1447

被折叠的 条评论
为什么被折叠?



