You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
}
原因分析
  1. 字节序不匹配:自定义lcd_set_color函数中对RGB565颜色值执行了swap_high_low字节交换,而LVGL显示驱动未做相同处理。ST7789液晶屏要求颜色数据以特定字节序传输,LVGL默认输出的字节序与之不符,导致颜色错位。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:50:57