启用伟大的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); } }烧录就可以看到测试界面啦~ ,屏幕闪烁着,有什么问题可以评论区提出来嗷