ESP32C3合宙开发板及屏幕移植LVGL--基于ESP-IDF+VSCODE

最终完成

1. 主要程序地址

LVGL 主体程序
https://github.com/lvgl/lvgl/tags

LVGL芯片驱动程序
https://github.com/lvgl/lvgl_esp32_drivers/tree/master

LVGL移植示例程序
https://github.com/lvgl/lv_port_esp32

esp-idf 4.4.4
https://dl.espressif.cn/dl/esp-idf/?idf=4.4

2. 移植相关版本

  • Esp-idf : esp-idf-tools-setup-offline-4.4.4(lvgl_esp32_drivers目前只适配了4.4.4版本的idf,如果使用5.0
    idf 会报错)
  • Lvgl : 8.3.0(dev),8.3.8(实测也可以)
  • lvgl_esp32_drivers : (ESP spi 屏幕芯片的驱动程序,SPI初始化,显示刷新)

3. 移植步骤

  • 在新建项目中(如bink),工程里创建一个 components 文件夹
    在这里插入图片描述

  • 将lvgl和 lvgl_esp32_drivers 文件夹copy入 components 文件夹
    在这里插入图片描述

  • 编译并重启vscode,在工程配置中应会出现lvgl相关配置
    在这里插入图片描述

  • 将示例的lvgl_init.h,lvgl_init.c文件拷贝入main文件夹中,并修改main文件夹中的CMakeLists.txt 文件
    在这里插入图片描述

lvgl_init.c 代码如下:

#include "lvgl_init.h"

/******************************************************************
 *  STATIC PROTOTYPES
 ******************************************************************/

void lv_tick_task(void *arg)
{
    lv_tick_inc(LV_TICK_PERIOD_MS);
}
/* Creates a semaphore to handle concurrent call to lvgl stuff
 * If you wish to call *any* lvgl function from other threads/tasks
 * you should lock on the very same semaphore! */
/*********************** GUI_SHOW_CODE_START***********************/
lv_obj_t * label_1;
lv_obj_t * label_2;

void UI_Init()
{
    lv_obj_t *scr = lv_scr_act(); //创建scr
    lv_obj_set_pos(scr,0,0);
    lv_scr_load(scr);

    label_1 =lv_label_create(scr);//创建label
    lv_label_set_recolor(label_1,1);//颜色可变换
    lv_label_set_long_mode(label_1,LV_LABEL_LONG_SCROLL_CIRCULAR);//设置滚动模式
    lv_obj_set_pos(label_1,0,0);//设置位置
    lv_obj_set_size(label_1,160,30);//设定大小
    lv_label_set_text(label_1, "#0000ff This is a GUI thread yes");//设定文本内容
 
    label_2 =lv_label_create(scr);//创建labe2
    lv_label_set_recolor(label_2,1);//颜色可变换
    lv_label_set_long_mode(label_2,LV_LABEL_LONG_SCROLL_CIRCULAR);//设置滚动模式
    lv_obj_set_pos(label_2,0,40);//设置位置
    lv_obj_set_size(label_2,160,40);//设定大小
    lv_label_set_text(label_2, "#ff0000 red#");//设定文本内容

}
/*********************** GUI_SHOW_CODE_END***********************/

void guiTask(void *p) 
{


    lv_init();
    /* Initialize SPI or I2C bus used by the drivers */
    lvgl_driver_init();

    lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
   // memset(buf1,0x00ff,DISP_BUF_SIZE * sizeof(lv_color_t));
    assert(buf1 != NULL);

    /* Use double buffered when not working with monochrome displays */
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
    lv_color_t* buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
    //memset(buf2,0x00ff,DISP_BUF_SIZE * sizeof(lv_color_t));
    assert(buf2 != NULL);
#else
    static lv_color_t *buf2 = NULL;
#endif

    static lv_disp_draw_buf_t disp_buf;

    uint32_t size_in_px = DISP_BUF_SIZE;

#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820         \
    || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A    \
    || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D     \
    || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306

    /* Actual size in pixels, not bytes. */
    size_in_px *= 8;
#endif

    /* Initialize the working buffer depending on the selected display.
     * NOTE: buf2 == NULL when using monochrome displays. */
    lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);

    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.flush_cb = disp_driver_flush;
    disp_drv.draw_buf = &disp_buf;
    lv_disp_drv_register(&disp_drv);
    /* Register an input device when enabled on the menuconfig */
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
    lv_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

    /* Create and start a periodic timer interrupt to call lv_tick_inc */
    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));

    UI_Init();//基础UI渲染函数

    while (1) 
    {
        /* Delay 1 tick (assumes FreeRTOS tick is 10ms */
        vTaskDelay(pdMS_TO_TICKS(10));
        lv_task_handler();
    }
    /* A task should NEVER return */
    free(buf1);
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
    free(buf2);
#endif
    vTaskDelete(NULL);
}

lvgl_init.h 代码如下:

#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "lvgl.h"
#include "freertos/semphr.h"
#include "esp_system.h"


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


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


#define LV_TICK_PERIOD_MS 1
#define BUF_W 20
#define BUF_H 10


void lv_tick_task(void *arg);
void guiTask(void *pvParameter);
void Show_State();
  • 在blink_example_main.c文件中添加lvgl_init.c头文件,并新建线程指令,启动lvgl_init.c文件中的lvgl相应线程
    在这里插入图片描述

4. 移植设置(针对合宙,ESP32C3开发板及air10屏幕)

	屏幕参数0.96寸 TFT,驱动芯片 ST7735S ,分辨率160*80
  • 显示驱动配置
    在这里插入图片描述
    在这里插入图片描述
    针对air10屏幕配置如下(如端口配置不正确,不报错但会导致开发板一直重启)
    在这里插入图片描述在这里插入图片描述
  • 颜色校正配置
    因为ST7735S、ST7789在接收16位颜色值时是高位在前的16位短整型。而ESP32因为是小端模式,DMA在发送16位数据时,会先发低8位字节再发送高8位字节,这就造成了数据不一至!所以需要勾选一下,勾选后,就是调换了一下。如果你勾选了此选项造成颜色不对你可以不勾选。
    在这里插入图片描述
    如下位置也会关联显示颜色,但此移植不选
    在这里插入图片描述
  • 代码修改
    首先就是在 lvgl_helpers.h 的下面添加几个宏定义:
    在这里插入图片描述
#define LV_HOR_RES_MAX 160
#define LV_VER_RES_MAX 80
#define SPI_HOST_MAX 3

此时编译会出现花屏或显示错误,再修改如下配置
(blink\components\lvgl_esp32_drivers\lvgl_tft\st7735s.h)
在这里插入图片描述
如ROWSTART 设置为1,字体会逐行歪斜

参考

ESP32c3 移植lvgl核心组件教程
安信可ESP32 LVGL_V8 最快移植攻略

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值