參考 [LVGL]LVGL库入门教程-LVGL简介与基本控件 - LVGL教程玩法
LVGL 可在任何现代 MCU 或 MPU 上运行。* 架构:16、32 或 64 位
- 时钟速度:> 64MHz
- **RAM:**4kB + 150byte /小部件(对于具有几个屏幕的UI~48kB)
- 闪存:~100kB(LVGL)(取决于启用的功能)
- 绘制缓冲区:> 1/10 屏幕大小的缓冲区用于渲染
- 帧缓冲器:显示控制器、内部或外部RAM中至少有1个帧缓冲器
- 编译器:C99 或更高版本
- 构建系统:LVGL 没有外部依赖。只需将其复制到您的项目中,并将其与项目的其他文件一起编译即可
UI 功能
许多小部件
LVGL 带有 30+ 内置小部件,例如弧形、条形、日历、图表、复选框、下拉列表、键盘、仪表、消息框、开关、表格、选项卡视图、文本区域。
有了这些小部件,您在智能手机应用程序中看到的内容也可以通过 LVGL 实现。
这些小部件可以实时创建和删除。这样,您可以通过动态创建当前可见的屏幕和小部件来节省 RAM。
渲染功能
LVGL 带有强大的软件渲染引擎,可以使用最少的资源以矢量图形方式绘制抗锯齿小部件。
- 半径矩形
- 边框与半径
- 水平梯度和垂直梯度
- 框阴影
- 歪斜线
- 弧
- 缩放和旋转图像或任何小部件
- 掩蔽
风格
您可以从 100+ 样式属性中进行选择,以设置小部件运行时的样式。它可以动态更改 UI 的主题,甚至对样式进行动画处理。它还可以节省闪光灯,因为您需要使用更少的图像。
小部件可以在任何状态下设置样式,例如按下、选中、聚焦、禁用。小部件的任何部分也可以自定义。例如,滑块由主、指示灯和旋钮部分组成,其外观可以自由调节。
最重要的是,通过使用您所做的过渡,LVGL 可以在状态更改时自动为样式制作动画。
LVGL的初始化
在使用LVGL之前前,你需要调用以下三个个函数完成LVGL库的初始化以及LVGL显示设备接口的初始化,其中lv_init()与lv_port_disp_init()方法必须添加,lv_port_indev_init()用于触摸:
// lvgl 初始化
lv_init();
// 初始化显示器和创建用于绘图的缓冲区
lv_port_disp_init();
//找到 LittelvGL 支持的输入设备
lv_port_indev_init();
然后我们就可以,写我们第一个LVGL的应用“Hello world”:
/*更改活动屏幕的背景颜色*/
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x003a57), LV_PART_MAIN);
/*创建一个白色标签,设置其文本并将其与中心对齐*/
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello world");
lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
要处理 LVGL 的任务,您需要定期调用以下命令之一:
lv_task_handler()
- main() 函数的 while(1)
- 定时器周期性中断(低优先级
lv_tick_inc())
- 定期执行操作系统任务
时间并不重要,但应该大约是 5 毫秒,以保持系统响应。
while(1) {
lv_task_handler();
usleep(5 * 1000);
//bflb_mtimer_delay_ms(5);
}
然后将编译得到的结果使用模拟器打开,就可以在窗口上看到带有“Hello world”字样的蓝色窗口:

LVGL输入设备的类型
如果只有显示设备没有输入的话,那么用户就没办法交互了。所以输入设备必不可少,下面介绍一下LVGL输入设备。
LVGL 所支持的输入设备有以下几种:
- 1、触摸板或鼠标
- 2、键盘或小键盘
- 3、具有左/右转和推动选项的编码器
- 4、外部按钮
要注册输入设备,必须初始化一个变量:lv_indev_drv_t
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*基本初始化*/
indev_drv.type =... /*见type介绍*/
indev_drv.read_cb =... /*见read_cb 介绍*/
/*在 LVGL 中注册驱动程序并保存创建的输入设备对象*/
lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);
**type**可以是
LV_INDEV_TYPE_POINTER触摸板或鼠标
LV_INDEV_TYPE_KEYPAD键盘或小键盘
">LV_INDEV_TYPE_ENCODER具有左/右转和推动选项的编码器
LV_INDEV_TYPE_BUTTON外部按钮几乎按压屏幕
b是一个函数指针,将定期调用它来报告输入设备的当前状态。
触摸板、鼠标或任何指针
可以点击屏幕上的点的输入设备属于此类别。
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_input_read;
...
void my_input_read(lv_indev_drv_t * drv, lv_indev_data_t*data)
{
if(touchpad_pressed) {
data->point.x = touchpad_x;
data->point.y = touchpad_y;
data->state = LV_INDEV_STATE_PRESSED;
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
}
小键盘或键盘
带有所有字母的完整键盘或带有几个导航按钮的简单小键盘都属于这里。
要使用键盘/小键盘:
- 使用 type 注册函数。
read_cb LV_INDEV_TYPE_KEYPAD
- 必须创建一个对象组:
lv_group_t * g = lv_group_create() 并且必须使用 lv_group_add_obj(g,obj)
- 必须将创建的组分配给输入设备:(
my_indev 是 lv_indev_drv_register 的返回值 )
- 使用
LV_KEY_... 在组中的对象之间进行导航。可用的KEY可以查看 lv_core/lv_group.h
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
indev_drv.read_cb = keyboard_read;
...
void keyboard_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
data->key = last_key(); /*获取上次按下或释放的键*/
if(key_pressed()) data->state = LV_INDEV_STATE_PRESSED;
else data->state = LV_INDEV_STATE_RELEASED;
}
编码器
使用编码器,您可以做 4 件事:
- 按下它的按钮
- 长按其按钮
- 左转
简而言之,编码器输入设备的工作方式如下:
- 通过转动编码器,您可以专注于下一个/上一个对象。
- 当您在简单对象(如按钮)上按下编码器时,它将被单击。
- 如果在复杂对象(如列表、消息框等)上按下编码器,则该对象将进入编辑模式,转动编码器即可在对象内导航。
- 要离开编辑模式,请长按按钮。
要使用编码器(类似于键盘),应将对象添加到组中。
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = encoder_read;
...
void encoder_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
data->enc_diff = enc_get_new_moves();
if(enc_pressed()) data->state = LV_INDEV_STATE_PRESSED;
else data->state = LV_INDEV_STATE_RELEASED;
}
按钮
按钮是指屏幕旁边的外部“硬件”按钮,这些按钮被分配给屏幕的特定坐标。 如果按下按钮,它将模拟按下指定的坐标。(类似于触摸板)
lv_indev_set_button_points(my_indev,points_array)
points_array const lv_point_t points_array[] ={{12,30},{60,90},...}
indev_drv.type = LV_INDEV_TYPE_BUTTON;
indev_drv.read_cb = button_read;
...
void button_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
static uint32_t last_btn = 0; /*存储上次按下的按钮*/
int btn_pr = my_btn_read(); /*获取 (0,1,2...) 按下按钮 ID */
if(btn_pr >= 0) { /*判断按钮是否按下 ( -1 没有按下按钮)*/
last_btn = btn_pr; /*保存按下按钮的 ID */
data->state = LV_INDEV_STATE_PRESSED; /*设置按钮按下状态*/
} else {
data->state = LV_INDEV_STATE_RELEASED; /*设置按钮释放状态*/
}
data->btn = last_btn; /*保存按钮*/
}
使用LVGL模拟器
对于单片机或者MCU来说使用LVGL图形库,进行开发如果每次改动都通过编译和烧录进行效果确认,那么是非常耗时的一个操作。工作效率也很低,而且比较繁琐。那么有没有一种方式可以直接预览画面而不进行烧录和编译进行效果的查看呢,答案是肯定的 LVGL 为我们提供了PC端的模拟器,它可以在 PC 端上直接生成可交互的界面,无需编译烧录即可查看绘制效果。

如图,这个就是模拟器上面运行的效果。