简介
LVGL(轻量级和通用图形库)是一个免费和开源的图形库,提供UI通信元素的构建接口与较低资源实现的源码,适用于快速开发UI图形交互页面的应用
官方已经适配了ESP32硬件平台,库版本为v7.11,开箱即用
如有异议,欢迎留言指正
特性
强大的构建块,例如按钮、图表、列表、滑块、图像等。带有动画、抗锯齿、不透明度、平滑滚动的高级图形各种输入设备,如触摸板、鼠标、键盘、编码器等。多语言支持 UTF-8 编码多显示器支持,即同时使用多个 TFT、单色显示器具有类似 CSS 样式的完全可定制的图形元素独立于硬件:与任何微控制器或显示器一起使用可扩展:能够以很少的内存运行(64 kB Flash,16 kB RAM)支持但不要求操作系统、外部存储器和 GPU即使具有高级图形效果,也可进行单帧缓冲区操作用 C 编写以获得最大的兼容性(C++ 兼容)在没有嵌入式硬件的 PC 上启动嵌入式 GUI 设计的模拟器绑定到 MicroPython快速 GUI 设计的教程、示例、主题文档可在线获取并以 PDF 格式提供在 MIT 许可下免费和开源硬件要求
软件源码
系统框架
源码下载
建议IDF使用v4.0以上版本,github仓库地址,克隆到本地并同步子模块
工程结构
lvgl:核心图像库lv_drivers:适配显示驱动,适配了主流芯片方案的驱动代码lv_examples:例程代码,内部提供了刷屏与压测的实例工程配置
使用命令配置工具idf.py menuconfig
,通过Kconfig文件,来适配具体的硬件与例程的选择
适配控制器驱动:路径Componenet config-->LVGL TFT Display controller
,选择驱动与适配PIN脚
修改分辨率与颜色深度:路径Componenet config-->LVGL configuration
触摸控制器:路径Componenet config-->LVGL Touch controller
,不带触摸的选None
选择实例demo:路径Componenet config-->LVGL Touch controller
,可以选择需要演示的例程
处理流程
代码解读
app_main入口中创建了guiTask任务,截取guiTask内部分代码xGuiSemaphore = xSemaphoreCreateMutex();//创建互斥变量(限制多线程的访问lvgl接口)lv_init(); //初始化 lvgl 库lvgl_driver_init(); //初始化驱动(SPI、IIC总线)lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);//开辟支持dma服务的缓存assert(buf1 != NULL);//双缓存#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROMElv_color_t* buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);assert(buf2 != NULL);#elsestatic lv_color_t *buf2 = NULL;#endifstatic lv_disp_buf_t disp_buf;//lvgl显示缓存区lv_disp_buf_init(&disp_buf, buf1, buf2, size_in_px);//初始化工作缓存区lv_disp_drv_t disp_drv;lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = disp_driver_flush;//刷屏实现接口//触摸控制器#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONElv_indev_drv_t indev_drv;lv_indev_drv_init(&indev_drv);indev_drv.read_cb = touch_driver_read;indev_drv.type = LV_INDEV_TYPE_POINTER;lv_indev_drv_register(&indev_drv);#endif//创建软定时器, 内部实现 lv_tick_inc定时,处理相关lvgl任务操作const esp_timer_create_args_t periodic_timer_args = {.callback = &lv_tick_task,.name = "periodic_gui"};esp_timer_handle_t periodic_timer;ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));//具体应用create_demo_application();while (1) {/* Delay 1 tick (assumes FreeRTOS tick is 10ms */vTaskDelay(pdMS_TO_TICKS(10));/* Try to take the semaphore, call lvgl related function on success */if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY))//获取互斥信号 {lv_task_handler(); //lv任务处理器xSemaphoreGive(xGuiSemaphore); //是否互斥信号}}
运行应用函数lv_demo_widgets,例程执行了小部件动画的演示
void lv_demo_widgets(void){tv = lv_tabview_create(lv_scr_act(), NULL); //创建表格对象tv//主题设置#if LV_USE_THEME_MATERIALif(LV_THEME_DEFAULT_INIT == lv_theme_material_init) {lv_disp_size_t disp_size = lv_disp_get_size_category(NULL);if(disp_size >= LV_DISP_SIZE_MEDIUM) {lv_obj_set_style_local_pad_left(tv, LV_TABVIEW_PART_TAB_BG, LV_STATE_DEFAULT, LV_HOR_RES / 2);lv_obj_t * sw = lv_switch_create(lv_scr_act(), NULL);if(lv_theme_get_flags() & LV_THEME_MATERIAL_FLAG_DARK)lv_switch_on(sw, LV_ANIM_OFF);lv_obj_set_event_cb(sw, color_chg_event_cb);lv_obj_set_pos(sw, LV_DPX(10), LV_DPX(10));lv_obj_set_style_local_value_str(sw, LV_SWITCH_PART_BG, LV_STATE_DEFAULT, "Dark");lv_obj_set_style_local_value_align(sw, LV_SWITCH_PART_BG, LV_STATE_DEFAULT, LV_ALIGN_OUT_RIGHT_MID);lv_obj_set_style_local_value_ofs_x(sw, LV_SWITCH_PART_BG, LV_STATE_DEFAULT, LV_DPI/35);}}#endift1 = lv_tabview_add_tab(tv, "Controls");//新增tv1表格控件t2 = lv_tabview_add_tab(tv, "Visuals"); //新增tv2表格控件t3 = lv_tabview_add_tab(tv, "Selectors");//新增tv3表格控件//初始化box样式与位置lv_style_init(&style_box); lv_style_set_value_align(&style_box, LV_STATE_DEFAULT, LV_ALIGN_OUT_TOP_LEFT);lv_style_set_value_ofs_y(&style_box, LV_STATE_DEFAULT, - LV_DPX(10));lv_style_set_margin_top(&style_box, LV_STATE_DEFAULT, LV_DPX(30));controls_create(t1);//创建t1对象具体的组件visuals_create(t2); //创建t2对象具体的组件selectors_create(t3);//创建t3对象具体的组件#if LV_DEMO_WIDGETS_SLIDESHOWlv_task_create(tab_changer_task_cb, 8000, LV_TASK_PRIO_LOW, NULL);//创建动画切换刷新任务#endif}
对象结构lv_obj_t
在LVGL中,用户接口的基础构建块是对象(面向对象的编程思想),比如button、lable、image,通过lv_obj_t定义具体的属性,组件子类可继承父类对象