当前位置: 首页 > news >正文

[笔记] 基于esp32s3用GUI-Guider-1.9.1-GA开发LVGL界面

基于esp32s3用GUI-Guider-1.9.1-GA开发LVGL界面用于485通讯

1. 准备措施

1.1.硬件准备

仓库内含视频地址, 配套的视频很简单, 不过够用了.仓库地址: 禾木科技/esp32-s3-4inch-001-sdk

  • 使用的硬件是某宝买的一个方案板: [esp32s3蓝牙wifi板4寸RGB屏UI开发LVGL方案电容触摸st7701s驱动]
    在这里插入图片描述

  • 他们提供了驱动库, 有完整配套例程, 和视频讲解,很是方便, 不用关心屏幕的驱动和LVGL库的移植, 所以本文主要讲解使用.

  • 缺点就是把驱动库的.c文件都打包加密了.不能观看学习,也不开源原理图,导致只能自己反推接线.

1.2.环境准备

关于ESP32S3的环境部署, 参考笔记: 【ESP】一小时速通入门笔记

  • 使用ESP32S3作为主控, 关于环境配置可以看我之前的笔记.

1.3.工具准备

官网下载 GUI-Guider-1.9.1-GA
移植参考: GUI-Guider安装使用及项目移植(7.11版本)

  • 仓库配套例程推荐的是 SquareLine_Studio, 它收费, 试用只有1个月, 但因为我的公司电脑, 电脑时间和网络时间不一致, 导致我安装后直接用不了,试了半天没成功, 也没找到破解版, 就放弃了
  • 我搜了一下, 发现NXP有推出一款免费的 GUI-Guider, 注册就可以用.
  • 注意 GUI-Guider 迭代了几个版本, 我看了一下:
    • 1.5.1只支持v7LVGL;
    • 1.6.1支持v7v8LVGL;
    • 1.9.1支持v8v9LVGL;
  • 而且它不同版本直接是不能相互打开工程的!!!示意开始创建工程之前一定要确定使用哪个版本的软件, 避免后面要改, 更改就得重做了.
  • 而且不同版本之间操作方式也有较大的差异性.

2.开始测试

2.1.测试LVGL

例程目录: esp32-s3-4inch-001-sdk\examples\1.lvgl_v8
例程视频: esp32通用RGB驱动板开源lvgl V8.3.11程序下载及86盒方案演示

  • 只需要将仓库的componentsexamples/1.lvgl_v8拷贝到自己的新建文件夹即可,1.lvgl_v8可以修改名字app_main,只要和组件的相对路径不变即可; 类似下图, 我加了.git管理和LVGL工程文件,也放一起.

在这里插入图片描述

  • 然后打开esp-idf终端,
    • cd切换目录,
    • idf.py set-target {esp32s3}切换芯片类型,
    • idf.py build编译文件.
    • idf.py menuconfig修改配置(默认不用,只是我想列从来 ),
    • idf.py {-p COM8} flash下载,
    • idf.py {-p COM8} monitor监听. 最后成功运行, 和视频介绍的一样.
  • 使用vscode打开工程, 为了方便代码之间跳转查看, 添加.vscode/c_cpp_properties.json文件, 在"configurations"内添加"compileCommands": "${workspaceFolder}/build/compile_commands.json".
  • 再编译一下, 没有问题. 速通成功, 下一步.

2.2. 替换GUI-Guider文件

参考笔记: LVGL使用GUI Guider配置STM32界面详细笔记教程

  • 例程自带的是SquareLine Studio的代码文件, 和GUI-Guider不通用, 需要修改.
  • 先打开软件GUI-Guider-1.9.1-GA,创建v8工程:
  • 板子选择默认Simulator,模板选择一个例程SmartBuiding,屏幕选择Custom,尺寸填写480*480;后续会围绕这个模板将LVGL的功能.

在这里插入图片描述

在这里插入图片描述

  • 界面大体如下: 不同版本差别较大, 认准目前讲解的1.9.1版本

在这里插入图片描述

  • 直接编译运行, 初次比较久, 过了一会就能看到弹窗, 可以试一下功能;

在这里插入图片描述

  • 然后开始导出代码,选择放在esp32工程里的新建文件夹.

在这里插入图片描述

然后会导出2个文件夹,customgenerated, 然后将2个文件夹的路径添加到esp32编译文件配置CMakeLists.txt中:

在这里插入图片描述

idf_component_register(    SRC_DIRS".""gui_app/custom""gui_app/generated"INCLUDE_DIRS ".""gui_app/custom""gui_app/generated")
  • 然后在main.c文件中直接添加代码即可:
...省略...
#include "gui_app/generated/gui_guider.h"
#include "gui_app/generated/events_init.h"
lv_ui guider_ui;
...省略...void app_main(void)
{...省略...lv_port_sem_take();setup_ui(&guider_ui);events_init(&guider_ui);lv_port_sem_give();  
}
  • 然后编译运行(报错), 就能看到板子上呈现一样的界面.唯一问题就是比较卡顿, 可能是因为算力不够,运行太慢.

2.3. 移植GUI-Guider时钟组件dclock

参考笔记: Gui-Guider1.8.1 数字时钟控件找不到定义,无法编译

  • 上面的正常操作最后是会编译报错, 因为使用的这个gui工程使用了私有组件, 需要手动移植;

  • 打开软件所在文件夹, 然后找到以下文件夹: E:\NXP\GUI-Guider-1.9.1-GA\environment\template\project\v8\lvgl\src\extra\widgets

在这里插入图片描述

  • 将文件夹复制到工程里, 记得添加esp32文件编译路径

在这里插入图片描述

idf_component_register(    SRC_DIRS".""gui_app/custom""gui_app/dclock""gui_app/generated"INCLUDE_DIRS ".""gui_app/custom""gui_app/dclock""gui_app/generated")
  • 然后找到这个esp32s3组件里的头文件lvgl.h, 添加一行头文件路径.

在这里插入图片描述

/*-----------------* EXTRAS*----------------*/
#include "src/extra/lv_extra.h"#include "../../../examples/app_main_s100/main/gui_app/dclock/lv_dclock.h"
/**********************      DEFINES*********************/
  • 然后回到lv_dclock.clv_dclock.h,进行如下修改.
// lv_dclock.c:/**********************      INCLUDES*********************/
#include "lv_dclock.h"
#if LV_USE_DCLOCK != 0
//注释掉原有的头文件
//#include "../../../core/lv_obj.h"
//#include "../../../misc/lv_assert.h"
//#include "../../../core/lv_group.h"
//#include "../../../draw/lv_draw.h"
//#include "../../../misc/lv_color.h"
//#include "../../../misc/lv_math.h"
//#include "../../../misc/lv_bidi.h"
//#include "../../../misc/lv_txt_ap.h"
//#include "../../../misc/lv_printf.h"
//#include "../../../widgets/lv_label.h"
  • 宏定义LV_USE_DCLOCKLV_DCLOCK_TEXT_SELECTION的添加是因为又耦合了另一文件, 避免多余的移植, 就直接将用到的宏定义写在这里.
// lv_dclock.h: #ifndef LV_DCLOCK_H
#define LV_DCLOCK_H#ifdef __cplusplus
extern "C" {
#endif/**********************      INCLUDES*********************/
//#include "../../../lv_conf_internal.h"  //注释掉原有的lv_conf_internal.h文件//观察lv_conf_internal.h文件,选择需要的参数置位1
#define LV_USE_DCLOCK             1   
#define LV_DCLOCK_TEXT_SELECTION  1#if LV_USE_DCLOCK != 0#include <stdarg.h>
#include <stdlib.h>
#include "lvgl.h"   //我们自己的lvgl.h头文件,代替其原有调用的一些lvgl有文件
//#include "../../../core/lv_obj.h"
//#include "../../../font/lv_font.h"
//#include "../../../font/lv_symbol_def.h"
//#include "../../../misc/lv_txt.h"
//#include "../../../draw/lv_draw.h"
  • 写在再编译应该就万无一失了, 可以正常运行下载了.

2.4. 测试RS485

官方指南: 通用异步接收器/发送器 (UART)
参考笔记: ESP32 单片机学习笔记 - 01 - gpio&ledc&uart
esp32自带例程地址: \Espressif\frameworks\esp-idf-v5.3.1\examples\peripherals\uart\uart_echo_rs485
参考笔记: 6.RS485模块发布esp32方案86盒温控器加入RS485通信控制
方案板自带例程地址:\esp32-s3-4inch-001-sdk\examples\6.RS485

  • 先用方案板例程跑一下, 正常运行, 使用万用表蜂鸣档和查看手册描述知道, 板载自带的RS485接口的具体IO是IO4/5/6.
  • 然后可以直接使用esp32自带的例程, 使用idf.py menuconfig修改默认配置,引脚和波特率.然后编译下载进去,得到和方案板例程一样的效果.
// 注意: 目标芯片上的某些引脚无法分配用于UART通信.
// 请参阅所选板和目标的文档, 以使用Kconfig配置引脚.
#define ECHO_TEST_TXD           (CONFIG_ECHO_UART_TXD)  // 目前板载的是IO6
#define ECHO_TEST_RXD           (CONFIG_ECHO_UART_RXD)  // 目前板载的是IO4// RS485半双工模式的 RTS 管理 DE / ~RE
#define ECHO_TEST_RTS           (CONFIG_ECHO_UART_RTS)  // 目前板载的是IO5
  • 就可以把esp32例程里的代码移植到方案板例程上了, 因为方案板库自带的rs485组件功能很少, 不好打包使用, 所以重新实现, 屏幕驱动就用自带的组件 .
  • 注意,将/main/Kconfig.projbuild文件的内容也移植, 它是规定idf.py menuconfig配置的,可以方便修改配置, 具体的语法自行举一反三吧, 我不列举了.

menu "Echo RS485 Example Configuration"orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"config ECHO_UART_PORT_NUMint "UART port number"range 0 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3default 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3range 0 1default 0helpUART communication port number for the example.See UART documentation for available port numbers.config ECHO_UART_BAUD_RATEint "UART communication speed"range 1200 115200default 9600helpUART communication speed for Modbus example.config ECHO_UART_RXDint "UART RXD pin number"range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAXdefault 22 if IDF_TARGET_ESP32default 4 if !IDF_TARGET_ESP32helpGPIO number for UART RX pin. See UART documentation for more informationabout available pin numbers for UART.config ECHO_UART_TXDint "UART TXD pin number"range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAXdefault 23 if IDF_TARGET_ESP32default 6 if !IDF_TARGET_ESP32helpGPIO number for UART TX pin. See UART documentation for more informationabout available pin numbers for UART.config ECHO_UART_RTSint "UART RTS pin number"range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAXdefault 18 if IDF_TARGET_ESP32default 5 if !IDF_TARGET_ESP32helpGPIO number for UART RTS pin. This pin is connected to~RE/DE pin of RS485 transceiver to switch direction.See UART documentation for more information about available pinnumbers for UART.endmenu
  • 使用esp32自带的rs485功能, 将DE引脚设置为RTS功能引脚, 就可以在收发时自动切换使能, 免去控制逻辑. 作为主机使用很方便, 因为主机收发固定.从机的话就有点不一样,从机要考虑不发时一直收的情况. 自行判断要不要使用

  • 软件流控: 如果硬件流控处于禁用状态,可使用函数 uart_set_rts()uart_set_dtr() 分别手动设置 RTSDTR 信号电平。

// 设置RS485半双工模式
ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX));
  • 注意, 我目前遇到了2个未想明白的问题, 在收发函数前后使用打印函数, 老是容易死机重启. 其次就是, 这个 uart_read_bytes() 函数的超时时间, 是判断2次接收数据的时间差, 不能设置大, 不然会导致卡很久,将2次数据认为一次数据, 它居然不是按照 uart_set_rx_timeout() 区分一次数据. 可能还要另一个函数
// 根据超时时间接收数据, 这里自行确保返回的长度是符合缓存大小的
uart_read_bytes(ECHO_UART_PORT, data, BUF_SIZE, pdMS_TO_TICKS(tick)); // 设置UART TOUT功能的读取超时
ESP_ERROR_CHECK(uart_set_rx_timeout(uart_num, ECHO_READ_TOUT));

3. 编辑界面

推荐中文英文手册网址: https://lvgl.100ask.net/master/intro/introduction.html#requirements

  • 前期铺垫完了, 现在esp32编程和板子驱动, 还有 LVGL 测试确保正常. 开始编写 LVGL 界面工程

3.1. 添加组件

  • 直接点击这个图标就可以打开组件工具箱, 然后拖动组件到画布上就可以添加了, 也支持复制粘贴,

在这里插入图片描述

3.2. 组件属性

  • 组件的属性可以通过右栏设置,
    • 如果组件有不同状态, 就点右边的下拉框选择状态. 比如按钮有按下, 松开等不同状态.
    • 如果组件有不同模式, 就点左边的下拉框选择模式, 比如进度条有底色和进度条颜色, 还有表格, 有表头和表单等组成.
  • 不同模式又可能有多种状态可以供设置. 内置的预设样式也好过没有, 可以参考看看.

在这里插入图片描述

3.3. 布局对齐

  • 有一个容器组件, 可以做嵌套式布局, 形成子级父级关系. 这个软件的坐标系统是 相对父级 来说的, 如果起点都在 左上角, xy始终为正数, 终点在右下角.
  • 软件支持快捷对齐布局操作, 需要注意几点:
    • 上下左右,中心对齐是以最后一个选择的组件作为对象, 这个逻辑和画pcb和模型图时用的对齐指令不一样 .
    • 如果发现对齐后没有效果, 是因为两个组件不在同一的父级下, 对齐后坐标系统, 位置不同.

在这里插入图片描述

3.4. 组件事件

  • 模板里有很多可供学习的事件设置, 选择要设置的组件, 然后点击下栏中的 事件添加 即可. 软件提供的是可视化编程. 对于一些组件操作内置了选项, 也支持自定义事件代码.

  • 点击按调用cont_menu容器的isVisible(使能)函数, 达到一个点击图标显示菜单的效果.

在这里插入图片描述

  • 然后在对容器设置,点击后隐藏的效果:

在这里插入图片描述

  • 也可以设置跳转屏幕,和跳转动画等效果.

在这里插入图片描述

  • 也可以选择自定义代码. 更多其他内置事件功能自行尝试, 不赘述了.

在这里插入图片描述

3.5. 组件事件 自定义代码

  • 选择custom code -> Edit code 添加自定义代码.可以选择添加c或python类型. 添加并保存后, 点击右上角的生成代码, 即可自动将代码添加在工程中.在代码编辑中可以看到生成的内容.

在这里插入图片描述

  • 工程代码主要是 Custom 文件夹 和 Generated 文件夹 的内容. 前者是属于可更改的, 后者是不可更改的, 会在每次生成代码时自动刷新.
  • 其中 events_init.c 的内容就是对应 组件事件 中编辑的内容.
  • 需要注意的是, 他们是杂糅堆一起的, 是可以共同调用定义的全局变量, 也需要注意不要重复定义的全局变量!!!

在这里插入图片描述

  • Custom 文件夹的内容不会被自动刷新掉, 一般添加一下打包函数, 可以被 events_init.c 文件调用到.

在这里插入图片描述

3.6. 选择编译

  • 因为LVGL界面编辑是一个工程, 为了能编译运行, 不能添加一些多余的代码. 但最终是要给esp32工程里用的, 必定会用到一些工程里的变量函数, 如果每次导出都刷新掉, 重新更改, 就太不科学了. 所以我想到添加宏定义进行选择编译.

如果你有更好的方法请介绍给我.

#ifdef ESP_PLATFORM // esp32工程编译时自带的宏定义// 添加实际所需代码esp32_uart_read(rx_buf, 1000); // 假设的伪代码lv_spinbox_set_value(guider_ui.Settings_spinbox_2, reg.par.add);  // 控制ui组件
#else // LVGL仿真时执行的测试内容// 不耦合的测试内容int add = 666; // 测试组件代码正常运行lv_spinbox_set_value(guider_ui.Settings_spinbox_2, add);  // 控制ui组件
#endif

4. 总结

  • 剩下的就是枯燥无味, 简单重复的ui的组件修改, 和接口协议匹配的内容.
  • 或许可以尝试丢给ai, 最近挺流行的, 直接去研究怎么让ai帮忙写, 比自己写快多了 .
  • 今天刚通关剑星, 不知道啥时候出现ai觉醒的剧情 .
http://www.xdnf.cn/news/1053307.html

相关文章:

  • 认识电子元器件之磁传感器
  • Spring有代理对象的循环依赖时,如何确保代理对象能够正确持有原始对象的所有属性赋值结果?
  • 234. 回文链表
  • SQL 增删改查 —— 笔记篇
  • 面向对象设计原则
  • 深度学习——基于卷积神经网络实现食物图像分类【3】(保存最优模型)
  • React19源码系列之Hooks(useState)
  • Linux中的连接符
  • 谐波减速器 MINIF8 和 MINIF11 的区别
  • 事务传播机制分析:用户注册场景分析
  • 日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段(2):2020年12月2018年7月
  • leetcode148-排序链表
  • 《Java编程思想》读书笔记:第十二章
  • 01 人工智能起源与诞生
  • 在 Windows 上使用 Docker Desktop 快速搭建本地 Kubernetes 环境(附详细部署教程)
  • 第六章、6.2 ESP32低功耗模式详解:深度睡眠与轻度睡眠实战指南
  • Java泛型深度解析
  • MySQL-DCL数据控制语言详解
  • 深度学习打卡1
  • 【计算机网络】网络层IP协议与子网划分详解:从主机通信到网络设计的底层逻辑
  • Windows平台轻量级图片处理工具实测:功能与体验分享
  • 「Matplotlib 入门指南」 Python 数据可视化分析【数据分析全栈攻略:爬虫+处理+可视化+报告】
  • 前端面试九之Vue Router
  • 【Qt 中的元对象系统(Meta-Object System)】
  • 洛谷 P3865 【模板】ST 表 RMQ 问题
  • 基于OpenManus的跨平台部署方案及远程访问安全机制
  • 李宏毅2025《机器学习》第二讲-深度解构AI Agent:让大型语言模型学会记忆、使用工具与制定计划
  • LeetCode 2389.和有限的最长子序列
  • libuv 框架
  • RabbitMQ死信队列