esp32-s3通过tft_espi驱动ST7789v2屏幕并运行LVGL

依赖:

需要指定espressif32的版本为6.5.0,否则会出现Guru Meditation Error: Core 0 panic'ed (Store access fault). Exception was unhandled.

参考

Guru Meditation Error: Core 1 panic'ed · Issue #3429 · Bodmer/TFT_eSPI 
https://github.com/Bodmer/TFT_eSPI/issues/3429

TFT Feather S3 resets when init() is called · Issue #3568 · Bodmer/TFT_eSPI 
https://github.com/Bodmer/TFT_eSPI/issues/3568

[env:esp32-s3]
platform = espressif32@6.5.0
board = esp32-s3-devkitc-1
framework = arduino
monitor_speed = 115200
build_type = debug

lib_deps =
    lvgl/lvgl
    bodmer/TFT_eSPI

 

参考esp32-s3官方文档配置GPIO,该内容替换到.pio/libdeps/esp32-s3/TFT_eSPI/User_Setup.h(目前没有发现更好的方法):

SPI 主机驱动程序 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/api-reference/peripherals/spi_master.html

此处选用的是HSPI,#define USE_HSPI_PORT为必选。

#define ST7789_2_DRIVER

#define USE_HSPI_PORT
#define TFT_SDA_READ

#define TFT_WIDTH  240
#define TFT_HEIGHT 320

// 配置SPI引脚
#define TFT_CS   10
#define TFT_MOSI 11
#define TFT_SCLK 12
#define TFT_MISO   -1

#define TFT_DC   14
#define TFT_RST  15
#define TFT_BL   16

#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT

//#define SPI_FREQUENCY  40000000
#define  SPI_FREQUENCY 27000000
//#define  SPI_READ_FREQUENCY 20000000
//#define  SPI_TOUCH_FREQUENCY 2500000

#define TFT_BACKLIGHT_ON LOW

 参考网上资料将以下内容替换到.pio/libdeps/esp32-s3/lvgl/lv_conf.h

#define LV_CONF_INCLUDE_SIMPLE 1
#define LV_COLOR_DEPTH 16
//#define LV_USE_PERF_MONITOR 1
#define LV_USE_DEMO_WIDGETS 1

 

屏幕初始化和绘制:


#include "tft.h"
#include "TFT_eSPI.h"
#include <lvgl.h>
#include "User_Setup.h"

TFT_eSPI tft = TFT_eSPI(); // TFT实例

lv_display_t *display;

// 缓冲区大小(16-bit 色深)
static lv_color_t buf1[TFT_WIDTH * 10];

void my_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
    int32_t w = lv_area_get_width(area);
    int32_t h = lv_area_get_height(area);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushPixels((uint16_t *) px_map, w * h);
    tft.endWrite();

    lv_display_flush_ready(disp);
}


void tft_init() {
    tft.init();
    tft.fillScreen(TFT_BLACK);

    lv_init();

    display = lv_display_create(TFT_WIDTH, TFT_HEIGHT);
    lv_display_set_flush_cb(display, my_flush_cb);
    lv_display_set_buffers(display, buf1, nullptr, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL);

    LV_FONT_DECLARE(MapleMonoRegular)

    lv_obj_t *btn = lv_button_create(lv_screen_active());
    lv_obj_center(btn);
    lv_obj_t *label = lv_label_create(btn);
    lv_label_set_text(label, "我真日了真的");
    lv_obj_center(label);
    lv_obj_set_style_text_font(label, &MapleMonoRegular, LV_PART_MAIN | LV_STATE_DEFAULT);

    Serial.print("inited");
}


void refresh() {
    lv_timer_handler(); // 处理LVGL任务
    vTaskDelay(5);           // 调整刷新率
}

 

额外:

实现中文显示的方法,需要将需要用到的文字转为lvgl字体数组,可用

Font Converter — LVGL 
https://lvgl.io/tools/fontconverter
来进行转换。

参考

LVGL显示中文汉字【看这一篇就够了】-CSDN博客 
https://blog.csdn.net/weixin_41880709/article/details/128065133

posted @ 2025-05-10 18:43  Jackie_JK  阅读(51)  评论(0)    收藏  举报