ESP32S3 中景园1.69液晶屏ST7789V LVGL 坑记录

异常

  • 基于VScode ESP-IDF 4.4.5 移植LVGL 8.3.0版本,启动后液晶屏出现花屏现象,运行LVGL demo 会出现拉窗帘现象

环境说明

  • 下载 lvgl :
    https://github.com/lvgl/lvgl/tree/release/v8.3

  • 下载lvgl_esp32_drivers(master 分支):
    https://github.com/lvgl/lvgl_esp32_drivers/tree/master

  • 移植参考
    https://blog.csdn.net/weixin_43326110/article/details/126314659

分析过程

  1. 液晶屏驱动程序,未使用LVGL下已经调试成功,可以正常使用,该液晶屏使用的驱动芯片为(ST7789V),和lvgl_esp32_drivers 库中的驱动型号不一致
  2. 对比st7789_init_cmds 配置寄存器信息,修正lvgl_esp32_drivers 库 中st7789.c 中的配置寄存器表
    lcd_init_cmd_t st7789_init_cmds[] = {
        {0x11, {0}, 0x80},
        {0x3A, {0x05},1},
        {0xB2, {0x0c,0x0c,0x00,0x33,0x33},5},
        {0xB7, {0x35}, 1},
        {0xBB, {0x32}, 1},
        {0xC2, {0x01}, 1},
        {0xC3, {0x15}, 1},
        {0xC4, {0x20}, 1},
        {0xC6, {0x0F}, 1},
        {0xD0, {0xA4,0xA1}, 2},
        {ST7789_PVGAMCTRL, {0xD0, 0x08, 0x0E, 0x09, 0x09, 0x05, 0x31, 0x33, 0x48, 0x17, 0x14, 0x15, 0x31, 0x34}, 14},
        {ST7789_NVGAMCTRL, {0xD0, 0x08, 0x0E, 0x09, 0x09, 0x15, 0x31, 0x33, 0x48, 0x17, 0x14, 0x15, 0x31, 0x34}, 14},
#if ST7789_INVERT_COLORS == 1
		{ST7789_INVON, {0}, 0}, // set inverted mode
#else
 	    {ST7789_INVOFF, {0}, 0}, // set non-inverted mode
#endif
        {ST7789_DISPON, {0}, 0x80},
        {0, {0}, 0xff},
    };
  1. 分析spi 初始化,查看lv_spi_conf.h文件
// XXX: 修改SPI MODE
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789)
#define SPI_TFT_SPI_MODE    (3)
#else
#define SPI_TFT_SPI_MODE    (0)
#endif
  1. DISP_BUF_SIZE 大小踩坑(维持不动即可)
// 如果设置成 分辨率大小 会出现闪屏现象
#define DISP_BUF_SIZE  (LV_HOR_RES_MAX * LV_VER_RES_MAX)

// 维持不动则不会有异常 (这里表示 不理解)
#define DISP_BUF_SIZE  (LV_HOR_RES_MAX * 40)
  1. 初始化需增加y方向偏移(官方提供的资料是 240300 尺寸的,实际使用的是 240280)
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.hor_res = LV_HOR_RES_MAX;
    disp_drv.ver_res = LV_VER_RES_MAX;
    disp_drv.offset_x = 0;
    // 设置成 20 (增加偏移)
    disp_drv.offset_y = 20;
    disp_drv.flush_cb = disp_driver_flush;
    disp_drv.draw_buf = &disp_buf;
#if defined CONFIG_DISPLAY_ORIENTATION_PORTRAIT || defined CONFIG_DISPLAY_ORIENTATION_PORTRAIT_INVERTED
    disp_drv.rotated = 1;
#endif
    // disp_drv.full_refresh = 1;
    lv_disp_drv_register(&disp_drv);

应用参考

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "esp_system.h"
#include "esp_timer.h"

/* Littlevgl specific */
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#include "demos/lv_demos.h"
#else
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#endif

#include "lvgl_helpers.h"
#include "lvgl/src/hal/lv_hal_disp.h"

static const char *TAG = "example";

#define LV_TICK_PERIOD_MS 1

static void create_demo_application(void);

void lv_tick_task(void *arg)
{
    lv_tick_inc(LV_TICK_PERIOD_MS);
}

SemaphoreHandle_t xGuiSemaphore;

static void lvgl_gui_task(void *pvParameter)
{
    xGuiSemaphore = xSemaphoreCreateMutex();

    lv_init();
    lvgl_driver_init();

	static lv_disp_draw_buf_t disp_buf;
    lv_color_t *buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t) , MALLOC_CAP_DMA);
    lv_color_t *buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t)  , MALLOC_CAP_DMA);

    lv_disp_draw_buf_init(&disp_buf, buf1, buf2, DISP_BUF_SIZE); /*Initialize the display buffer*/

    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.hor_res = LV_HOR_RES_MAX;
    disp_drv.ver_res = LV_VER_RES_MAX;
    disp_drv.offset_x = 0;
    disp_drv.offset_y = 20;
    disp_drv.flush_cb = disp_driver_flush;
    disp_drv.draw_buf = &disp_buf;
#if defined CONFIG_DISPLAY_ORIENTATION_PORTRAIT || defined CONFIG_DISPLAY_ORIENTATION_PORTRAIT_INVERTED
    disp_drv.rotated = 1;
#endif
    // disp_drv.full_refresh = 1;
    lv_disp_drv_register(&disp_drv);

    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));

    // lv_disp_set_bg_color(lv_disp_get_default(),lv_color_make(0xFF,0x0,0x0));
    // /* Create the demo application */
    // vTaskDelay(pdMS_TO_TICKS(50));
    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();
            xSemaphoreGive(xGuiSemaphore);
       }
    }
}


static void create_demo_application(void)
{
    // lv_demo_music();
    lv_demo_benchmark();
}


void app_main(void)
{
    size_t ram = heap_caps_get_free_size(MALLOC_CAP_DMA);
    ESP_LOGW(TAG, "dram=%dkb", ram/1024);
    ram = heap_caps_get_free_size(MALLOC_CAP_8BIT);
    ESP_LOGW(TAG, "psram=%dkb", ram/1024);
    xTaskCreatePinnedToCore(lvgl_gui_task, "gui", 4096*4, NULL, 0, NULL, 1);
}
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值