# display **Repository Path**: NetADs/display ## Basic Information - **Project Name**: display - **Description**: ESP-IDF架构。ESP32-S3-N16R8,TFT_LCD320x240SPI屏,ST7789V驱动。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-26 - **Last Updated**: 2026-06-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ESP-IDF ST7789 显示驱动组件 适用于 ESP32 平台的 ST7789 显示驱动组件。 ## 特性 - 支持 ST7789 显示面板 - 支持 SPI 接口 - 兼容 ESP-IDF v5.x - 模块化驱动架构 - 内置 PWM 背光控制 - 显示旋转和颜色反转 ## 目录结构 ``` components/display/ ├── CMakeLists.txt # 组件构建配置 ├── Kconfig # 组件配置选项 ├── idf_component.yml # 组件元数据 ├── include/ │ └── display.h # 公共 API ├── src/ │ ├── display.c # 主实现 │ ├── display_interface.c # SPI 接口层 │ └── private/ │ └── display_interface.h # 私有接口头文件 ├── drivers/ │ └── st7789.c/h # ST7789 驱动 ├── docs/ # 文档 └── examples/ # 示例应用 ``` ## 安装 ### 方式一:复制到组件目录 将 `display` 文件夹复制到项目的 `components` 目录: ``` your_project/ ├── components/ │ └── display/ ├── main/ └── CMakeLists.txt ``` 项目顶层 `CMakeLists.txt` 中添加: ```cmake set(EXTRA_COMPONENT_DIRS components) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(your_project_name) ``` ### 方式二:通过 git 依赖自动下载 在 `main/idf_component.yml` 中添加: ```yaml dependencies: display: git: https://gitee.com/NetADs/display.git path: components/display ``` 执行 `idf.py reconfigure` 后,组件管理器会自动克隆仓库并下载到 `managed_components/display/`。 ### 方式三:本地路径引用 在 `main/idf_component.yml` 中添加: ```yaml dependencies: display: path: components/display ``` ## 配置 运行 `idf.py menuconfig` → `Component config` → `Display Driver Configuration` 进行配置: - SPI 接口的 GPIO 引脚 - 显示分辨率 - SPI 时钟频率 ## 使用示例 ### 基础初始化 ```c #include "display.h" void app_main(void) { display_config_t cfg = { // SPI 引脚 .sck = 21, .mosi = 47, .cs = 41, .dc = 40, .rst = 45, .bl = 42, .bl_on_level = 1, // 显示参数 .width = 240, .height = 320, .clk_hz = 40 * 1000 * 1000, }; ESP_ERROR_CHECK(display_init(&cfg)); // 填充红色 ESP_ERROR_CHECK(display_clear(0xF800)); // 绘制绿色像素点 ESP_ERROR_CHECK(display_set_pixel(50, 50, 0x07E0)); } ``` ### 使用 menuconfig 配置 ```c #include "display.h" #include "sdkconfig.h" void app_main(void) { display_config_t cfg = { // 使用 menuconfig 中的配置 .width = CONFIG_DISPLAY_WIDTH, .height = CONFIG_DISPLAY_HEIGHT, }; ESP_ERROR_CHECK(display_init(&cfg)); } ``` ## API 参考 ### 核心函数 | 函数 | 描述 | |----------|-------------| | `display_init()` | 初始化显示驱动 | | `display_deinit()` | 反初始化显示驱动 | | `display_is_ready()` | 检查初始化状态 | ### 显示控制 | 函数 | 描述 | |----------|-------------| | `display_set_backlight()` | 设置亮度(0-100) | | `display_get_backlight()` | 获取当前亮度 | | `display_set_rotation()` | 设置旋转角度 | | `display_get_rotation()` | 获取当前旋转角度 | | `display_invert_colors()` | 反转颜色 | | `display_is_inverted()` | 获取反转状态 | | `display_sleep()` | 进入休眠模式 | | `display_wakeup()` | 唤醒 | ### 绘图函数 | 函数 | 描述 | |----------|-------------| | `display_draw_area()` | 绘制位图区域 | | `display_fill_area()` | 填充颜色区域 | | `display_set_pixel()` | 设置单个像素 | | `display_clear()` | 清屏 | ### 访问器 | 函数 | 描述 | |----------|-------------| | `display_get_panel()` | 获取面板句柄 | | `display_get_io()` | 获取 IO 句柄 | | `display_get_width()` | 获取显示宽度 | | `display_get_height()` | 获取显示高度 | ## 支持的面板 | 面板 | 接口 | 状态 | |-------|-----------|--------| | ST7789 | SPI | ✅ | | GC9A01 | SPI | TODO | | ST7735 | SPI | TODO | ## 添加新的面板驱动 要支持新的面板类型: 1. 在 `drivers/your_panel.c` 中创建驱动实现: ```c #include "your_panel.h" #include "esp_lcd_panel_vendor.h" esp_err_t your_panel_panel_init(esp_lcd_panel_io_handle_t io, esp_lcd_panel_handle_t *panel, uint16_t width, uint16_t height, int8_t rst_gpio_num) { esp_lcd_panel_dev_config_t cfg = { .reset_gpio_num = (rst_gpio_num >= 0) ? rst_gpio_num : GPIO_NUM_NC, .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_BIG, }; return esp_lcd_new_panel_st7789(io, &cfg, panel); } ``` 2. 在 `drivers/your_panel.h` 中创建头文件 3. 在 `src/display.c` 的 `create_panel()` 函数中添加调用 4. 更新 `CMakeLists.txt` 包含新的源文件 ## LVGL 集成 ### 层分离设计 驱动层与显示层职责独立: - **驱动层** (`display.c`):始终反映物理分辨率 (240x320),`display_get_width()` / `display_get_height()` 返回物理尺寸不随旋转变化。`display_set_rotation()` 仅操作 ST7789 硬件 MADCTL 寄存器完成坐标映射,不修改逻辑尺寸。 - **显示层** (LVGL):自行管理逻辑分辨率。横屏模式下 LVGL 使用 `hres=320, vres=240` 作为渲染空间。 LVGL flush 回调中坐标直接传递给 `esp_lcd_panel_draw_bitmap()`,硬件侧 swap_xy 已开启,自动完成物理地址映射。 ### 竖屏模式 (240x320) ```c #include "display.h" #include "esp_lvgl_port.h" void app_main(void) { display_config_t cfg = { .width = 240, .height = 320, // ... 引脚配置 ... }; ESP_ERROR_CHECK(display_init(&cfg)); const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG(); ESP_ERROR_CHECK(lvgl_port_init(&lvgl_cfg)); lvgl_port_display_cfg_t disp_cfg = { .io_handle = display_get_io(), .panel_handle = display_get_panel(), .hres = 240, .vres = 320, }; lv_disp_t *disp = lvgl_port_add_disp(&disp_cfg); lvgl_port_start(); } ``` ### 横屏模式 (320x240) 驱动层以物理分辨率初始化,显示层设置逻辑横屏分辨率并调用旋转: ```c #include "display.h" #include "esp_lvgl_port.h" void app_main(void) { // 驱动层始终使用物理分辨率初始化 display_config_t cfg = { .width = 240, .height = 320, // ... 引脚配置 ... }; ESP_ERROR_CHECK(display_init(&cfg)); // 旋转硬件到横屏 (仅操作 MADCTL,不修改逻辑尺寸) display_set_rotation(DISPLAY_ROTATION_90); const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG(); ESP_ERROR_CHECK(lvgl_port_init(&lvgl_cfg)); // 显示层设置逻辑横屏分辨率 lvgl_port_display_cfg_t disp_cfg = { .io_handle = display_get_io(), .panel_handle = display_get_panel(), .hres = 320, .vres = 240, }; lv_disp_t *disp = lvgl_port_add_disp(&disp_cfg); // LVGL 在 320x240 逻辑空间渲染 // flush 回调中坐标直接透传,硬件 swap_xy 完成物理映射 lvgl_port_start(); } ``` ## 依赖 - `esp_lcd`(ESP-IDF 组件) - `driver`(ESP-IDF 组件) 可选的: - `esp_lvgl_port` + `lvgl`(用于 LVGL 集成) ## 许可证 MIT License