目录
一、前言
在之前的尝试中,已经参考lvgl_port_esp32项目在esp32上运行了lvgl7,但是由于lvgl_esp32_drivers库并不支持lvgl8,因此需要一定的修改才能适配lvgl8,这波就进行lvgl8移植的尝试。
二、代码
跟上次一样,还是把项目构建出来,然后把lvgl_esp32_drivers库和lvgl库放到components组件里。注意这里由于是希望适配用lvgl8,这里的lvgl库已经不是lvgl_port_esp32项目里的lvgl库,可以通过git指令下载,也可以到github上手动下载,我这里用的是最新的Release v8.3.1版本。
然后把是preloader.h,preloader.c,CMakeLists.txt(perloader库内),main.c等四个文件,其中preloader.h和CMakeLists.txt(perloader库内)文件与之前版本一致,这里不再贴出来,需要可以点这里查看。下面贴出来另外两个的代码:
preloader.c
#include "preloader.h"
#include "lvgl.h"
void create_preloader_demo(){
lv_obj_t * preload = lv_spinner_create(lv_scr_act(),1000,100);
lv_obj_set_size(preload,100,100);
lv_obj_align(preload,LV_ALIGN_CENTER,0,0);
}
可以看到lv_spinner_create和lv_obj_align函数的变量都有了一定的变化。
main.c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include "esp_freertos_hooks.h"
#include "lvgl.h"
#include "lvgl_helpers.h"
#include "preloader.h"
void lv_tick_task(void *arg);
static void guiTask(void *pvParameter);
SemaphoreHandle_t xGuiSemaphore;
static void guiTask(void *pvParameter)
{
(void) pvParameter;
xGuiSemaphore = xSemaphoreCreateMutex();
lv_init();
lvgl_driver_init();
lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf1 != NULL);
lv_color_t *buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf2 != NULL);
static lv_disp_draw_buf_t disp_buf;
uint32_t size_in_px = DISP_BUF_SIZE;
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = disp_driver_flush;
disp_drv.hor_res = LV_HOR_RES_MAX;
disp_drv.ver_res = LV_VER_RES_MAX;
disp_drv.draw_buf = &disp_buf;
lv_disp_drv_register(&disp_drv);
esp_register_freertos_tick_hook((void *)lv_tick_task);
/* Create the demo application */
create_preloader_demo();
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();
xSemaphoreGive(xGuiSemaphore);
}
}
/* A task should NEVER return */
free(buf1);
free(buf2);
vTaskDelete(NULL);
}
void app_main(void)
{
xTaskCreatePinnedToCore(guiTask, "gui", 4096 * 4, NULL, 0, NULL, 1);
}
void lv_tick_task(void *arg)
{
(void)arg;
lv_tick_inc(portTICK_PERIOD_MS);
}
main文件主要是lvgl的一些函数接口出现了修改,上述代码里与之前版本有变化的主要是这几个函数/变量:
static lv_disp_draw_buf_t disp_buf;
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);
disp_drv.hor_res = LV_HOR_RES_MAX;
disp_drv.ver_res = LV_VER_RES_MAX;
disp_drv.draw_buf = &disp_buf;
三、硬件说明
开发板:ESP-WROOM-32
屏幕:中景园1.47寸lcd显示屏高清ips172x320 st7789驱动液晶屏
四、ESP-IDF设置
这里与上一篇基本一致,依然把频率设为80MHz,否则黑屏,其他的直接把结果贴出来,按照自己情况设置即可:
![](https://i-blog.csdnimg.cn/blog_migrate/599ba56d513293d3c2f22af4d13b138a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a80af9e388806f1e0f57b06d79b31254.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e27f7f579c6b09927dd8ecc1119301f9.png)
五、驱动文件适配lvgl8
这里驱动文件的修改不止像上一篇只需要设置屏幕偏移,兼容lvgl8的一些适配也需要取修改。主要是对lvgl_esp32_drivers库的lvgl_tft文件夹内st7789.c和lvgl_esp32_drivers库的lvgl_helpers.h两个文件的修改。
5.1 lvgl8适配修改
这一部分主要是修改lvgl_helpers.h。首先是屏幕尺寸的设定问题,lvgl8在ESP-IDF内的模块少了屏幕尺寸的设定,因此需要在这里进行一个修改。此外在ESP-IDF内进行屏幕的旋转设定也不能直接应用,需要在驱动文件内进行屏幕尺寸的适配。
将如下代码贴到lvgl_helpers.h,其中CONFIG_LV_DISPLAY_ORIENTATION是在ESP-IDF的设置界面内设定的屏幕方向,在方向设定完后,需要根据屏幕方向修改尺寸设定,在横屏的时候(PORTRAIT)那LV_HOR_RES_MAX就设定为320,反之竖屏(LANDSCAPE)则设定为172。
/* 屏幕方向定义 */
#define LV_PORTRAIT 0 /* 横屏 */
#define LV_PORTRAIT_INVERTED 1 /* 横屏倒置 */
#define LV_LANDSCAPE 2 /* 竖屏 */
#define LV_LANDSCAPE_INVERTED 3 /* 竖屏倒置 */
#if (LV_PORTRAIT == CONFIG_LV_DISPLAY_ORIENTATION)||(LV_PORTRAIT_INVERTED == CONFIG_LV_DISPLAY_ORIENTATION)
#define LV_HOR_RES_MAX 320
#define LV_VER_RES_MAX 172
#endif
#if (LV_LANDSCAPE == CONFIG_LV_DISPLAY_ORIENTATION)||(LV_LANDSCAPE_INVERTED == CONFIG_LV_DISPLAY_ORIENTATION)
#define LV_HOR_RES_MAX 172
#define LV_VER_RES_MAX 320
#endif
#define SPI_HOST_MAX 3
还有就是 SPI_HOST_MAX设定为3,这里不设置编译会报错找不到这个变量,是lvgl8与lvgl_esp32_drivers库的适配问题。
5.1 屏幕偏移设置
屏幕偏移问题由于驱动的尺寸设定导致屏幕内坐标系也出现了旋转,因此需要进行一定的修正。首先在在lvgl_esp32_drivers库的lvgl_tft文件夹内找到st7789.c驱动文件。并对函数void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)进行修改:
#if (LV_LANDSCAPE == CONFIG_LV_DISPLAY_ORIENTATION)||(LV_LANDSCAPE_INVERTED == CONFIG_LV_DISPLAY_ORIENTATION)
offsetx1 += 34;
offsetx2 += 34;
#elif (LV_PORTRAIT == CONFIG_LV_DISPLAY_ORIENTATION)||(LV_PORTRAIT_INVERTED == CONFIG_LV_DISPLAY_ORIENTATION)
offsety1 += 34;
offsety2 += 34;
#endif
如上代码,在横屏的时候(PORTRAIT)需要在y方向上进行偏移补偿;反之竖屏(LANDSCAPE)则在x方向进行补偿。
5.3 lvgl8适配一些说明
关于lvgl8的适配问题,这个目前来看比较复杂,网上有很多不同的修改方式,由于兼容性的问题,这种修改面对不同的硬件可能是完全不同的,本文只代表我这套硬件对应的解决方案。但是这里也简单把之前看的一些修改lvgl_esp32_drivers库适配lvgl8的方法列举一下以供参考,手段包括但不限于
- 注释SPI_HOST_MAX对应行
- 修改DISP_BUF_SIZE计算方法
- 修改lvgl_spi_conf.h文件
(21条消息) 又一次移植最新lvgl8到esp32的踩坑记录_flamebox的博客-CSDN博客
[教程] esp32平台下运行lvgl,使用屏幕st7735s 128*128详细配置 - 哔哩哔哩 (bilibili.com)
ESP32 IDF 移植 LVGL 最新版本 - 哔哩哔哩 (bilibili.com)
(21条消息) ESP32 IDF LVGL 1.47寸圆角屏幕测试_史达芬林的博客-CSDN博客
(21条消息) 燃起来 ESP32移植LVGL最新版本8.2_Wireless_Link的博客-CSDN博客_esp32移植lvgl
参考资料
(21条消息) 【esp32&lvgl】-2.1 # esp32移植lvgl7驱动st7789屏幕(ESP-IDF框架)_weixin_43326110的博客-CSDN博客