添加 UI 变量管理并重构主应用程序结构
引入 vars.c 和 vars.h 用于管理与 UI 相关的全局变量。 新增 get_var_weigt_ui 和 set_var_weigt_ui 函数,用于访问和修改 UI 重量变量。 更新 CMakeLists.txt 以包含新的 UI 和 LVGL 依赖项。 将 main.c 转换为 main.cpp 以支持 C++ 特性,并重构了应用程序入口点。 实现了使用 FreeRTOS 定期更新 UI 的 UI 任务。 在 partitions.csv 中创建自定义分区表,用于管理闪存空间。 添加 update_sdkconfig.sh 脚本,自动更新 SDK 配置中的闪存大小和 SPIRAM 设置。 移除旧的 main.c 文件以精简项目结构。
This commit is contained in:
4
components/lvgl_st7789_use/CMakeLists.txt
Normal file
4
components/lvgl_st7789_use/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
idf_component_register(SRCS "lvgl_st7789_use.c"
|
||||||
|
INCLUDE_DIRS "include"
|
||||||
|
REQUIRES driver esp_lcd esp_lvgl_port
|
||||||
|
)
|
||||||
59
components/lvgl_st7789_use/Kconfig.projbuild
Normal file
59
components/lvgl_st7789_use/Kconfig.projbuild
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
menu "LVGL ST7789 显示屏配置"
|
||||||
|
|
||||||
|
config LVGL_ST7789_LCD_H_RES
|
||||||
|
int "LCD 水平分辨率 (H_RES)"
|
||||||
|
range 1 1000
|
||||||
|
default 240
|
||||||
|
help
|
||||||
|
LCD 屏幕的水平分辨率(像素)。
|
||||||
|
|
||||||
|
config LVGL_ST7789_LCD_V_RES
|
||||||
|
int "LCD 垂直分辨率 (V_RES)"
|
||||||
|
range 1 1000
|
||||||
|
default 240
|
||||||
|
help
|
||||||
|
LCD 屏幕的垂直分辨率(像素)。
|
||||||
|
|
||||||
|
config LVGL_ST7789_GPIO_SCLK
|
||||||
|
int "LCD SCLK GPIO"
|
||||||
|
range 0 39
|
||||||
|
default 2
|
||||||
|
help
|
||||||
|
LCD SPI 时钟引脚 GPIO 号。
|
||||||
|
|
||||||
|
config LVGL_ST7789_GPIO_MOSI
|
||||||
|
int "LCD MOSI GPIO"
|
||||||
|
range 0 39
|
||||||
|
default 3
|
||||||
|
help
|
||||||
|
LCD SPI MOSI 引脚 GPIO 号。
|
||||||
|
|
||||||
|
config LVGL_ST7789_GPIO_RST
|
||||||
|
int "LCD RST GPIO"
|
||||||
|
range 0 39
|
||||||
|
default 9
|
||||||
|
help
|
||||||
|
LCD 复位引脚 GPIO 号。
|
||||||
|
|
||||||
|
config LVGL_ST7789_GPIO_DC
|
||||||
|
int "LCD DC GPIO"
|
||||||
|
range 0 39
|
||||||
|
default 8
|
||||||
|
help
|
||||||
|
LCD 数据/命令引脚 GPIO 号。
|
||||||
|
|
||||||
|
config LVGL_ST7789_GPIO_CS
|
||||||
|
int "LCD CS GPIO"
|
||||||
|
range 0 39
|
||||||
|
default 7
|
||||||
|
help
|
||||||
|
LCD 片选引脚 GPIO 号。
|
||||||
|
|
||||||
|
config LVGL_ST7789_GPIO_BL
|
||||||
|
int "LCD 背光 GPIO (NC为-1)"
|
||||||
|
range -1 39
|
||||||
|
default -1
|
||||||
|
help
|
||||||
|
LCD 背光引脚 GPIO 号,未连接请填-1。
|
||||||
|
|
||||||
|
endmenu
|
||||||
114
components/lvgl_st7789_use/README.md
Normal file
114
components/lvgl_st7789_use/README.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# lvgl_st7789_use 组件说明
|
||||||
|
|
||||||
|
`lvgl_st7789_use` 是项目中的 LCD 显示组件,基于 `esp_lcd + esp_lvgl_port`,用于快速驱动 ST7789 SPI 屏并显示 LVGL 界面。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 功能概览
|
||||||
|
|
||||||
|
- 初始化 SPI LCD(含背光、面板、显示偏移)
|
||||||
|
- 初始化 LVGL 端口并注册显示设备
|
||||||
|
- 默认创建一个居中标签用于快速验证显示链路
|
||||||
|
- 提供运行时更新中心文本接口
|
||||||
|
- 支持可配置方向、镜像与偏移
|
||||||
|
- 支持可选三色测试图(调试用)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 对外 API
|
||||||
|
|
||||||
|
头文件:`include/lvgl_st7789_use.h`
|
||||||
|
|
||||||
|
- `esp_err_t start_lvgl_demo(void);`
|
||||||
|
- 完成 LCD + LVGL 初始化并创建默认界面
|
||||||
|
|
||||||
|
- `esp_err_t lvgl_st7789_set_center_text(const char *text);`
|
||||||
|
- 运行时更新中心标签文字(线程安全,内部已加锁)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 关键配置项(可直接改宏)
|
||||||
|
|
||||||
|
在 `include/lvgl_st7789_use.h` 中:
|
||||||
|
|
||||||
|
### 1) 屏幕与 SPI
|
||||||
|
|
||||||
|
- `EXAMPLE_LCD_H_RES` / `EXAMPLE_LCD_V_RES`
|
||||||
|
- `EXAMPLE_LCD_PIXEL_CLK_HZ`
|
||||||
|
- `EXAMPLE_LCD_SPI_NUM`
|
||||||
|
- `EXAMPLE_LCD_CMD_BITS` / `EXAMPLE_LCD_PARAM_BITS`
|
||||||
|
|
||||||
|
建议:ST7789 默认可先用 `20MHz`,如出现花屏或不稳定再降到 `10MHz` 复测。
|
||||||
|
|
||||||
|
### 2) 颜色校准(重点)
|
||||||
|
|
||||||
|
- `EXAMPLE_LCD_COLOR_ORDER_BGR`
|
||||||
|
- `EXAMPLE_LCD_INVERT_COLOR`
|
||||||
|
- `EXAMPLE_LCD_SWAP_BYTES`
|
||||||
|
|
||||||
|
说明:
|
||||||
|
- 出现“黑色发灰、红绿蓝偏紫/互串”时,优先调整这三项。
|
||||||
|
- 建议从 `RGB + 不反色 + 不交换字节` 起步,再逐项切换。
|
||||||
|
|
||||||
|
### 3) 方向与偏移(重点)
|
||||||
|
|
||||||
|
- `EXAMPLE_LCD_GAP_X`
|
||||||
|
- `EXAMPLE_LCD_GAP_Y`
|
||||||
|
- `EXAMPLE_LCD_ROT_SWAP_XY`
|
||||||
|
- `EXAMPLE_LCD_ROT_MIRROR_X`
|
||||||
|
- `EXAMPLE_LCD_ROT_MIRROR_Y`
|
||||||
|
|
||||||
|
说明:
|
||||||
|
- 若出现“文字偏移/边缘花屏/方向反了”,优先微调上述宏,不要同时在多层重复旋转。
|
||||||
|
|
||||||
|
### 4) 调试项
|
||||||
|
|
||||||
|
- `EXAMPLE_LCD_ENABLE_COLOR_TEST`
|
||||||
|
- `1`:上电先画 RGB 三色测试图(便于确认硬件链路)
|
||||||
|
- `0`:跳过测试,直接进入 LVGL
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 在主程序中调用
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "lvgl_st7789_use.h"
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(start_lvgl_demo());
|
||||||
|
ESP_ERROR_CHECK(lvgl_st7789_set_center_text("BotanicalBuddy"));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### 1) 背光亮但没有内容
|
||||||
|
|
||||||
|
优先排查:
|
||||||
|
- 面板型号与驱动是否匹配(当前应为 ST7789)
|
||||||
|
- SPI 模式、时钟是否过高
|
||||||
|
- 方向/偏移参数是否正确
|
||||||
|
|
||||||
|
### 2) 文字方向反了或显示偏移
|
||||||
|
|
||||||
|
优先调整:
|
||||||
|
- `EXAMPLE_LCD_ROT_*`
|
||||||
|
- `EXAMPLE_LCD_GAP_X / EXAMPLE_LCD_GAP_Y`
|
||||||
|
|
||||||
|
### 3) 想快速确认硬件链路是否通
|
||||||
|
|
||||||
|
把 `EXAMPLE_LCD_ENABLE_COLOR_TEST` 设为 `1`,观察是否能显示三色图。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 依赖
|
||||||
|
|
||||||
|
由组件 `CMakeLists.txt` 声明:
|
||||||
|
|
||||||
|
- `driver`
|
||||||
|
- `esp_lcd`
|
||||||
|
- `esp_lvgl_port`
|
||||||
80
components/lvgl_st7789_use/include/lvgl_st7789_use.h
Normal file
80
components/lvgl_st7789_use/include/lvgl_st7789_use.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* LCD pins */
|
||||||
|
#ifndef EXAMPLE_LCD_GPIO_SCLK
|
||||||
|
#define EXAMPLE_LCD_GPIO_SCLK CONFIG_LVGL_ST7789_GPIO_SCLK
|
||||||
|
#endif
|
||||||
|
#ifndef EXAMPLE_LCD_GPIO_MOSI
|
||||||
|
#define EXAMPLE_LCD_GPIO_MOSI CONFIG_LVGL_ST7789_GPIO_MOSI
|
||||||
|
#endif
|
||||||
|
#ifndef EXAMPLE_LCD_GPIO_RST
|
||||||
|
#define EXAMPLE_LCD_GPIO_RST CONFIG_LVGL_ST7789_GPIO_RST
|
||||||
|
#endif
|
||||||
|
#ifndef EXAMPLE_LCD_GPIO_DC
|
||||||
|
#define EXAMPLE_LCD_GPIO_DC CONFIG_LVGL_ST7789_GPIO_DC
|
||||||
|
#endif
|
||||||
|
#ifndef EXAMPLE_LCD_GPIO_CS
|
||||||
|
#define EXAMPLE_LCD_GPIO_CS CONFIG_LVGL_ST7789_GPIO_CS
|
||||||
|
#endif
|
||||||
|
#ifndef EXAMPLE_LCD_GPIO_BL
|
||||||
|
#define EXAMPLE_LCD_GPIO_BL CONFIG_LVGL_ST7789_GPIO_BL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* LCD size (ST7789 240x240) */
|
||||||
|
// 可通过 menuconfig 配置
|
||||||
|
#ifndef EXAMPLE_LCD_H_RES
|
||||||
|
#define EXAMPLE_LCD_H_RES CONFIG_LVGL_ST7789_LCD_H_RES
|
||||||
|
#endif
|
||||||
|
#ifndef EXAMPLE_LCD_V_RES
|
||||||
|
#define EXAMPLE_LCD_V_RES CONFIG_LVGL_ST7789_LCD_V_RES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* LCD SPI总线配置 */
|
||||||
|
#define EXAMPLE_LCD_SPI_NUM (SPI2_HOST) // 使用SPI2主机接口进行通信
|
||||||
|
|
||||||
|
/* LCD显示参数配置 */
|
||||||
|
#define EXAMPLE_LCD_PIXEL_CLK_HZ (20 * 1000 * 1000) // ST7789常用20MHz,兼顾稳定性与刷新速度
|
||||||
|
|
||||||
|
/* LCD命令和参数配置 */
|
||||||
|
#define EXAMPLE_LCD_CMD_BITS (8) // 命令位数为8位,用于发送LCD控制命令
|
||||||
|
#define EXAMPLE_LCD_PARAM_BITS (8) // 参数位数为8位,用于发送命令参数
|
||||||
|
|
||||||
|
/* LCD颜色和缓冲区配置 */
|
||||||
|
#define EXAMPLE_LCD_BITS_PER_PIXEL (16) // 每个像素使用16位颜色(RGB565格式)
|
||||||
|
#define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (1) // 启用双缓冲模式,提高显示流畅度
|
||||||
|
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (50) // 绘图缓冲区高度为50行,影响刷新性能
|
||||||
|
|
||||||
|
/* ST7789颜色配置(出现偏色时优先调整这三项) */
|
||||||
|
#define EXAMPLE_LCD_COLOR_ORDER_BGR (0) // 0: RGB, 1: BGR
|
||||||
|
#define EXAMPLE_LCD_INVERT_COLOR (1) // 0: 正常色, 1: 反色
|
||||||
|
#define EXAMPLE_LCD_SWAP_BYTES (1) // 0: 不交换RGB565高低字节, 1: 交换
|
||||||
|
|
||||||
|
/* LCD背光配置 */
|
||||||
|
#define EXAMPLE_LCD_BL_ON_LEVEL (1) // 背光开启电平为高电平(1)
|
||||||
|
|
||||||
|
/* LCD方向/偏移配置 */
|
||||||
|
#define EXAMPLE_LCD_GAP_X (0)
|
||||||
|
#define EXAMPLE_LCD_GAP_Y (0)
|
||||||
|
#define EXAMPLE_LCD_ROT_SWAP_XY (1)
|
||||||
|
#define EXAMPLE_LCD_ROT_MIRROR_X (1)
|
||||||
|
#define EXAMPLE_LCD_ROT_MIRROR_Y (0)
|
||||||
|
|
||||||
|
/* 调试项:上电后是否先显示三色测试图 */
|
||||||
|
#define EXAMPLE_LCD_ENABLE_COLOR_TEST (0)
|
||||||
|
|
||||||
|
|
||||||
|
esp_err_t start_lvgl_demo(void);
|
||||||
|
esp_err_t lvgl_st7789_set_center_text(const char *text);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
257
components/lvgl_st7789_use/lvgl_st7789_use.c
Normal file
257
components/lvgl_st7789_use/lvgl_st7789_use.c
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "lvgl_st7789_use.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "driver/spi_master.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "esp_lcd_panel_io.h"
|
||||||
|
#include "esp_lcd_panel_vendor.h"
|
||||||
|
#include "esp_lcd_panel_ops.h"
|
||||||
|
#include "esp_lvgl_port.h"
|
||||||
|
|
||||||
|
static const char *TAG = "lvgl_st7789_use";
|
||||||
|
|
||||||
|
static esp_lcd_panel_io_handle_t lcd_io = NULL;
|
||||||
|
static esp_lcd_panel_handle_t lcd_panel = NULL;
|
||||||
|
static lv_display_t *lvgl_disp = NULL;
|
||||||
|
static lv_obj_t *s_center_label = NULL;
|
||||||
|
|
||||||
|
#if EXAMPLE_LCD_ENABLE_COLOR_TEST
|
||||||
|
static esp_err_t app_lcd_color_test(void)
|
||||||
|
{
|
||||||
|
const size_t pixels = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES;
|
||||||
|
uint16_t *frame = calloc(pixels, sizeof(uint16_t));
|
||||||
|
ESP_RETURN_ON_FALSE(frame != NULL, ESP_ERR_NO_MEM, TAG, "分配测试帧缓冲失败");
|
||||||
|
|
||||||
|
for (int y = 0; y < EXAMPLE_LCD_V_RES; y++) {
|
||||||
|
for (int x = 0; x < EXAMPLE_LCD_H_RES; x++) {
|
||||||
|
uint16_t color;
|
||||||
|
if (x < EXAMPLE_LCD_H_RES / 3) {
|
||||||
|
color = 0xF800; // 红
|
||||||
|
} else if (x < (EXAMPLE_LCD_H_RES * 2) / 3) {
|
||||||
|
color = 0x07E0; // 绿
|
||||||
|
} else {
|
||||||
|
color = 0x001F; // 蓝
|
||||||
|
}
|
||||||
|
frame[y * EXAMPLE_LCD_H_RES + x] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t err = esp_lcd_panel_draw_bitmap(lcd_panel, 0, 0, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, frame);
|
||||||
|
free(frame);
|
||||||
|
ESP_RETURN_ON_ERROR(err, TAG, "三色测试绘制失败");
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "LCD三色测试图已发送");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化LCD硬件和SPI接口
|
||||||
|
*
|
||||||
|
* 该函数负责初始化LCD所需的GPIO、SPI总线,并配置LCD面板
|
||||||
|
* 包括背光控制、SPI总线配置、面板IO配置和面板驱动安装
|
||||||
|
*
|
||||||
|
* @return esp_err_t 初始化结果,ESP_OK表示成功
|
||||||
|
*/
|
||||||
|
static esp_err_t app_lcd_init(void)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
|
||||||
|
if (EXAMPLE_LCD_GPIO_BL != GPIO_NUM_NC && EXAMPLE_LCD_GPIO_BL >= 0) {
|
||||||
|
gpio_config_t bk_gpio_config = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = 1ULL << EXAMPLE_LCD_GPIO_BL
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "背光引脚未配置(GPIO_NUM_NC 或 <0),跳过背光GPIO初始化");
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "初始化SPI总线");
|
||||||
|
const spi_bus_config_t buscfg = {
|
||||||
|
.sclk_io_num = EXAMPLE_LCD_GPIO_SCLK,
|
||||||
|
.mosi_io_num = EXAMPLE_LCD_GPIO_MOSI,
|
||||||
|
.miso_io_num = GPIO_NUM_NC,
|
||||||
|
.quadwp_io_num = GPIO_NUM_NC,
|
||||||
|
.quadhd_io_num = GPIO_NUM_NC,
|
||||||
|
.max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t),
|
||||||
|
};
|
||||||
|
ESP_RETURN_ON_ERROR(spi_bus_initialize(EXAMPLE_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI初始化失败");
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "安装面板IO");
|
||||||
|
const esp_lcd_panel_io_spi_config_t io_config = {
|
||||||
|
.dc_gpio_num = EXAMPLE_LCD_GPIO_DC,
|
||||||
|
.cs_gpio_num = EXAMPLE_LCD_GPIO_CS,
|
||||||
|
.pclk_hz = EXAMPLE_LCD_PIXEL_CLK_HZ,
|
||||||
|
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
|
||||||
|
.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
|
||||||
|
.spi_mode = 0,
|
||||||
|
.trans_queue_depth = 10,
|
||||||
|
};
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)EXAMPLE_LCD_SPI_NUM, &io_config, &lcd_io), err, TAG, "创建面板IO失败");
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "安装LCD驱动");
|
||||||
|
const esp_lcd_panel_dev_config_t panel_config = {
|
||||||
|
.reset_gpio_num = EXAMPLE_LCD_GPIO_RST,
|
||||||
|
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0)
|
||||||
|
.rgb_endian = EXAMPLE_LCD_COLOR_ORDER_BGR ? LCD_RGB_ENDIAN_BGR : LCD_RGB_ENDIAN_RGB,
|
||||||
|
#else
|
||||||
|
.rgb_ele_order = EXAMPLE_LCD_COLOR_ORDER_BGR ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB,
|
||||||
|
#endif
|
||||||
|
.bits_per_pixel = EXAMPLE_LCD_BITS_PER_PIXEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(lcd_io, &panel_config, &lcd_panel), err, TAG, "创建面板失败");
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_panel_reset(lcd_panel), err, TAG, "面板复位失败");
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_panel_init(lcd_panel), err, TAG, "面板初始化失败");
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_panel_swap_xy(lcd_panel, false), err, TAG, "设置面板swap_xy失败");
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_panel_mirror(lcd_panel, false, false), err, TAG, "设置面板镜像失败");
|
||||||
|
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_panel_set_gap(lcd_panel, EXAMPLE_LCD_GAP_X, EXAMPLE_LCD_GAP_Y), err, TAG, "设置显示偏移失败");
|
||||||
|
ESP_LOGI(TAG, "面板基准参数已应用: gap=(%d,%d)", EXAMPLE_LCD_GAP_X, EXAMPLE_LCD_GAP_Y);
|
||||||
|
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_panel_invert_color(lcd_panel, EXAMPLE_LCD_INVERT_COLOR), err, TAG, "设置反色失败");
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_panel_disp_on_off(lcd_panel, true), err, TAG, "打开显示失败");
|
||||||
|
|
||||||
|
if (EXAMPLE_LCD_GPIO_BL != GPIO_NUM_NC) {
|
||||||
|
ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_LCD_GPIO_BL, EXAMPLE_LCD_BL_ON_LEVEL), TAG, "背光引脚置位失败");
|
||||||
|
ESP_LOGI(TAG, "背光已打开,电平=%d", EXAMPLE_LCD_BL_ON_LEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "颜色参数: order=%s invert=%d swap_bytes=%d",
|
||||||
|
EXAMPLE_LCD_COLOR_ORDER_BGR ? "BGR" : "RGB",
|
||||||
|
EXAMPLE_LCD_INVERT_COLOR,
|
||||||
|
EXAMPLE_LCD_SWAP_BYTES);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
// 错误处理标签,用于清理资源
|
||||||
|
err:
|
||||||
|
if (lcd_panel) {
|
||||||
|
esp_lcd_panel_del(lcd_panel);
|
||||||
|
lcd_panel = NULL;
|
||||||
|
}
|
||||||
|
if (lcd_io) {
|
||||||
|
esp_lcd_panel_io_del(lcd_io);
|
||||||
|
lcd_io = NULL;
|
||||||
|
}
|
||||||
|
spi_bus_free(EXAMPLE_LCD_SPI_NUM);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化LVGL图形库
|
||||||
|
*
|
||||||
|
* 该函数负责初始化LVGL库,并配置显示设备
|
||||||
|
* 包括LVGL任务配置、显示缓冲区配置和旋转设置
|
||||||
|
*
|
||||||
|
* @return esp_err_t 初始化结果,ESP_OK表示成功
|
||||||
|
*/
|
||||||
|
static esp_err_t app_lvgl_init(void)
|
||||||
|
{
|
||||||
|
const lvgl_port_cfg_t lvgl_cfg = {
|
||||||
|
.task_priority = 4,
|
||||||
|
.task_stack = 8192,
|
||||||
|
.task_affinity = -1,
|
||||||
|
.task_max_sleep_ms = 500,
|
||||||
|
.timer_period_ms = 5
|
||||||
|
};
|
||||||
|
ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL端口初始化失败");
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "添加LCD屏幕");
|
||||||
|
const lvgl_port_display_cfg_t disp_cfg = {
|
||||||
|
.io_handle = lcd_io,
|
||||||
|
.panel_handle = lcd_panel,
|
||||||
|
.buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT,
|
||||||
|
.double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE,
|
||||||
|
.hres = EXAMPLE_LCD_H_RES,
|
||||||
|
.vres = EXAMPLE_LCD_V_RES,
|
||||||
|
.monochrome = false,
|
||||||
|
#if LVGL_VERSION_MAJOR >= 9
|
||||||
|
.color_format = LV_COLOR_FORMAT_RGB565,
|
||||||
|
#endif
|
||||||
|
.rotation = {
|
||||||
|
.swap_xy = EXAMPLE_LCD_ROT_SWAP_XY,
|
||||||
|
.mirror_x = EXAMPLE_LCD_ROT_MIRROR_X,
|
||||||
|
.mirror_y = EXAMPLE_LCD_ROT_MIRROR_Y,
|
||||||
|
},
|
||||||
|
.flags = {
|
||||||
|
.buff_dma = true,
|
||||||
|
#if LVGL_VERSION_MAJOR >= 9
|
||||||
|
.swap_bytes = EXAMPLE_LCD_SWAP_BYTES,
|
||||||
|
#endif
|
||||||
|
}};
|
||||||
|
|
||||||
|
lvgl_disp = lvgl_port_add_disp(&disp_cfg);
|
||||||
|
ESP_RETURN_ON_FALSE(lvgl_disp != NULL, ESP_FAIL, TAG, "添加LVGL显示设备失败");
|
||||||
|
ESP_LOGI(TAG, "LVGL旋转已应用: swap_xy=%d mirror_x=%d mirror_y=%d",
|
||||||
|
EXAMPLE_LCD_ROT_SWAP_XY, EXAMPLE_LCD_ROT_MIRROR_X, EXAMPLE_LCD_ROT_MIRROR_Y);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建并显示LVGL主界面
|
||||||
|
*
|
||||||
|
* 该函数负责创建LVGL的用户界面元素,包括图像、标签和按钮
|
||||||
|
* 并设置它们的位置和属性
|
||||||
|
*/
|
||||||
|
static void app_main_display(void)
|
||||||
|
{
|
||||||
|
lv_obj_t *scr = lv_scr_act();
|
||||||
|
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
|
||||||
|
lv_obj_set_style_bg_color(scr, lv_color_white(), 0);
|
||||||
|
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||||
|
|
||||||
|
s_center_label = lv_label_create(scr);
|
||||||
|
lv_label_set_text(s_center_label, "BotanicalBuddy\nloading...");
|
||||||
|
lv_label_set_recolor(s_center_label, false);
|
||||||
|
lv_label_set_long_mode(s_center_label, LV_LABEL_LONG_WRAP);
|
||||||
|
lv_obj_set_size(s_center_label, EXAMPLE_LCD_H_RES - 6, EXAMPLE_LCD_V_RES - 6);
|
||||||
|
lv_obj_set_style_text_color(s_center_label, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_text_font(s_center_label, &lv_font_montserrat_14, 0);
|
||||||
|
lv_obj_set_style_text_align(s_center_label, LV_TEXT_ALIGN_CENTER, 0);
|
||||||
|
lv_obj_set_style_pad_all(s_center_label, 0, 0);
|
||||||
|
lv_obj_align(s_center_label, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启动LVGL演示程序
|
||||||
|
*
|
||||||
|
* 该函数是程序的入口点,负责初始化LCD硬件、LVGL库,并显示主界面
|
||||||
|
*/
|
||||||
|
esp_err_t lvgl_st7789_set_center_text(const char *text)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(text != NULL, ESP_ERR_INVALID_ARG, TAG, "text is null");
|
||||||
|
ESP_RETURN_ON_FALSE(s_center_label != NULL, ESP_ERR_INVALID_STATE, TAG, "label not ready");
|
||||||
|
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
lv_label_set_text(s_center_label, text);
|
||||||
|
lv_obj_align(s_center_label, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t start_lvgl_demo(void)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_ERROR(app_lcd_init(), TAG, "LCD初始化失败");
|
||||||
|
|
||||||
|
#if EXAMPLE_LCD_ENABLE_COLOR_TEST
|
||||||
|
ESP_RETURN_ON_ERROR(app_lcd_color_test(), TAG, "LCD测试图绘制失败");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(300));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ESP_RETURN_ON_ERROR(app_lvgl_init(), TAG, "LVGL初始化失败");
|
||||||
|
|
||||||
|
// app_main_display();
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
22
components/ui/.eez-project-build
Normal file
22
components/ui/.eez-project-build
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"actions.h",
|
||||||
|
"eez-flow.cpp",
|
||||||
|
"eez-flow.h",
|
||||||
|
"fonts.h",
|
||||||
|
"images.c",
|
||||||
|
"images.h",
|
||||||
|
"screens.c",
|
||||||
|
"screens.h",
|
||||||
|
"structs.h",
|
||||||
|
"styles.c",
|
||||||
|
"styles.h",
|
||||||
|
"ui.c",
|
||||||
|
"ui.h",
|
||||||
|
"ui_font_chinese32.c",
|
||||||
|
"ui_font_chinese64.c",
|
||||||
|
"ui_font_num.c",
|
||||||
|
"ui_font_num2.c",
|
||||||
|
"vars.h"
|
||||||
|
]
|
||||||
|
}
|
||||||
6
components/ui/CMakeLists.txt
Normal file
6
components/ui/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
idf_component_register(
|
||||||
|
SRC_DIRS "."
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES lvgl esp_lvgl_port
|
||||||
|
)
|
||||||
14
components/ui/actions.h
Normal file
14
components/ui/actions.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef EEZ_LVGL_UI_EVENTS_H
|
||||||
|
#define EEZ_LVGL_UI_EVENTS_H
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*EEZ_LVGL_UI_EVENTS_H*/
|
||||||
9901
components/ui/eez-flow.cpp
Normal file
9901
components/ui/eez-flow.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4388
components/ui/eez-flow.h
Normal file
4388
components/ui/eez-flow.h
Normal file
File diff suppressed because it is too large
Load Diff
29
components/ui/fonts.h
Normal file
29
components/ui/fonts.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef EEZ_LVGL_UI_FONTS_H
|
||||||
|
#define EEZ_LVGL_UI_FONTS_H
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const lv_font_t ui_font_num;
|
||||||
|
extern const lv_font_t ui_font_num2;
|
||||||
|
extern const lv_font_t ui_font_chinese64;
|
||||||
|
extern const lv_font_t ui_font_chinese32;
|
||||||
|
|
||||||
|
#ifndef EXT_FONT_DESC_T
|
||||||
|
#define EXT_FONT_DESC_T
|
||||||
|
typedef struct _ext_font_desc_t {
|
||||||
|
const char *name;
|
||||||
|
const void *font_ptr;
|
||||||
|
} ext_font_desc_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern ext_font_desc_t fonts[];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*EEZ_LVGL_UI_FONTS_H*/
|
||||||
5
components/ui/images.c
Normal file
5
components/ui/images.c
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include "images.h"
|
||||||
|
|
||||||
|
const ext_img_desc_t images[1] = {
|
||||||
|
0
|
||||||
|
};
|
||||||
24
components/ui/images.h
Normal file
24
components/ui/images.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef EEZ_LVGL_UI_IMAGES_H
|
||||||
|
#define EEZ_LVGL_UI_IMAGES_H
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EXT_IMG_DESC_T
|
||||||
|
#define EXT_IMG_DESC_T
|
||||||
|
typedef struct _ext_img_desc_t {
|
||||||
|
const char *name;
|
||||||
|
const lv_img_dsc_t *img_dsc;
|
||||||
|
} ext_img_desc_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const ext_img_desc_t images[1];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*EEZ_LVGL_UI_IMAGES_H*/
|
||||||
189
components/ui/screens.c
Normal file
189
components/ui/screens.c
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "screens.h"
|
||||||
|
#include "images.h"
|
||||||
|
#include "fonts.h"
|
||||||
|
#include "actions.h"
|
||||||
|
#include "vars.h"
|
||||||
|
#include "styles.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
objects_t objects;
|
||||||
|
|
||||||
|
static const char *screen_names[] = { "Main" };
|
||||||
|
static const char *object_names[] = { "main", "obj0", "obj1", "obj2" };
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event handlers
|
||||||
|
//
|
||||||
|
|
||||||
|
lv_obj_t *tick_value_change_obj;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Screens
|
||||||
|
//
|
||||||
|
|
||||||
|
void create_screen_main() {
|
||||||
|
void *flowState = getFlowState(0, 0);
|
||||||
|
(void)flowState;
|
||||||
|
lv_obj_t *obj = lv_obj_create(0);
|
||||||
|
objects.main = obj;
|
||||||
|
lv_obj_set_pos(obj, 0, 0);
|
||||||
|
lv_obj_set_size(obj, 240, 240);
|
||||||
|
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
{
|
||||||
|
lv_obj_t *parent_obj = obj;
|
||||||
|
{
|
||||||
|
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||||
|
objects.obj0 = obj;
|
||||||
|
lv_obj_set_pos(obj, 217, 123);
|
||||||
|
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_text_font(obj, &ui_font_num, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_style_text_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
lv_label_set_text(obj, "g");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||||
|
objects.obj1 = obj;
|
||||||
|
lv_obj_set_pos(obj, 5, 94);
|
||||||
|
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_text_font(obj, &ui_font_num2, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_style_text_color(obj, lv_color_hex(0xffffe503), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_RIGHT, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
lv_label_set_text(obj, "");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||||
|
objects.obj2 = obj;
|
||||||
|
lv_obj_set_pos(obj, 40, 7);
|
||||||
|
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_text_font(obj, &ui_font_chinese32, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_style_text_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
lv_label_set_text(obj, "智能电子称");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tick_screen_main();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tick_screen_main() {
|
||||||
|
void *flowState = getFlowState(0, 0);
|
||||||
|
(void)flowState;
|
||||||
|
{
|
||||||
|
const char *new_val = evalTextProperty(flowState, 2, 3, "Failed to evaluate Text in Label widget");
|
||||||
|
const char *cur_val = lv_label_get_text(objects.obj1);
|
||||||
|
if (strcmp(new_val, cur_val) != 0) {
|
||||||
|
tick_value_change_obj = objects.obj1;
|
||||||
|
lv_label_set_text(objects.obj1, new_val);
|
||||||
|
tick_value_change_obj = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*tick_screen_func_t)();
|
||||||
|
tick_screen_func_t tick_screen_funcs[] = {
|
||||||
|
tick_screen_main,
|
||||||
|
};
|
||||||
|
void tick_screen(int screen_index) {
|
||||||
|
tick_screen_funcs[screen_index]();
|
||||||
|
}
|
||||||
|
void tick_screen_by_id(enum ScreensEnum screenId) {
|
||||||
|
tick_screen_funcs[screenId - 1]();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fonts
|
||||||
|
//
|
||||||
|
|
||||||
|
ext_font_desc_t fonts[] = {
|
||||||
|
{ "Num", &ui_font_num },
|
||||||
|
{ "Num2", &ui_font_num2 },
|
||||||
|
{ "chinese64", &ui_font_chinese64 },
|
||||||
|
{ "chinese32", &ui_font_chinese32 },
|
||||||
|
#if LV_FONT_MONTSERRAT_8
|
||||||
|
{ "MONTSERRAT_8", &lv_font_montserrat_8 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_10
|
||||||
|
{ "MONTSERRAT_10", &lv_font_montserrat_10 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_12
|
||||||
|
{ "MONTSERRAT_12", &lv_font_montserrat_12 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_14
|
||||||
|
{ "MONTSERRAT_14", &lv_font_montserrat_14 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_16
|
||||||
|
{ "MONTSERRAT_16", &lv_font_montserrat_16 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_18
|
||||||
|
{ "MONTSERRAT_18", &lv_font_montserrat_18 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_20
|
||||||
|
{ "MONTSERRAT_20", &lv_font_montserrat_20 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_22
|
||||||
|
{ "MONTSERRAT_22", &lv_font_montserrat_22 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_24
|
||||||
|
{ "MONTSERRAT_24", &lv_font_montserrat_24 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_26
|
||||||
|
{ "MONTSERRAT_26", &lv_font_montserrat_26 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_28
|
||||||
|
{ "MONTSERRAT_28", &lv_font_montserrat_28 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_30
|
||||||
|
{ "MONTSERRAT_30", &lv_font_montserrat_30 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_32
|
||||||
|
{ "MONTSERRAT_32", &lv_font_montserrat_32 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_34
|
||||||
|
{ "MONTSERRAT_34", &lv_font_montserrat_34 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_36
|
||||||
|
{ "MONTSERRAT_36", &lv_font_montserrat_36 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_38
|
||||||
|
{ "MONTSERRAT_38", &lv_font_montserrat_38 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_40
|
||||||
|
{ "MONTSERRAT_40", &lv_font_montserrat_40 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_42
|
||||||
|
{ "MONTSERRAT_42", &lv_font_montserrat_42 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_44
|
||||||
|
{ "MONTSERRAT_44", &lv_font_montserrat_44 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_46
|
||||||
|
{ "MONTSERRAT_46", &lv_font_montserrat_46 },
|
||||||
|
#endif
|
||||||
|
#if LV_FONT_MONTSERRAT_48
|
||||||
|
{ "MONTSERRAT_48", &lv_font_montserrat_48 },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
void create_screens() {
|
||||||
|
|
||||||
|
eez_flow_init_fonts(fonts, sizeof(fonts) / sizeof(ext_font_desc_t));
|
||||||
|
|
||||||
|
// Set default LVGL theme
|
||||||
|
lv_display_t *dispp = lv_display_get_default();
|
||||||
|
lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT);
|
||||||
|
lv_display_set_theme(dispp, theme);
|
||||||
|
|
||||||
|
// Initialize screens
|
||||||
|
eez_flow_init_screen_names(screen_names, sizeof(screen_names) / sizeof(const char *));
|
||||||
|
eez_flow_init_object_names(object_names, sizeof(object_names) / sizeof(const char *));
|
||||||
|
|
||||||
|
// Create screens
|
||||||
|
create_screen_main();
|
||||||
|
}
|
||||||
39
components/ui/screens.h
Normal file
39
components/ui/screens.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef EEZ_LVGL_UI_SCREENS_H
|
||||||
|
#define EEZ_LVGL_UI_SCREENS_H
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Screens
|
||||||
|
|
||||||
|
enum ScreensEnum {
|
||||||
|
_SCREEN_ID_FIRST = 1,
|
||||||
|
SCREEN_ID_MAIN = 1,
|
||||||
|
_SCREEN_ID_LAST = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _objects_t {
|
||||||
|
lv_obj_t *main;
|
||||||
|
lv_obj_t *obj0;
|
||||||
|
lv_obj_t *obj1;
|
||||||
|
lv_obj_t *obj2;
|
||||||
|
} objects_t;
|
||||||
|
|
||||||
|
extern objects_t objects;
|
||||||
|
|
||||||
|
void create_screen_main();
|
||||||
|
void tick_screen_main();
|
||||||
|
|
||||||
|
void tick_screen_by_id(enum ScreensEnum screenId);
|
||||||
|
void tick_screen(int screen_index);
|
||||||
|
|
||||||
|
void create_screens();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*EEZ_LVGL_UI_SCREENS_H*/
|
||||||
13
components/ui/structs.h
Normal file
13
components/ui/structs.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef EEZ_LVGL_UI_STRUCTS_H
|
||||||
|
#define EEZ_LVGL_UI_STRUCTS_H
|
||||||
|
|
||||||
|
#include "eez-flow.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "vars.h"
|
||||||
|
|
||||||
|
using namespace eez;
|
||||||
|
|
||||||
|
#endif /*EEZ_LVGL_UI_STRUCTS_H*/
|
||||||
6
components/ui/styles.c
Normal file
6
components/ui/styles.c
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "styles.h"
|
||||||
|
#include "images.h"
|
||||||
|
#include "fonts.h"
|
||||||
|
|
||||||
|
#include "ui.h"
|
||||||
|
#include "screens.h"
|
||||||
14
components/ui/styles.h
Normal file
14
components/ui/styles.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef EEZ_LVGL_UI_STYLES_H
|
||||||
|
#define EEZ_LVGL_UI_STYLES_H
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*EEZ_LVGL_UI_STYLES_H*/
|
||||||
56
components/ui/ui.c
Normal file
56
components/ui/ui.c
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include "ui.h"
|
||||||
|
#include "screens.h"
|
||||||
|
#include "images.h"
|
||||||
|
#include "actions.h"
|
||||||
|
#include "vars.h"
|
||||||
|
|
||||||
|
// ASSETS DEFINITION
|
||||||
|
const uint8_t assets[460] = {
|
||||||
|
0x7E, 0x45, 0x45, 0x5A, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||||
|
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xF0, 0x00, 0xF0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x2C, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x30, 0x75, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x31, 0x75, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x30, 0x75, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x30, 0x75, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||||
|
0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||||
|
0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||||
|
0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00,
|
||||||
|
0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00,
|
||||||
|
0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00,
|
||||||
|
0x00, 0xE0, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
native_var_t native_vars[] = {
|
||||||
|
{ NATIVE_VAR_TYPE_NONE, 0, 0 },
|
||||||
|
{ NATIVE_VAR_TYPE_FLOAT, get_var_weigt_ui, set_var_weigt_ui },
|
||||||
|
};
|
||||||
|
|
||||||
|
ActionExecFunc actions[] = {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
void ui_init() {
|
||||||
|
eez_flow_init(assets, sizeof(assets), (lv_obj_t **)&objects, sizeof(objects), images, sizeof(images), actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_tick() {
|
||||||
|
eez_flow_tick();
|
||||||
|
tick_screen(g_currentScreen);
|
||||||
|
}
|
||||||
21
components/ui/ui.h
Normal file
21
components/ui/ui.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef EEZ_LVGL_UI_GUI_H
|
||||||
|
#define EEZ_LVGL_UI_GUI_H
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
#include "eez-flow.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const uint8_t assets[460];
|
||||||
|
|
||||||
|
void ui_init();
|
||||||
|
void ui_tick();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // EEZ_LVGL_UI_GUI_H
|
||||||
5393
components/ui/ui_font_chinese32.c
Normal file
5393
components/ui/ui_font_chinese32.c
Normal file
File diff suppressed because it is too large
Load Diff
18752
components/ui/ui_font_chinese64.c
Normal file
18752
components/ui/ui_font_chinese64.c
Normal file
File diff suppressed because it is too large
Load Diff
3293
components/ui/ui_font_num.c
Normal file
3293
components/ui/ui_font_num.c
Normal file
File diff suppressed because it is too large
Load Diff
11151
components/ui/ui_font_num2.c
Normal file
11151
components/ui/ui_font_num2.c
Normal file
File diff suppressed because it is too large
Load Diff
13
components/ui/vars.c
Normal file
13
components/ui/vars.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "vars.h"
|
||||||
|
|
||||||
|
float weigt_ui;
|
||||||
|
|
||||||
|
float get_var_weigt_ui() {
|
||||||
|
return weigt_ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_var_weigt_ui(float value) {
|
||||||
|
weigt_ui = value;
|
||||||
|
}
|
||||||
28
components/ui/vars.h
Normal file
28
components/ui/vars.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef EEZ_LVGL_UI_VARS_H
|
||||||
|
#define EEZ_LVGL_UI_VARS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// enum declarations
|
||||||
|
|
||||||
|
// Flow global variables
|
||||||
|
|
||||||
|
enum FlowGlobalVariables {
|
||||||
|
FLOW_GLOBAL_VARIABLE_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Native global variables
|
||||||
|
|
||||||
|
extern float get_var_weigt_ui();
|
||||||
|
extern void set_var_weigt_ui(float value);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*EEZ_LVGL_UI_VARS_H*/
|
||||||
32
dependencies.lock
Normal file
32
dependencies.lock
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
dependencies:
|
||||||
|
espressif/esp_lvgl_port:
|
||||||
|
component_hash: b6360960f47b6776462e7092861b3ea66477ffb762a01baa0aecbb3d74cd50f4
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.1'
|
||||||
|
- name: lvgl/lvgl
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: public
|
||||||
|
version: '>=8,<10'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 2.7.2
|
||||||
|
idf:
|
||||||
|
source:
|
||||||
|
type: idf
|
||||||
|
version: 5.5.2
|
||||||
|
lvgl/lvgl:
|
||||||
|
component_hash: 184e532558c1c45fefed631f3e235423d22582aafb4630f3e8885c35281a49ae
|
||||||
|
dependencies: []
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 9.5.0
|
||||||
|
direct_dependencies:
|
||||||
|
- espressif/esp_lvgl_port
|
||||||
|
- idf
|
||||||
|
manifest_hash: fa314ee0d60a34ffe2dea85313c7369c0c4b16079167ed05ad45e0cadad2199d
|
||||||
|
target: esp32s3
|
||||||
|
version: 2.0.0
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
idf_component_register(SRCS "main.c"
|
idf_component_register(SRCS "main.cpp"
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES nvs_flash esp_wifi esp_event esp_system wifi-connect)
|
REQUIRES nvs_flash esp_wifi esp_event esp_system wifi-connect ui lvgl_st7789_use)
|
||||||
|
|||||||
17
main/idf_component.yml
Normal file
17
main/idf_component.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
## IDF Component Manager Manifest File
|
||||||
|
dependencies:
|
||||||
|
## Required IDF version
|
||||||
|
idf:
|
||||||
|
version: '>=4.1.0'
|
||||||
|
# # Put list of dependencies here
|
||||||
|
# # For components maintained by Espressif:
|
||||||
|
# component: "~1.0.0"
|
||||||
|
# # For 3rd party components:
|
||||||
|
# username/component: ">=1.0.0,<2.0.0"
|
||||||
|
# username2/component2:
|
||||||
|
# version: "~1.0.0"
|
||||||
|
# # For transient dependencies `public` flag can be set.
|
||||||
|
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||||
|
# # All dependencies of `main` are public by default.
|
||||||
|
# public: true
|
||||||
|
espressif/esp_lvgl_port: ^2.7.2
|
||||||
25
main/main.c
25
main/main.c
@@ -1,25 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
|
|
||||||
#include "wifi-connect.h"
|
|
||||||
|
|
||||||
// 等待 Wi-Fi 连接成功,超时后返回当前连接状态
|
|
||||||
static bool wait_for_wifi_connected(TickType_t timeout_ticks)
|
|
||||||
{
|
|
||||||
const TickType_t start_ticks = xTaskGetTickCount();
|
|
||||||
while ((xTaskGetTickCount() - start_ticks) < timeout_ticks)
|
|
||||||
{
|
|
||||||
if (wifi_connect_get_status() == WIFI_CONNECT_STATUS_CONNECTED)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(200));
|
|
||||||
}
|
|
||||||
return wifi_connect_get_status() == WIFI_CONNECT_STATUS_CONNECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void app_main(void)
|
|
||||||
{
|
|
||||||
ESP_ERROR_CHECK(wifi_connect_init()); // 初始化 Wi-Fi 配网模块
|
|
||||||
}
|
|
||||||
41
main/main.cpp
Normal file
41
main/main.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "wifi-connect.h"
|
||||||
|
#include "esp_lvgl_port.h" // 包含 LVGL 端口头文件,提供 LVGL 相关的类型定义和函数声明
|
||||||
|
#include "lvgl_st7789_use.h" // 使用EEZStudio提供的LVGL和ST7789驱动,便于后续扩展
|
||||||
|
#include "ui.h" // 使用EEZStudio提供的ui组件,便于后续扩展
|
||||||
|
#include "vars.h" // 包含全局变量定义和访问函数
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UI 任务函数
|
||||||
|
*
|
||||||
|
* 负责定期驱动 UI 刷新,并实现屏幕自动轮播。
|
||||||
|
*
|
||||||
|
* @param arg 任务参数(未使用)
|
||||||
|
*/
|
||||||
|
static void ui_task(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
ui_tick();
|
||||||
|
lvgl_port_unlock();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void app_main(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(wifi_connect_init()); // 初始化 Wi-Fi 配网模块
|
||||||
|
|
||||||
|
start_lvgl_demo(); // 初始化 LVGL 和 LCD 显示
|
||||||
|
// 初始化 UI 组件(需在 LVGL 锁内进行对象创建)
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
ui_init();
|
||||||
|
lvgl_port_unlock();
|
||||||
|
// 创建一个 FreeRTOS 任务来更新 UI 显示(字符串拼接需要更多栈空间)
|
||||||
|
xTaskCreate(ui_task, "ui_task", 4096, NULL, 10, NULL);
|
||||||
|
}
|
||||||
5
partitions.csv
Normal file
5
partitions.csv
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# ESP-IDF Custom Partition Table
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 4M,
|
||||||
|
9
update_sdkconfig.sh
Executable file
9
update_sdkconfig.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
sed -i 's/CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y/# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set/g' sdkconfig
|
||||||
|
sed -i 's/CONFIG_ESPTOOLPY_FLASHSIZE="2MB"/CONFIG_ESPTOOLPY_FLASHSIZE="16MB"/g' sdkconfig
|
||||||
|
echo "CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y" >> sdkconfig
|
||||||
|
echo "CONFIG_SPIRAM=y" >> sdkconfig
|
||||||
|
echo "CONFIG_SPIRAM_MODE_OCT=y" >> sdkconfig
|
||||||
|
echo "CONFIG_SPIRAM_SPEED_80M=y" >> sdkconfig
|
||||||
|
echo "CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y" >> sdkconfig
|
||||||
|
echo "CONFIG_SPIRAM_RODATA=y" >> sdkconfig
|
||||||
Reference in New Issue
Block a user