继上一个文章,移植完显示和输入,接下来就剩存储,这里演示lvgl自带的spiffs文件系统,把一个gif图解码并存放。
找到自己安装esp idf环境的路径,找到spiffs文件夹我这里的路径如下
C:\Espressif\frameworks\esp-idf-v4.4.4\examples\storage\spiffsgen
继续使用上篇文章,完成了显示和输入的工程。把spiffs示例里的东西放在自己的工程里面。
放到lvgl初始化的上面,同时别忘了包含头文件。
从spiffs示例里导入测试函数
测试函数放入,记得把打印hello world删除
把spiffs示例下的spiffs_image文件夹拷贝到自己的工程目录下。(可以自定义hello.txt文件里的内容)
此时,根据官方手册里,还需要修改CMakeList文件
在main文件夹下的CmakeList中添加这段代码
spiffs_create_partition_image(storage ../spiffs_image FLASH_IN_PROJECT)
文件系统需要分配分区,点开左下角的小齿轮,选择自定义CSV
同时,把spiffs下的csv文件放入自己的工程,重新编译 成功运行
这里我们对代码进行一些修整,文件系统的代码任然放在appmain里,此时不需要按键所以把它和按键回调都删除,在lv_porting文件夹里新建lv_task.c和.h文件,放置我们的任务函数
/**
* @file lv_task.h
*
*/
/*Copy this file as "lv_task.h" and set this value to "1" to enable content*/
#if 1
#ifndef LV_TASK_H
#define LV_TASK_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_task();
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_TASK_H*/
#endif /*Disable/Enable content*/
/**
* @file lv_task.c
*
*/
#include
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include "esp_timer.h"
#include "lvgl_helpers.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
#include "lvgl.h"
#include "lv_demos.h"
#include "lv_task.h"
#include "./driver/gpio.h"
static void lv_tick_task(void *arg) // LVGL 时钟任务
{
(void)arg;
lv_tick_inc(10);
}
void lv_task(void)
{
lv_init();
lv_port_disp_init();
// 設定三個按鍵:4,5,16
// 左 右 確定
gpio_config_t pGPIOConfig =
{
.intr_type = GPIO_INTR_DISABLE, // 中断不开启
.mode = GPIO_MODE_INPUT,
.pin_bit_mask = GPIO_SEL_4,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pull_up_en = GPIO_PULLDOWN_ENABLE};
gpio_config(&pGPIOConfig);
pGPIOConfig.pin_bit_mask = GPIO_SEL_5;
gpio_config(&pGPIOConfig);
pGPIOConfig.pin_bit_mask = GPIO_SEL_16;
gpio_config(&pGPIOConfig);
lv_port_indev_init();
lv_group_t *group = lv_group_create(); // 創建group
lv_indev_set_group(indev_keypad, group);
/* 创建一个10ms定时器*/ // 定期处理GUI回调
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, 10 * 1000));
while (1)
{
lv_timer_handler(); // 处理LVGL任务
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
lv_tick_inc(10);
vTaskDelay(pdMS_TO_TICKS(10));
}
}
app_main函数里对应的删除掉,并且创建任务
xTaskCreate(&lv_task, "lv_task", 1024*8, NULL, 5, NULL);
为了方便调用,在第三方库,设定"/"作为文件系统调用。同时勾选上GIFT解码。
因为单片机设定缓存较低,这里把Memory settings 自定义勾选上。
展示cpu的fps
在task程序里添加以下代码,演示lvgl例程里的gif图(放在while循环前面即可)
LV_IMG_DECLARE(img_bulb_gif); //可以使用其他文件里的数组
lv_obj_t *img;
img = lv_gif_create(lv_scr_act());
lv_gif_set_src(img, &img_bulb_gif);
lv_obj_align(img, LV_ALIGN_LEFT_MID, 20, 0);
编译下载,屏幕显示gif图
先把上面显示例程gif的代码注释掉,加上下面的代码(把官方例程下的gif放在自己工程的spiffs_image文件夹下,并命名为test.gif)
LV_IMG_DECLARE(img_bulb_gif); //可以使用其他文件里的数组
lv_obj_t *img;
// img = lv_gif_create(lv_scr_act());
// lv_gif_set_src(img, &img_bulb_gif);
// lv_obj_align(img, LV_ALIGN_LEFT_MID, 20, 0);
img = lv_gif_create(lv_scr_act());
/* Assuming a File system is attached to letter 'A'
* E.g. set LV_USE_FS_STDIO 'A' in lv_conf.h */
//lv_gif_set_src(img, "A:lvgl/examples/libs/gif/bulb.gif");
lv_gif_set_src(img, "/spiffs/test.gif");
lv_obj_align(img, LV_ALIGN_RIGHT_MID, -20, 0);
同样的效果
如果把设置里"/"改成"/spiffs"
就可以省略
lv_gif_set_src(img, "/test.gif");
把47改回65对应字符'A'
就需要这样写
lv_gif_set_src(img, "A:spiffs/test.gif");
不过跟推荐使用"/",之后需要调用的多了使用反斜杠更加方便
使用宏定义定义字符串,字符串之间会自动拼接
#define SPIFFS_PATH "/spiffs"
lv_gif_set_src(img, SPIFFS_PATH"/test.gif");