You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

单SPI总线驱动双物理屏:LVGL下副屏横屏显示画面异常

问题:双屏LVGL横屏显示异常

在Adafruit Feather ESP32-S3上使用LVGL驱动两块ILI9341屏幕时遇到问题:基础Adafruit_GFX驱动单独工作正常,但接入LVGL后,主屏显示正常,副屏设置为横屏(旋转角度3)时画面损坏。将副屏旋转角度改为0或2,或者移除LVGL仅用Adafruit驱动时,副屏显示恢复正常。Arduino IDE编译无内存报错,下图右侧为主屏,左侧为异常的副屏。

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <lvgl.h>
// 验证可用的SPI + ILI9341引脚
#define TFT_SCK  12
#define TFT_MOSI 11
// 上方屏幕(ILI9341)引脚 - 已验证
#define UPPER_CS   10
#define UPPER_DC   9
#define UPPER_RST  6

// 下方屏幕引脚
#define LOWER_CS  14
#define LOWER_DC  8
#define LOWER_RST 5

Adafruit_ILI9341 upper(UPPER_CS, UPPER_DC, UPPER_RST);
Adafruit_ILI9341  lower(LOWER_CS, LOWER_DC, LOWER_RST);

inline void selectUpper()   { digitalWrite(LOWER_CS, HIGH); digitalWrite(UPPER_CS, LOW); }
inline void deselectUpper() { digitalWrite(UPPER_CS, HIGH); }

inline void selectLower()   { digitalWrite(UPPER_CS, HIGH); digitalWrite(LOWER_CS, LOW); }
inline void deselectLower() { digitalWrite(LOWER_CS, HIGH); }

#define UPPER_TFT_HOR_RES 320
#define UPPER_TFT_VER_RES 240

#define LOWER_TFT_HOR_RES 320
#define LOWER_TFT_VER_RES 240

static void flush_upper(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
{
  const uint32_t w = area->x2 - area->x1 + 1;
  const uint32_t h = area->y2 - area->y1 + 1;

  selectUpper();
  upper.startWrite();
  upper.setAddrWindow(area->x1, area->y1, w, h);
  upper.writePixels((uint16_t*)px_map, w * h, true);
  upper.endWrite();
  deselectUpper();

  lv_display_flush_ready(disp);
}

static void flush_lower(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
{
  const uint32_t w = area->x2 - area->x1 + 1;
  const uint32_t h = area->y2 - area->y1 + 1;

  selectLower();
  lower.startWrite();
  lower.setAddrWindow(area->x1, area->y1, w, h);
  lower.writePixels((uint16_t*)px_map, w * h, true);
  lower.endWrite();
  deselectLower();

  lv_display_flush_ready(disp);
}

static uint32_t my_tick_cb(void)
{
    return millis();
}

void setup() {
  Serial.begin(115200);
  delay(200);

  pinMode(UPPER_CS, OUTPUT);
  pinMode(LOWER_CS, OUTPUT);
  pinMode(UPPER_DC, OUTPUT);
  pinMode(LOWER_DC, OUTPUT);

  digitalWrite(UPPER_CS, HIGH);
  digitalWrite(LOWER_CS, HIGH);

  /*初始化LVGL*/
  lv_init();

  /*为LVGL设置基于毫秒的时钟源,用于时间追踪*/
  lv_tick_set_cb(my_tick_cb);

  lv_display_t * upperDisplay = lv_display_create(UPPER_TFT_HOR_RES, UPPER_TFT_VER_RES);
  lv_display_t * lowerDisplay = lv_display_create(LOWER_TFT_HOR_RES, LOWER_TFT_VER_RES);

  static lv_color_t upperBuf[UPPER_TFT_HOR_RES * UPPER_TFT_VER_RES / 10 ];
  lv_display_set_buffers(upperDisplay, upperBuf, NULL, sizeof(upperBuf), LV_DISPLAY_RENDER_MODE_PARTIAL);

  static lv_color_t lowerBuf[LOWER_TFT_HOR_RES * LOWER_TFT_VER_RES / 10 ];
  lv_display_set_buffers(lowerDisplay, lowerBuf, NULL, sizeof(lowerBuf), LV_DISPLAY_RENDER_MODE_PARTIAL);

  lv_display_set_flush_cb(upperDisplay, flush_upper);
  lv_display_set_flush_cb(lowerDisplay, flush_lower);

  SPI.begin(TFT_SCK, -1, TFT_MOSI);

  // --- 初始化上方屏幕 ---
  selectUpper();
  upper.begin();
  upper.setSPISpeed(8000000);
  upper.setRotation(3);
  upper.fillScreen(ILI9341_BLACK);
  deselectUpper();

  // --- 初始化下方屏幕 ---
  selectLower();
  lower.begin();
  lower.setSPISpeed(8000000);
  lower.setRotation(3);
  Serial.print("lower width = ");
  Serial.println(lower.width());
  Serial.print("lower height = ");
  Serial.println(lower.height());
  lower.fillScreen(ILI9341_BLACK);
  delay(500);
  lower.fillScreen(ILI9341_RED);
  deselectLower();

  lv_obj_t * upperScreen = lv_display_get_screen_active(upperDisplay);
  lv_obj_t * lowerScreen = lv_display_get_screen_active(lowerDisplay);

  lv_obj_t * upperLabel = lv_label_create(upperScreen);
  lv_label_set_text(upperLabel, "Hello world");
  lv_obj_center(upperLabel);

  lv_obj_t * lowerLabel = lv_label_create(lowerScreen);
  lv_label_set_text(lowerLabel, "Hi");
  lv_obj_center(lowerLabel);

}

void loop() {
  lv_timer_handler();
  delay(5); 
}

显示异常的双屏

内容的提问来源于stack exchange,提问作者Collin

火山引擎 最新活动