esp-idf 移植 lvgl8.3.3
一、准备材料
- 开发板:esp32s3
- idf版本:4.4.2
- lvgl:8.3.3
注意:lvgl不要选择master分支,编译失败时不好确定问题。
二、创建idf项目
方式一
通过 VSCode 创建项目
在命令面板中搜索 esp-idf new,开始创建项目
项目配置信息
选择需要的模板,也可以选择想要的案例
注意: 需要VSCode 中安装 idf 环境的可以看我之前的笔记VSCode 中安装 esp-idf
方式二
通过命令创建项目
idf.py create-project
方式三
直接在路径 %ESP-IDF%\espressif\frameworks\esp-idf-v4.4.2\examples
中拷贝自己需要的使用案例
三、添加LVGL库
下载lvgl8.3.3
GitHub:https://github.com/lvgl/lvgl.git将lvgl库添加到项目的 components 文件中,如下图所示
** 注意,如果觉得文件比较多的话,可以删除不用的文件,如下图所示:
将
lv_conf_template.h
重命名为lv_conf_.h
,并将文件中的#if 0
改为#if 1
设置开发板为esp32s3
编译
** 注意:**如果出现编译错误时,检查一下自己是否下载成了master分支
四、添加显示驱动
下载lvgl_esp32_drivers
GitHub:https://github.com/lvgl/lvgl_esp32_drivers使用命令
idf.py menuconfig
打开图形配置界面
进入 Component config → LVGL ESP Drivers → LVGL TFT Display controller 配置显示驱动信息
SPI引脚配置
进入 Component config → LVGL configguration 配置LVGL信息
按s键进行保存,完成后按Q退出
配置屏幕信息和SPI通道数量
编译后会产生以下错误,如果所示
未定义显示器的像素宽度和高度
未定义开发板 SPI 的通道数量
只需要在文件
lvgl_helpers.h
中添加以下定义即可,如图所示#define SPI_HOST_MAX 3 // 开发板 SPI 通道数量
#define LV_HOR_RES_MAX 240 // 显示器水平像素
#define LV_VER_RES_MAX 320 // 显示器垂直像素
编译通过后,在 main.c 文件中添加程序,程序后面附上
SPI 信道错误
运行后不断重启,并出现图示中的问题,值需要在文件 `` 中将SPI信道改为自动模式
SPI_DMA_CH_AUTO
即可,如下图所示:
到此屏幕就能正常显示了。
五、添加触摸驱动
使用命令
idf.py menuconfig
打开图形配置界面
进入 Component config → LVGL ESP Drivers → LVGL Touch controller 打开触摸驱动
返回上一级,选择I2C通道
进入 Component config → I2C Port Settings 配置I2C引脚
六、main.c文件
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_freertos_hooks.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include "driver/gpio.h"
/* Littlevgl specific */
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#include "lvgl_helpers.h"
/*********************
* DEFINES
*********************/
#define TAG "main"
#define LV_TICK_PERIOD_MS 1
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_tick_task(void *arg);
static void guiTask(void *pvParameter);
static void create_demo_application(void);
/**********************
* APPLICATION MAIN
**********************/
void app_main() {
/* 使用任务创建图形时,必须使用固定任务创建
* 注意:不使用Wi-Fi或蓝牙时,可以将gui任务固定到核心0 */
xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 0, NULL, 1);
}
/* Creates a semaphore to handle concurrent call to lvgl stuff
* If you wish to call *any* lvgl function from other threads/tasks
* you should lock on the very same semaphore! */
SemaphoreHandle_t xGuiSemaphore;
static void guiTask(void *pvParameter) {
(void) pvParameter;
xGuiSemaphore = xSemaphoreCreateMutex();
lv_init();
/* 初始化驱动程序使用的SPI或I2C总线 */
lvgl_driver_init();
/* 创建堆内存,用过图形缓冲区buf1 */
lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf1 != NULL);
/* 不使用单色显示器时使用双缓冲 */
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
lv_color_t* buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf2 != NULL);
#else
static lv_color_t *buf2 = NULL;
#endif
static lv_disp_draw_buf_t disp_buf;
uint32_t size_in_px = DISP_BUF_SIZE;
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820 \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
/* Actual size in pixels, not bytes. */
size_in_px *= 8;
#endif
/* Initialize the working buffer depending on the selected display.
* NOTE: buf2 == NULL when using monochrome displays. */
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = disp_driver_flush;
/* When using a monochrome display we need to register the callbacks:
* - rounder_cb
* - set_px_cb */
#ifdef CONFIG_LV_TFT_DISPLAY_MONOCHROME
disp_drv.rounder_cb = disp_driver_rounder;
disp_drv.set_px_cb = disp_driver_set_px;
#endif
disp_drv.draw_buf = &disp_buf;
lv_disp_drv_register(&disp_drv);
/* Register an input device when enabled on the menuconfig */
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.read_cb = touch_driver_read;
indev_drv.type = LV_INDEV_TYPE_POINTER;
lv_indev_drv_register(&indev_drv);
#endif
/* Create and start a periodic timer interrupt to call lv_tick_inc */
const esp_timer_create_args_t periodic_timer_args = {
.callback = &lv_tick_task,
.name = "periodic_gui"
};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));
/* Create the demo application */
create_demo_application();
while (1) {
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
vTaskDelay(pdMS_TO_TICKS(10));
/* Try to take the semaphore, call lvgl related function on success */
if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
lv_task_handler();
xSemaphoreGive(xGuiSemaphore);
}
}
/* A task should NEVER return */
free(buf1);
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
free(buf2);
#endif
vTaskDelete(NULL);
}
/**
* @brief 创建标签
*/
void lvgl_lable_test(){
/* 创建一个标签 */
lv_obj_t* label = lv_label_create(lv_scr_act());
if (NULL != label)
{
// lv_obj_set_x(label, 90); // 设置控件的X坐标
// lv_obj_set_y(label, 100); // 设置控件的Y坐标
// lv_obj_set_size(label, 60, 20); // 设置控件大小
lv_label_set_text(label, "Counter"); // 初始显示 0
// lv_obj_center(label); // 居中显示
lv_obj_align(label, LV_ALIGN_CENTER, 0, -50); // 居中显示后,向上偏移50
}
}
/**
* @brief 按钮事件回调函数
*/
static void btn_event_callback(lv_event_t* event)
{
static uint32_t counter = 1;
lv_obj_t* btn = lv_event_get_target(event); //获取事件对象
if (btn != NULL)
{
lv_obj_t* btn_parent = lv_obj_get_parent(btn);
lv_obj_t* label = lv_obj_get_child(btn_parent, 0);
lv_label_set_text_fmt(label, "%d", counter); //设置显示内容
lv_obj_align(label, LV_ALIGN_CENTER, 0, -50); // 居中显示后,向上偏移50
counter++;
}
}
/**
* @brief 创建按钮
*/
void lvgl_button_test(){
/* 在当前界面中创建一个按钮 */
lv_obj_t* btn = lv_btn_create(lv_scr_act()); // 创建Button对象
if (btn != NULL)
{
lv_obj_set_size(btn, 80, 20); // 设置对象宽度和高度
// lv_obj_set_pos(btn, 90, 200); // 设置按钮的X和Y坐标
lv_obj_add_event_cb(btn, btn_event_callback, LV_EVENT_CLICKED, NULL); // 给对象添加CLICK事件和事件处理回调函数
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 50); // 居中显示后,向下偏移50
lv_obj_t* btn_label = lv_label_create(btn); // 基于Button对象创建Label对象
if (btn_label != NULL)
{
lv_label_set_text(btn_label, "button"); // 设置显示内容
lv_obj_center(btn_label); // 对象居中显示
}
}
}
static void create_demo_application(void)
{
/* 加载标签 */
lvgl_lable_test();
/* 加载按钮 */
lvgl_button_test();
}
static void lv_tick_task(void *arg) {
(void) arg;
lv_tick_inc(LV_TICK_PERIOD_MS);
}
esp-idf 移植 lvgl8.3.3的更多相关文章
- [IOT] 自制蓝牙工牌办公室定位系统 (二)—— 基于ESP32的蓝牙信号扫描系统
前面章节: 自制蓝牙工牌办公室定位系统 (一)-- 阿里物联网平台概览及打通端到云(硬核·干货) 目录: 1.蓝牙广播简介 2.蓝牙扫描简介 3.基于蓝牙广播和蓝牙扫描常见应用 4.ESP32 ...
- 如何为 esp32 编译和配置及烧写 MicroPython 固件。
MicroPython 在 esp-idf (esp32) 上编译固件 esp32 编译 micropython 的固件相关的资料应该很多吧,我也会出一篇,但会额外讲一些 linux 的东西的. 资料 ...
- VS Code 与 ESP32 官方SDK配置
开发基于 ESP XXX 微控制器应用,最简单的环境搭建方案是像 MicroPython.CircuitPython.NanoFramework 等,下载固件,直接开刷:或者基于 Arduino 的开 ...
- Cocos2d-x项目移植到WinRT/Win8小记
Cocos2d-x项目移植到WinRT/Win8小记 作者: K.C. 日期: 11/17/2013 Date: 2013-11-17 23:33 Title: Cocos2d-x项目移植到WinRT ...
- IDF实验室-简单的ELF逆向 writeup
题目:http://ctf.idf.cn/index.php?g=game&m=article&a=index&id=39 下载得到ElfCrackMe1文件,直接用IDA打开 ...
- ANSIC程序到KeilC51的移植心得
摘要:本文讲述了将ANSIC程序移植到KeilC51上应该注意的事项.文章讲述了存储类型.指针类型.重入函数.根据目标系统RAM的分布的段定位和仿真栈设置.函数指针.NULL指针问题.字节顺序.交叉汇 ...
- FL2440 rt3070模块ap模式移植
---------------------------------------------------------------------------------------------------- ...
- 如何使用安信可 ESP 系列一体化开发环境【转】
本文转载自:http://wiki.ai-thinker.com/ai_ide_use 关于 Problems 报错 注意:Eclipse 只是一个代码编写工具,它并不能读取 makefile 里面的 ...
- arduino 天下第一(暴论) -- 智能猫眼与 SDDC 连接器移植到 arduino 上
前言 之前看了官方玩过一个智能猫眼摄像头,我很有兴趣,但是那个 IDF 平台属实难整,我光安装都整了一天,网不好下载的包可能有问题.然后命令行操作也比较麻烦,我就想到了无敌的 arduino ,ESP ...
随机推荐
- 一个小 Trick
平方变两次 一个状态 \(S\) 有一个贡献,所有状态 \(S\) 组成集合 \(U\) . 然后我们要统计下面这个东西 \[ans=\sum_{S\in U}f^2(S) \] 然后我们就可以看作是 ...
- YII学习总结3(session)
session操作 <?php namespace app\controllers; use yii\web\Controller; class HelloController extends ...
- 关于mybatis-plus出现Not Found TableInfoCache. 的解决方法
查看自己的pom里面是不是导入了多个mybatis相关,若是的话就全部删去,然后添加如下代码段即可 <dependency> <groupId>com.baomidou< ...
- ChromePortable-Chrome便携化、绿化软件v2.0
ChromePortable-Chrome便携化.绿化软件v2.0-用户手册 By:ybmj@vip.163.com ,http://bbs.kafan.cn/thread-1806385-1-1.h ...
- Taurus.MVC WebAPI 入门开发教程8:WebAPI文档与自动化测试。
系列目录 1.Taurus.MVC WebAPI 入门开发教程1:框架下载环境配置与运行. 2.Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World. 3.Tau ...
- 从零搭建云原生技术kubernetes(K8S)环境-通过kubesPhere的AllInOne方式
前言 k8s云原生搭建,步骤有点多,但通过kubesphere,可以快速搭建k8s环境,同时有一个以 Kubernetes 为内核的云原生分布式操作系统-kubesphere,本文将从零开始进行kub ...
- Taurus.MVC 微服务框架 入门开发教程:项目集成:2、客户端:ASP.NET Core(C#)项目集成:应用中心。
系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...
- numa 自动balance 的bug分析
关于migrate_swap() 和 active_balance()之间的hardlock 背景:这个是在3.10.0-957.el7.x86_64 遇到的一例crash 下面列一下我们是怎么排查并 ...
- 从零开始Blazor Server(15)--总结
我们用了14篇文章,基本上把一个后台管理系统需要的UI部分都说的差不多了.所以这套文章也该到了结束的时候了. 这里面有很多问题,比如我们直接使用UI来拉数据库信息而没有使用service,再比如我们大 ...
- wsl创建证书让chrome浏览器识别
我在wsl里面测试http2协议的时候,在wsl用openssl创建了证书, 然后我把证书放在windows证书管理后,用chrome打开发现提示这个: 虽然可以点击下面的强制 访问 但是chrome ...