2026.03 LVGL-在ESP32启用我们的伟大界面
2026.03-LVGL+ESP32启用我们的伟大界面
·
启用伟大的LVGL
两种方法,但都需要网络
第一种:打开ESP-IDF终端
分两次输入
idf.py add-dependency "lvgl/lvgl^9.4.0"
idf.py add-dependency "espressif/esp_lvgl_port^2.6.3"
以下是我的屏幕驱动
espressif/esp_lcd_touch_ft5x06: ^1.0.6 # 触摸屏驱动

第二种来到main目录下
创建idf_component.yml文件,缩进不能错,内容是
dependencies:
idf:
version: '>=4.1.0'
lvgl/lvgl: ^9.4.0
espressif/esp_lvgl_port: ^2.6.3
espressif/esp_lcd_touch_ft5x06: ^1.0.6

然后编译就行。
修改你的显示文件
说实话,这里没弄懂,我直接给出一个我的 .c和.h文件,对照着修改吧… 因为句柄确实是有些多了,设备是ST7789V液晶屏+ esp_lcd_touch_ft5x06,
LCD.c
#include "LCD.h"
/******************************************************************************/
/*************************** I2C ↓ *******************************************/
esp_err_t bsp_i2c_init(void)
{
i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = BSP_I2C_SDA,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = BSP_I2C_SCL,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = BSP_I2C_FREQ_HZ
};
i2c_param_config(BSP_I2C_NUM, &i2c_conf);
return i2c_driver_install(BSP_I2C_NUM, i2c_conf.mode, 0, 0, 0);
}
/*************************** I2C ↑ *******************************************/
/*******************************************************************************/
/***********************************************************/
/*************** IO扩展芯片 ↓ *************************/
// 读取PCA9557寄存器的值
esp_err_t pca9557_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{
return i2c_master_write_read_device(BSP_I2C_NUM, PCA9557_SENSOR_ADDR, ®_addr, 1, data, len, 1000 / portTICK_PERIOD_MS);
}
// 给PCA9557的寄存器写值
esp_err_t pca9557_register_write_byte(uint8_t reg_addr, uint8_t data)
{
uint8_t write_buf[2] = {reg_addr, data};
return i2c_master_write_to_device(BSP_I2C_NUM, PCA9557_SENSOR_ADDR, write_buf, sizeof(write_buf), 1000 / portTICK_PERIOD_MS);
}
// 初始化PCA9557 IO扩展芯片
void pca9557_init(void)
{
// 写入控制引脚默认值 DVP_PWDN=1 PA_EN = 0 LCD_CS = 1
pca9557_register_write_byte(PCA9557_OUTPUT_PORT, 0x05);
// 把PCA9557芯片的IO1 IO1 IO2设置为输出 其它引脚保持默认的输入
pca9557_register_write_byte(PCA9557_CONFIGURATION_PORT, 0xf8);
}
// 设置PCA9557芯片的某个IO引脚输出高低电平
esp_err_t pca9557_set_output_state(uint8_t gpio_bit, uint8_t level)
{
uint8_t data;
esp_err_t res = ESP_FAIL;
pca9557_register_read(PCA9557_OUTPUT_PORT, &data, 1);
res = pca9557_register_write_byte(PCA9557_OUTPUT_PORT, SET_BITS(data, gpio_bit, level));
return res;
}
/*************** IO扩展芯片 ↑ *************************/
/***********************************************************/
static const char *TAG = "lcd";
/***********************************************************/
/**************** LCD显示屏 ↓ *************************/
// 背光PWM初始化
esp_err_t bsp_display_brightness_init(void)
{
// Setup LEDC peripheral for PWM backlight control
const ledc_channel_config_t LCD_backlight_channel = {
.gpio_num = BSP_LCD_BACKLIGHT,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LCD_LEDC_CH,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = 1,
.duty = 0,
.hpoint = 0,
.flags.output_invert = true
};
const ledc_timer_config_t LCD_backlight_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_10_BIT,
.timer_num = 1,
.freq_hz = 5000,
.clk_cfg = LEDC_AUTO_CLK
};
ESP_ERROR_CHECK(ledc_timer_config(&LCD_backlight_timer));
ESP_ERROR_CHECK(ledc_channel_config(&LCD_backlight_channel));
return ESP_OK;
}
// 背光亮度设置
esp_err_t bsp_display_brightness_set(int brightness_percent)
{
if (brightness_percent > 100) {
brightness_percent = 100;
} else if (brightness_percent < 0) {
brightness_percent = 0;
}
ESP_LOGI(TAG, "Setting LCD backlight: %d%%", brightness_percent);
// LEDC resolution set to 10bits, thus: 100% = 1023
uint32_t duty_cycle = (1023 * brightness_percent) / 100;
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty_cycle));
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH));
return ESP_OK;
}
static esp_lcd_panel_handle_t panel_handle = NULL;
static esp_lcd_panel_io_handle_t io_handle = NULL;
// 液晶屏初始化
esp_err_t bsp_display_new(void)
{
esp_err_t ret = ESP_OK;
// 背光初始化
ESP_RETURN_ON_ERROR(bsp_display_brightness_init(), TAG, "Brightness init failed");
// 初始化SPI总线
ESP_LOGD(TAG, "Initialize SPI bus");
const spi_bus_config_t buscfg = {
.sclk_io_num = BSP_LCD_SPI_CLK,
.mosi_io_num = BSP_LCD_SPI_MOSI,
.miso_io_num = GPIO_NUM_NC,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.max_transfer_sz = BSP_LCD_H_RES * BSP_LCD_V_RES * sizeof(uint16_t),
};
ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed");
// 液晶屏控制IO初始化
ESP_LOGD(TAG, "Install panel IO");
const esp_lcd_panel_io_spi_config_t io_config = {
.dc_gpio_num = BSP_LCD_DC,
.cs_gpio_num = BSP_LCD_SPI_CS,
.pclk_hz = BSP_LCD_PIXEL_CLOCK_HZ,
.lcd_cmd_bits = LCD_CMD_BITS,
.lcd_param_bits = LCD_PARAM_BITS,
.spi_mode = 2,
.trans_queue_depth = 10,
};
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)BSP_LCD_SPI_NUM, &io_config, &io_handle), err, TAG, "New panel IO failed");
// 初始化液晶屏驱动芯片ST7789
ESP_LOGD(TAG, "Install LCD driver");
const esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = BSP_LCD_RST,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = BSP_LCD_BITS_PER_PIXEL,
};
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle), err, TAG, "New panel failed");
esp_lcd_panel_reset(panel_handle); // 液晶屏复位
PCA9557_SET_GPIO(LCD_CS_GPIO,0); // 拉低CS引脚
esp_lcd_panel_init(panel_handle); // 初始化配置寄存器
esp_lcd_panel_invert_color(panel_handle, true); // 颜色反转
esp_lcd_panel_swap_xy(panel_handle, true); // 显示翻转
esp_lcd_panel_mirror(panel_handle, true, false); // 镜像
return ret;
err:
if (panel_handle) {
esp_lcd_panel_del(panel_handle);
}
if (io_handle) {
esp_lcd_panel_io_del(io_handle);
}
spi_bus_free(BSP_LCD_SPI_NUM);
return ret;
}
// LCD显示初始化
esp_err_t bsp_lcd_init(void)
{
esp_err_t ret = ESP_OK;
ret = bsp_display_new(); // 液晶屏驱动初始化
lcd_set_color(BLACK); // 设置整屏背景黑色
ret = esp_lcd_panel_disp_on_off(panel_handle, true); // 打开液晶屏显示
ret = bsp_display_brightness_set(100);; // 打开背光显示
return ret;
}
// 设置液晶屏颜色
void lcd_set_color(uint16_t color)
{
// 分配内存 这里分配了液晶屏一行数据需要的大小
uint16_t *buffer = (uint16_t *)heap_caps_malloc(BSP_LCD_H_RES * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
if (NULL == buffer){
ESP_LOGE(TAG, "Memory for bitmap is not enough");
}else{
for (size_t i = 0; i < BSP_LCD_H_RES; i++){ // 给缓存中放入颜色数据
buffer[i] = color;
}
for (int y = 0; y < 240; y++){ // 显示整屏颜色
esp_lcd_panel_draw_bitmap(panel_handle, 0, y, 320, y+1, buffer);
}
free(buffer); // 释放内存
}
}
/*************** LCD显示屏 ↑ *************************/
/***********************************************************/
static esp_lcd_touch_handle_t tp; // 触摸屏句柄
static lv_disp_t *disp; // 指向液晶屏
static lv_indev_t *disp_indev = NULL; // 指向触摸屏
#define BSP_LCD_DRAW_BUF_HEIGHT (20)
// 液晶屏初始化+添加LVGL接口
static lv_disp_t *bsp_display_lcd_init(void)
{
/* 初始化液晶屏 */
bsp_display_new(); // 液晶屏驱动初始化
lcd_set_color(0xffff); // 设置整屏背景白色
esp_lcd_panel_disp_on_off(panel_handle, true); // 打开液晶屏显示
/* 液晶屏添加LVGL接口 */
ESP_LOGD(TAG, "Add LCD screen");
const lvgl_port_display_cfg_t disp_cfg = {
.io_handle = io_handle,
.panel_handle = panel_handle,
.buffer_size = BSP_LCD_H_RES * BSP_LCD_DRAW_BUF_HEIGHT, // LVGL缓存大小
.double_buffer = false, // 是否开启双缓存
.hres = BSP_LCD_H_RES, // 液晶屏的宽
.vres = BSP_LCD_V_RES, // 液晶屏的高
.monochrome = false, // 是否单色显示器
/* Rotation的值必须和液晶屏初始化里面设置的 翻转 和 镜像 一样 */
.rotation = {
.swap_xy = true, // 是否翻转
.mirror_x = true, // x方向是否镜像
.mirror_y = false, // y方向是否镜像
},
.flags = {
.buff_dma = true, // 是否使用DMA 注意:dma与spiram不能同时为true
.buff_spiram = false, // 是否使用PSRAM 注意:dma与spiram不能同时为true
.swap_bytes = true, // 是否交换字节(颜色逆序)
}
};
return lvgl_port_add_disp(&disp_cfg);
}
// 触摸屏初始化
esp_err_t bsp_touch_new(esp_lcd_touch_handle_t *ret_touch)
{
/* Initialize touch */
esp_lcd_touch_config_t tp_cfg = {
.x_max = BSP_LCD_V_RES,
.y_max = BSP_LCD_H_RES,
.rst_gpio_num = GPIO_NUM_NC, // Shared with LCD reset
.int_gpio_num = GPIO_NUM_NC,
.levels = {
.reset = 0,
.interrupt = 0,
},
.flags = {
.swap_xy = 1,
.mirror_x = 1,
.mirror_y = 0,
},
};
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_FT5x06_CONFIG();
ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)BSP_I2C_NUM, &tp_io_config, &tp_io_handle), TAG, "");
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_ft5x06(tp_io_handle, &tp_cfg, ret_touch));
return ESP_OK;
}
// 触摸屏初始化+添加LVGL接口
static lv_indev_t *bsp_display_indev_init(lv_disp_t *disp)
{
/* 初始化触摸屏 */
ESP_ERROR_CHECK(bsp_touch_new(&tp));
assert(tp);
/* 添加LVGL接口 */
const lvgl_port_touch_cfg_t touch_cfg = {
.disp = disp,
.handle = tp,
};
return lvgl_port_add_touch(&touch_cfg);
}
// 开发板显示初始化
void bsp_lvgl_start(void)
{
/* 初始化LVGL */
lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
lvgl_port_init(&lvgl_cfg);
/* 初始化液晶屏 并添加LVGL接口 */
disp = bsp_display_lcd_init();
/* 初始化触摸屏 并添加LVGL接口 */
disp_indev = bsp_display_indev_init(disp);
/* 打开液晶屏背光 */
bsp_display_brightness_set(100);
}
LCD.h
#ifndef _LCD_H_
#define _LCD_H_
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_lcd_touch_ft5x06.h"
#include "esp_lvgl_port.h"
void bsp_lvgl_start(void);
/******************************************************************************/
/*************************** I2C ↓ *******************************************/
#define BSP_I2C_SDA (GPIO_NUM_1) // SDA引脚
#define BSP_I2C_SCL (GPIO_NUM_2) // SCL引脚
#define BSP_I2C_NUM (0) // I2C外设
#define BSP_I2C_FREQ_HZ 100000 // 100kHz
esp_err_t bsp_i2c_init(void); // 初始化I2C接口
/*************************** I2C ↑ *******************************************/
/*******************************************************************************/
/***********************************************************/
/*************** IO扩展芯片 ↓ *************************/
#define PCA9557_INPUT_PORT 0x00
#define PCA9557_OUTPUT_PORT 0x01
#define PCA9557_POLARITY_INVERSION_PORT 0x02
#define PCA9557_CONFIGURATION_PORT 0x03
#define LCD_CS_GPIO BIT(0) // PCA9557_GPIO_NUM_1
#define PA_EN_GPIO BIT(1) // PCA9557_GPIO_NUM_2
#define DVP_PWDN_GPIO BIT(2) // PCA9557_GPIO_NUM_3
// 控制 PCA9557引脚输出高低电平 参数0输出低电平 参数1输出高电平
#define PCA9557_SET_GPIO(gpio,x) pca9557_set_output_state(gpio, x)
#define PCA9557_SENSOR_ADDR 0x19 /*!< Slave address of the MPU9250 sensor */
#define SET_BITS(_m, _s, _v) ((_v) ? (_m)|((_s)) : (_m)&~((_s)))
void pca9557_init(void);
/*************** IO扩展芯片 ↑ *************************/
/***********************************************************/
#include <string.h>
#include "math.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "driver/spi_master.h"
#include "driver/ledc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_lcd_types.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
/***********************************************************/
/**************** LCD显示屏 ↓ *************************/
#define BSP_LCD_PIXEL_CLOCK_HZ (80 * 1000 * 1000)
#define BSP_LCD_SPI_NUM (SPI3_HOST)
#define LCD_CMD_BITS (8)
#define LCD_PARAM_BITS (8)
#define BSP_LCD_BITS_PER_PIXEL (16)
#define LCD_LEDC_CH LEDC_CHANNEL_0
#define BSP_LCD_H_RES (320)
#define BSP_LCD_V_RES (240)
#define BSP_LCD_SPI_MOSI (GPIO_NUM_40)
#define BSP_LCD_SPI_CLK (GPIO_NUM_41)
#define BSP_LCD_SPI_CS (GPIO_NUM_NC)
#define BSP_LCD_DC (GPIO_NUM_39)
#define BSP_LCD_RST (GPIO_NUM_NC)
#define BSP_LCD_BACKLIGHT (GPIO_NUM_42)
//画笔颜色
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x1F00
#define BRED 0X1FF8
#define GRED 0XE0FF
#define GBLUE 0XFF07
#define RED 0x00F8
#define MAGENTA 0x1FF8
#define GREEN 0xE007
#define CYAN 0xFF7F
#define YELLOW 0xE0FF
#define BROWN 0X40BC //棕色
#define BRRED 0X07FC //棕红色
#define GRAY 0X3084 //灰色
#define DARKBLUE 0XCF01 //深蓝色
#define LIGHTBLUE 0X7C7D //浅蓝色
#define GRAYBLUE 0X5854 //灰蓝色
#define LIGHTGREEN 0X1F84 //浅绿色
#define LGRAY 0X18C6 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE 0X51A6 //浅灰蓝色(中间层颜色)
#define LBBLUE 0X122B //浅棕蓝色(选择条目的反色)
esp_err_t bsp_display_brightness_init(void);
esp_err_t bsp_display_brightness_set(int brightness_percent);
esp_err_t bsp_lcd_init(void);
void lcd_set_color(uint16_t color);
/*************** LCD显示屏 ↑ *************************/
/***********************************************************/
#endif
烧录Demo
为了测试是否正常安装了LVGL驱动,我们把Demo也编译进去

Main里面添加代码
#include <stdio.h>
#include "esp_log.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "LCD.h"
#include "demos/lv_demos.h"
void app_main(void)
{
bsp_i2c_init();
pca9557_init();
vTaskDelay(100);
bsp_lvgl_start();
lv_demo_benchmark();
while (1)
{
vTaskDelay(100);
}
}
烧录就可以看到测试界面啦~ ,屏幕闪烁着,有什么问题可以评论区提出来嗷
更多推荐



所有评论(0)