此文章运行环境ESP-IDF5.3(5.2也可),lvgl8.3.10,lcd1.3寸ST7789驱动屏幕,ESP32S3
不想看此文章了解流程,可以直接到文章最下面下载工程文件,修改引脚即可,注意如果LCD驱动屏幕不显示可能是屏幕芯片驱动不同,此驱动适合ST7789和ST7789V,如果是此芯片还是无法显示,可能你的LCD屏幕没有带CS片选引脚可能是老版本的批次,屏幕无法点亮可以去网上看看,要飞线。建议是带CS引脚的LCD屏幕,有此引脚也可以不用接CS引脚
1、 准备好两个文件,LVGL(任意版本)源码,准备显示屏驱动。这边显示屏驱动使用的是正点原子官网的LCD屏幕ST7789驱动。LCD驱动源码地址 https://pan.baidu.com/s/1A19N218T66hs4PgRgdTqgQ 提取码:ixmr。LVGL源码地址:https://github.com/lvgl/lvgl/releases/tag/v8.3.10,这边移植的是8.3.10,方便使用GUI GUIder软件。
2、 打开正点原子源码,修改引脚,增删文件。正点原子里的XL9555是用来拓展io的我们直接删除,还有IIC和LED的文件删除,并修改CMakeList文件,
3、 接下来修改LCD的引脚,记得修改图下函数,和引脚初始化
4、 初始化代码如下放入lcd_init函数中,并在lcd.h中宏定义
5、 然后直接编译,因为删除了三个文件夹,可能有些头文件的引用或者函数调用不存在了可,看哪里编译错误删除即可,此屏幕是1.3寸屏幕,正点原子里的屏幕尺寸源码不用修改。(已改的LCD源码下载
链接: https://pan.baidu.com/s/1P-vsxNBkQpaAE4HfvvvSAg?pwd=4567 提取码: 4567 (在spi和LCD头文件中修改引脚即可))
6、 移植lvgl,将lvgl下载的源码文件改名为lvgl,直接移入components文件夹即可,因为LVGL里的CMakelist文件已经链接好了。文件结构如下
7、修改ESP-IDF的SDK配置(注意每次修改一定要保存),使其lv_conf.h生效,当然其实可以不用修改直接使用SDK配置文件的设置界面,但是每次修改测试文件界面就会所有重启编译构建比较耗时间,这边建议直接修改lv_conf.h文件。配置界面搜索uncheck(要先编译一下再搜索不然没有lvgl的配置界面),关闭Uncheck this to use custom lv_conf.h。使能此文件。
8、将lv_conf_template.h复制并重命名为lv_conf.h,移入scr文件里,并使能文件
9、移植显示驱动,将components\lvgl\examples\porting里的以下几个文件复制,并到components/BSP文件里创建一个LV_Driver文件夹存放此文件并重命名两个文件为lv_port_disp。记住使能文件,两个文件里第一行的#if 0改为#if 1,并修改BSP里的CMakelist文件
10、导入LCD驱动的初始化到disp_init函数中,并在disp_flush初始化显示接口,以及缓冲区
lv_port_disp.c代码如下建议复制以下代码。记得修改屏幕尺寸
#if 1
/*********************
* INCLUDES
*********************/
#include "lv_port_disp.h"
#include <stdbool.h>
#include "spi.h"
#include "lcd.h"
/*********************
* DEFINES
*********************/
#ifndef MY_DISP_HOR_RES
#warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen width, default value 320 is used for now.
#define MY_DISP_HOR_RES 240
#endif
#ifndef MY_DISP_VER_RES
#warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen height, default value 240 is used for now.
#define MY_DISP_VER_RES 240
#endif
static void disp_init(void);
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
void lv_port_disp_init(void)
{
disp_init();
//缓冲区开辟
int DISP_BUF_SIZE =MY_DISP_HOR_RES * ((MY_DISP_VER_RES)/10);
static lv_disp_draw_buf_t draw_buf_dsc;
#if defined(CONFIG_GRAPHICS_USE_PSRAM)
lv_color_t *buf_1 = heap_caps_malloc(DISP_BUF_SIZE*2, MALLOC_CAP_SPIRAM);
lv_color_t *buf_2 = heap_caps_malloc(DISP_BUF_SIZE*2, MALLOC_CAP_SPIRAM);
#else
lv_color_t *buf_1 = heap_caps_malloc(DISP_BUF_SIZE*2, MALLOC_CAP_DMA);
lv_color_t *buf_2 = heap_caps_malloc(DISP_BUF_SIZE*2, MALLOC_CAP_DMA);
#endif
lv_disp_draw_buf_init(&draw_buf_dsc, buf_1, buf_2,DISP_BUF_SIZE);
//注册显示
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = MY_DISP_HOR_RES;
disp_drv.ver_res = MY_DISP_VER_RES;
disp_drv.flush_cb = disp_flush;
disp_drv.draw_buf = &draw_buf_dsc;
lv_disp_drv_register(&disp_drv);
}
static void disp_init(void)
{
spi2_init();
lcd_init();
}
volatile bool disp_flush_enabled = true;
void disp_enable_update(void)
{
disp_flush_enabled = true;
}
void disp_disable_update(void)
{
disp_flush_enabled = false;
}
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
lcd_set_window(area->x1, area->y1, area->x2, area->y2);
size_t size = (size_t)lv_area_get_width(area) * (size_t)lv_area_get_height(area);
lcd_write_data(color_p, size * 2);
//lcd_lvgl_flush(area->x1, area->y1, area->x2, area->y2,color_p, size);
lv_disp_flush_ready(disp_drv);
}
#else
#endif
11、 修改lv_conf.h里的LV_TICK_CUSTOM,配置LVGL的TICK,和LV_COLOR_16_SWAP置为1(如果屏幕反色就修改)
12、 最后运行DEMO记得再lv_conf.h使能LV_USE_DEMO_BENCHMARK,,但是特殊的是再SDK配置界面里也要使能LV_USE_DEMO_BENCHMARK,这是为什么呢。因为在components\lvgl\env_support\cmake\esp.cmake文件中有SDK配置界面的DEMO开启定义,所以运行demo两个地方都要使能不然会编译错误。其他的配置修改lv_conf.h即可。
13、 最后修改main.c文件,使其LVGL在ESP32S3的1号核上运行,并配置LVGL的刷新中断代码如下
main.c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "lvgl.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include "lv_port_disp.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_chip_info.h"
#include "esp_psram.h"
#include "esp_flash.h"
#include "esp_timer.h"
#include "demos/lv_demos.h"
static void lvgl_act(void *pvParameter);
void app_main(void)
{
xTaskCreatePinnedToCore(lvgl_act, "gui_app", 4096 * 2, NULL, 0, NULL, 1);
}
static void lvgl_act(void *pvParameter)
{
esp_err_t ret;
ret = nvs_flash_init(); /* 初始化NVS */
if (ret == ESP_ERR_NVS_NO_FREE_PAGES
|| ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
lv_init();
lv_port_disp_init();
lv_demo_benchmark();
while (1)
{
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
vTaskDelay(pdMS_TO_TICKS(10));
lv_task_handler();
}
}
14、最后编译运行结果。工程代码(改引脚直接运行即可)链接:: https://pan.baidu.com/s/117Lyi_Vw4iY-JK0AbTTx0g?pwd=4567 提取码: 4567