启用伟大的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,  &reg_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);

    }

}

烧录就可以看到测试界面啦~ ,屏幕闪烁着,有什么问题可以评论区提出来嗷

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐