LVGL9.2.2结合ESP-IDF驱动ST7789屏幕时颜色显示异常问题
问题描述
基于ESP-IDF框架,使用LVGL 9.2.2搭配ST7789 SPI液晶屏驱动,调用LVGL API设置颜色时显示异常,直接调用自定义lcd_set_color函数则显示正常。颜色映射异常如下:
| 预期颜色 | 实际显示颜色 |
|---|---|
| 红色 | 蓝色 |
| 绿色 | 非标准红色 |
| 蓝色 | 绿色 |
代码示例
driver.c
void lcd_set_color(uint16_t color) { uint16_t color_swap = swap_high_low(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_swap; } for (int y = 0; y < 240; y++) // 显示整屏颜色 { esp_lcd_panel_draw_bitmap(panel_handle, 0, y, 320, y + 1, buffer); } free(buffer); // 释放内存 } }
main.c
#include <stdio.h> #include "esp32_s3_szp.h" #include "logo_en_240x240_lcd.h" #include "yingwu.h" #include "demos/lv_demos.h" // 将RGB565 change to RGB888 format uint32_t rgb565_to_rgb888(uint16_t rgb565) { uint8_t r = (rgb565 >> 11) << 3; uint8_t g = ((rgb565 >> 5) & 0x3F) << 2; uint8_t b = (rgb565 & 0x1F) << 3; return (uint32_t)(r << 16) | (uint32_t)(g << 8) | (uint32_t)b; } void app_main(void) { bsp_i2c_init(); // I2C初始化 pca9557_init(); // IO扩展芯片初始化 bsp_lvgl_start(); // 初始化液晶屏lvgl接口 // lcd_set_color(0x001F); // blue rgb565 uint32_t blue_rgb888 = rgb565_to_rgb888(0xF800); //red // // 使用lvgl绘制一个矩形 lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(blue_rgb888), LV_PART_MAIN); // /*Create a white label, set its text and align it to the center*/ // lv_obj_t *label = lv_label_create(lv_scr_act()); // lv_label_set_text(label, "Hello JLF"); // lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN); // lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); // /* 下面5个demos 只打开1个运行 */ // // lv_demo_benchmark(); // // lv_demo_keypad_encoder(); // // lv_demo_music(); // // lv_demo_stress(); // // lv_demo_widgets(); }
原因分析
- 字节序不匹配:自定义
lcd_set_color函数中对RGB565颜色值执行了swap_high_low字节交换,而LVGL显示驱动未做相同处理。ST7789液晶屏要求颜色数据以特定字节序传输,LVGL默认输出的字节序与之不符,导致颜色错位。 - RGB通道顺序不匹配:ST7789初始化时可能配置为BGR颜色格式,而LVGL默认使用RGB格式输出颜色,造成通道映射反转,出现红/蓝、绿/红的错位显示。
解决办法
方法1:在LVGL显示驱动中添加字节交换处理
找到LVGL显示驱动的刷新回调函数(通常在lv_port_disp.c的disp_flush_cb函数中),在将LVGL输出的颜色数据发送到LCD前,对每个RGB565颜色值执行字节交换:
static void disp_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) { esp_lcd_panel_handle_t panel_handle = lv_display_get_user_data(disp); int32_t x1 = area->x1; int32_t y1 = area->y1; int32_t x2 = area->x2; int32_t y2 = area->y2; // 对颜色数据执行字节交换,和自定义函数逻辑一致 uint16_t *rgb565_data = (uint16_t *)px_map; size_t pixel_count = (x2 - x1 + 1) * (y2 - y1 + 1); for(size_t i = 0; i < pixel_count; i++) { rgb565_data[i] = swap_high_low(rgb565_data[i]); } esp_lcd_panel_draw_bitmap(panel_handle, x1, y1, x2 + 1, y2 + 1, rgb565_data); lv_display_flush_ready(disp); }
方法2:调整LVGL的颜色通道配置
在LVGL配置文件(lv_conf.h)中,修改颜色格式为BGR,匹配ST7789的设置:
#define LV_COLOR_DEPTH 16 #define LV_COLOR_FORMAT LV_COLOR_FORMAT_BGR565
若使用RGB888格式,对应修改为LV_COLOR_FORMAT_BGR888。
方法3:检查ST7789初始化命令
确认ST7789初始化时的0x36 MADCTL命令配置,确保颜色通道顺序与LVGL一致。例如,若MADCTL命令设置了BGR位(bit3),则LVGL需对应使用BGR格式;若未设置,则使用RGB格式。
内容的提问来源于stack exchange,提问作者Yunfei
相关产品推荐
相关产品推荐

