【LVGL学习笔记】(四)PlatformIO + LVGL8.3配置

news2025/2/5 3:52:46

LVGL全程LittleVGL,是一个轻量化的,开源的,用于嵌入式GUI设计的图形库。并且配合LVGL模拟器,可以在电脑对界面进行编辑显示,测试通过后再移植进嵌入式设备中,实现高效的项目开发。
在这里插入图片描述
LVGL中文教程手册:极客笔记之LVGL教程

配置信息
芯片:ESP32-PICO-D4
PlatformIO版本:6.1.5
显示屏型号:ST7789V 240x240

一. platformIO生成项目文件

首先生成一个新项目,可以取消最后一行的勾选,自定义项目存储位置。
在这里插入图片描述
项目架构

Project
├─ .pio
│  ├─ build            		# 编译生成的文件
│  ├─ libdeps          	# 依赖的开源库文件
│  │  ├─ integrity.dat 	# 库配置文件,这个文件自动生成,不能手动修改
├─ .vscode             	# vscode配置文件
├─ lib       		   			# 私有库文件,里面的文件会被编译为静态库链接到项目中
├─ include             		# 头文件放置文件夹
├─ src                 		# 源文件放置文件夹
├─ test                		# 测试文件放置文件夹
├─ .gitignore              
└─ platformio.ini	  	 	# 项目参数配置文件,libdeps中的库文件就在这里进行配置

修改platformio.ini文件
添加烧录串口号和串口监视速率,这里的串口速率只是配置platformio monitor接收数据的速率,并没有配置芯片的串口发送速率。

monitor_speed = 115200
upload_port = COM11

添加开源库
在下方的界面中搜索相应的库文件,并选择想要的版本添加到文件中。

注意:各个项目的库文件虽然都可以在installed中找到,但是不同项目的库文件不是共享的。也就是说,即使两个项目用了同一个版本的同一个库,installed中会有两个库文件,分别存储在两个项目的libdeps中。

在这里插入图片描述
在这里插入图片描述
选择添加之后,platformio.ini文件中就会自动生成依赖库代码。
在这里插入图片描述

二. 修改配置文件

1. lvgl

复制lv_conf_template.h到同一路径下,并改名为lvgl_conf.h
在这里插入图片描述
内容解注释
在这里插入图片描述
启用自定义时钟
注意:没有一步的话会导致屏幕停留在第一帧的界面
在这里插入图片描述

2.TFT_eSPI

修改User_Setup_Select.h文件,选择屏幕的型号。
这里只能解注释一个 #include ,所以需要把 #include<User_Setup.h> 给注释掉。
在这里插入图片描述
在这里插入图片描述
修改Setup24_ST7789.h文件,这里需要根据自己屏幕和芯片的连接引脚来确定引脚号。
在这里插入图片描述

三. 创建lvgl和屏幕的连接

可以参考lvgl/examples/porting/lv_port_disp_template.c文件,但是里面没有添加屏幕初始化的内容,所以需要结合TFT的demo来编写代码,以下是我用的源码。

注意:需要用cpp文件来编写,因为TFT_eSPI是基于cpp的。

/**
 * @file display.cpp
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "display.h"
#include <stdbool.h>
#include <TFT_eSPI.h>

/*********************
 *      DEFINES
 *********************/
#ifndef MY_DISP_HOR_RES
    #define MY_DISP_HOR_RES    (240)
#endif

#ifndef MY_DISP_VER_RES
    #define MY_DISP_VER_RES    (240)
#endif

/**********************
 *  STATIC VARIABLES
 **********************/
TFT_eSPI tft = TFT_eSPI();

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors(&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp_drv);
}

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void Display::init(void)
{
    /* Set Backlight mode */
    ledcSetup(LCD_BL_PWM_CHANNEL, 5000, 8);
	ledcAttachPin(LCD_BL_PIN, LCD_BL_PWM_CHANNEL);

    /* Init lvgl */
	lv_init();

    /* Init display device */
	tft.begin(); 
	tft.setRotation(4); /* mirror */

    /*-----------------------------
     * Create a buffer for drawing
     *----------------------------*/
    static lv_disp_draw_buf_t draw_buf_dsc_1;
    static lv_color_t buf_1[MY_DISP_HOR_RES * 10];  /*A buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/
    static lv_disp_drv_t disp_drv;      /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);        /*Basic initialization*/

    /*Set up the functions to access to your display*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = MY_DISP_HOR_RES;
    disp_drv.ver_res = MY_DISP_VER_RES;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_1;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}

void Display::routine(void)
{
	lv_task_handler();
}

void Display::setBackLight(float duty)
{
	duty = constrain(duty, 0, 1);
	duty = 1 - duty;
	ledcWrite(LCD_BL_PWM_CHANNEL, (int)(duty * 255));
}
#ifndef DISPLAY_H
#define DISPLAY_H

#include <lvgl.h>

#define LCD_BL_PIN 5
#define LCD_BL_PWM_CHANNEL 0


class Display
{
private:


public:
	void init();
	void routine();
	void setBackLight(float);
};

#endif

四. 设计UI

这里使用的是官方提供的demo,lvgl/examples 中有很多官方提供的demo可以进行参考。

void lv_demo(void)
{
    lv_obj_t * obj = lv_obj_create(lv_scr_act());
    lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_RED), 0);
    lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, 0);

    lv_obj_align(obj, LV_ALIGN_LEFT_MID, 10, 0);

    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, obj);
    lv_anim_set_values(&a, 10, 50);
    lv_anim_set_time(&a, 1000);
    lv_anim_set_playback_delay(&a, 100);
    lv_anim_set_playback_time(&a, 300);
    lv_anim_set_repeat_delay(&a, 500);
    lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
    lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out);

    lv_anim_set_exec_cb(&a, anim_size_cb);
    lv_anim_start(&a);
    lv_anim_set_exec_cb(&a, anim_x_cb);
    lv_anim_set_values(&a, 10, 240);
    lv_anim_start(&a);
}

五. 修改main.cpp

/**
 * @file main.cpp
 * @author jozenlee
 * @brief
 * @version 0.1
 * @date 2022-12-15
 *
 * @copyright Copyright (c) 2022
 *
 */

#include <Arduino.h>
#include "lv_demo.h"

#include "display.h"
Display screen;

// lv_group_t * group;
void setup() {
    /* Init Serial */
    Serial.begin(115200);
    
    /* Init lvgl display port */
    screen.init();
    screen.setBackLight(0.2);

    /* Inflate GUI objects */
    lv_demo();
}

void loop() {
    // run this as often as possible
    screen.routine();

    /* Serial test */
    Serial.println("hello");
}

效果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/103268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PicGo+GitHub搭建个人图床用于Markdown、HTML等图片引用

方便程度&#xff1a;★★★★☆ 配置难度&#xff1a;★★☆☆☆ 稳定性&#xff1a;★★★★★ 适用环境&#xff1a;Windows、Mac、Linux 需要工具&#xff1a;GitHub 账号、PicGo 客户端 隐私性&#xff1a;别人可以访问你的图片仓库 GitHub仓库设置 流程&#xff1…

vue后台系统管理项目-商城轮播图管理功能

商城轮播图管理功能 功能介绍&#xff1a; 1.轮播图列表分页功能&#xff1b; 2.轮播图添加功能&#xff1b; 3.轮播图编辑功能&#xff1b; 4.轮播图删除功能&#xff1b; 5.轮播图启用禁用功能&#xff1b; 6.轮播图获取排序号功能&#xff1b; 7.轮播图查看详情功能&#xf…

2.创建自己的Cesiunm地球隐藏控件

目录​​​​​​​ 一、创建地球 引入Cesium.JS和初始页面 修改初始页面 将项目通过tomcat发布 二、去除不需要的控件 一、创建地球 引入Cesium.JS和初始页面 创建一个名为my-cesium的文件夹&#xff0c;将下载好的Cesium中的Build文件夹和Apps中的HelloWorld.html复制到…

基于Android的地铁查询系统app-计算机毕业设计

项目介绍 本软件研究了一个Android平台的地铁查询软件实现方案,从数据库数据保存到地铁数据的提取&#xff0c;再到界面的友好展示,最后到一个成型软件的生成这样一个过程,研究了SQLite数据库在Android平台的应用以及在手机平台的展示等等。 系统提供了地铁线路、站点和换乘的…

3.Entity和CZML添加图形

目录 Entity创建盒子 创建view容器 配置Entity ​编辑CZML数据添加图形 CZML是什么 怎么加载CZML Entity创建盒子 创建view容器 <!DOCTYPE html> <html lang"en"><head><!-- Use correct character set. --><meta charset"ut…

精华推荐 |【深入浅出Sentinel原理及实战】「原理探索专题」完整剖析Alibaba微服务架构体系之轻量级高可用流量控制组件Sentinel(1)

Sentinel是什么&#xff1f;不要概念混淆啊&#xff01; 注意&#xff1a;本Sentinel与Redis服务Sentinel是两回事&#xff0c;压根不是一个概念&#xff0c;请大家不要混肴。 Alibaba的Sentinel Sentinel是由阿里巴巴中间件团队开发的开源项目&#xff0c;是一种面向分布式微…

Vuex的相关知识

「Vuex的相关知识」 ​ vuex是一种对vue 应用中多个组件的共享状态进行集中式的管理(读/写)&#xff1b; vuex的工作原理&#xff1a; https://segmentfault.com/a/1190000021717329 ​ vuex 核心概念和API&#xff1a;state、mutations、actions、getters、modules、向外暴…

green power 设备入网过程

目录 Green Power设备入网流程 单项green power commissioning过程 抓包实例 1. SINK发送Green Power:GP Proxy Commissioning Mode命令​编辑​编辑 2. GPD发送入网命令 3. Proxy和Sink发送Green Power:GP Commissioning Notification 4. …

通过 Request 请求获取真实 IP 地址以及对应省份城市

title: 通过 Request 请求获取真实 IP 地址以及对应省份城市和系统浏览器信息 date: 2022-12-16 16:20:26 tags: GeoIP2UserAgentUtils categories:开发技术及框架 cover: https://cover.png feature: false 1. 获取真实 IP 地址 1.1 代码 代码如下&#xff0c;这里的 Commo…

set、map使用及其细节

&#x1f9f8;&#x1f9f8;&#x1f9f8;各位大佬大家好&#xff0c;我是猪皮兄弟&#x1f9f8;&#x1f9f8;&#x1f9f8; 文章目录一、两个概念①关联式容器与序列式容器②键值对二、set、map①setset的两种遍历方式set的升降序排序set的eraseset的count②mapSGI-STL中键值…

ISCSLP论文介绍|利用BERT提高语种识别性能

本文介绍清华大学语音与音频技术实验室&#xff08;SATLab&#xff09;ISCSLP 2022录用论文。BERT-LID: Leveraging BERT to Improve Spoken Language Identification。这篇文章将BERT模型引入到语种识别领域。利用BERT模型的优越性&#xff0c;再结合下游不同的神经网络模型&a…

OFDM系统中基于dmrs导频的时间跟踪、频率跟踪算法

目录发射端模型假设接收端模型假设时延估计&#xff08;时间跟踪&#xff09;频偏估计&#xff08;频率跟踪&#xff09;在OFDM系统中&#xff0c;为了估计出信号传输遇到的时间偏移和频率偏移&#xff0c;可以采用导频进行估计。 发射端模型假设 我们假设如下模型&#xff1…

如何熟练掌握运用Delft3D建模、水动力模拟方法及在地表水环境影响评价中的实践技术

Delft3D是由荷兰Delft大学WL Delft Hydraulics开发的一套功能强大的软件包&#xff0c;主要应用于自由地表水环境。该软件具有灵活的框架&#xff0c;能够模拟二维和三维的水流、波浪、水质、生态、泥沙输移及床底地貌&#xff0c;以及各个过程之间的相互作用。它是国际上最为先…

使用 C# Graphics 绘图来绘制一个足球

背景 2022卡塔尔世界杯是足球爱好者的狂欢&#xff0c;这与我毫无关系&#xff0c;作为一个缺乏运动的人&#xff0c;还是不要去看人家玩命的运动了。虽然不看球&#xff0c;不过这波热度的持续冲击&#xff0c;还是让我在朋友圈刷到了结局 ———— 球王梅西如愿以偿捧得金杯…

Bootstrap5 下拉菜单

下拉菜单可以是单选下拉菜单&#xff0c;也可以是多选的下拉菜单。 单选下拉菜单&#xff1a; 多选下拉菜单&#xff1a; 在 Bootstrap5 中下拉菜单 <select> 元素可以使用 .form-select 类来渲染 : 实例 <select class"form-select"> <option>…

内核启动过程分析

目录 一、内核源码获取查看 1.1、Source Insight使用 二、查看链接脚本 三、分析head.S 3.1、到入口前代码 3.2、内核启动的汇编阶段 四、main.c内核启动的c语言阶段 4.1、内核打印函数printk 4.2、启动信息 五、rest_init函数 5.1、进程0、进程1、进程2​编辑 5.2、…

详细复习云开发~小程序【搜索功能、登陆注册功能、点赞收藏评论功能、评论功能、CMS网页版管理后台】

文章目录一&#xff0c;搜索功能1-1&#xff0c;需求1-2&#xff0c;实现原理1-3&#xff0c;模糊搜索的代码实现1-3-1&#xff0c;模糊搜索单个字段1-3-2&#xff0c;模糊搜索多个字段&#xff08;满足一个即可&#xff09;1-3-3&#xff0c;模糊搜索多个字段&#xff08;要同…

python获取redis memory使用情况

项目研发过程中&#xff0c;用到Python操作Redis场景&#xff0c;记录学习过程中的心得体会。 一、环境搭建 Windows Anaconda3安装redis第3方包&#xff0c;pip install -u redis pip install -u # 升级安装 linux下查看redis配置信息bind 127.0.0.1 # 表示只允许本地访问,…

AssetBundle依赖打包有哪些注意点

1&#xff09;AssetBundle依赖打包有哪些注意点 ​2&#xff09;子程序集如何引用Assembly-CSharp.dll 3&#xff09;Unity的线性空间下自定义贴图在PS中修改问题 4&#xff09;如何关闭视锥体剔除 这是第318篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化…

CSS3之2D转换

文章目录2D转换一、transform1-1.2D转换之移动translate1-2.translate&#xff08;百分比&#xff09;盒子居中二、rotate2-1.旋转效果2-2.transform-origin设置旋转中心点三、2D转换之缩放scale四、2D转换综合写法总结2D转换 转换&#xff08;trabsform&#xff09;是CSS3中具…