LVGL触控设计

触屏架构

LVGL对于输入设备单独使用一个文件lv_port_indev.c来进行管理。

触屏通过#define TOUCHPAD_DEV 1 来进行开启。用户需要设置

touchpad_init(void)
touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
static bool touchpad_is_pressed(void)
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)

这几个API来实现使用触控设备对LVGL的输入。

普通触屏架构设计就是直接将对应的API传入供LVGL调用即可。这样可以完成基本的功能,但是如果考虑到调用api占用的CPU和时间开销,这显然是不可以接受的。所以在RTOS的环境下,需要为触控的数据获取单独创建一个线程来进行读取。LVGL只需要在需要获取触控数据的时候去内存读取最新的触控数据即可。这样还可以适配多点触控的环境。

可能有人有疑问,为什么要一直读取呢?这样不会浪费数据吗?这其实也是对LVGL的输入设备的理解不充分。LVGL的输入和输出一样,都是根据宏来控制周期的。输入设备依靠

/*Input device read period in milliseconds*/
#define LV_INDEV_DEF_READ_PERIOD 20     /*[ms]*/

这个宏来控制周期。也就是每20ms(period)进行一次数据读取以及对应的更新。在里面进行阻塞式的数据读取会降低LVGL的帧率,降低动画流畅度。

下面是一个简单的基于时间轴的演示,

时间(ms):   0   5   10  15  20  25
Touch采样:  X       X       X
LVGL读取:       R   R   R   R   R

touch_task的采样周期为10ms,LVGL的读取周期为5ms。

在0ms/10ms/20ms时,touch_task进行采样。

在5mx/10mx/15mx/20ms/25ms时,LVGL调用API从内存中拷贝触屏数据。

在动画上这样的设计更加流畅,而且也可以在采样后进行滤波,校正坐标。

一个很重要的点:LVGL读取的触屏数据是一个状态,而不是一个瞬时时间。每次的触摸更新应该保证至少被读取一次。

┌──────────────┐
│   Touch IC   │  (I2C / SPI / INT)
└──────┬───────┘
       │
┌──────▼────────┐
│ Touch Task    │  ← 周期 or 中断触发
│ - 读硬件      │
│ - 去抖 / 滤波 │
│ - 坐标校正    │
└──────┬────────┘
       │
┌──────▼────────┐
│ Touch Buffer  │  ← 共享内存 / 结构体
│ (最新一帧)     │
└──────┬────────┘
       │
┌──────▼────────┐
│ LVGL indev    │  ← lv_indev_read_cb
│ 只拷贝数据     │
└───────────────┘
posted @ 2025-12-22 15:35  大葱团  阅读(1)  评论(0)    收藏  举报