NanoPi NEO移植LVGL8.3.5到1.69寸ST7789V屏幕

移植前准备

移植好fbtft屏幕驱动

参考链接:友善之臂NanoPi NEO利用fbtft驱动点亮1.69寸ST7789V2屏幕

获取源码

名称 地址 描述
lvgl https://github.com/lvgl/lvgl.git lvgl-8.3.5
lv_drivers https://github.com/lvgl/lv_drivers.git lv_drivers-6.1.1

创建工程目录

创建工程目录

c 复制代码
mkdir lvgl_display

下载的源码解压到该文件夹,将文件夹名称中的版本号去掉

c 复制代码
mv lvgl-8.3.5 lvgl
mv lv_drivers-6.1.1 lv_drivers

将头文件复制到工程目录下,去掉名称中的template

c 复制代码
lvgl_display/lvgl/lv_conf_template.h => lvgl_display/lv_conf.h
lvgl_display/lv_drivers/lv_drv_conf_template.h => lvgl_display/lv_drv_conf.h

工程目录下创建main.c,Makefile,创建文件夹build工程目录文件如下:

名称 描述
main.c 测试程序
Makefile 编译脚本
lv_conf.h lvgl配置文件
lv_drv_conf.h lvgl驱动配置文件
lvgl lvgl8.3.5源码
lv_drivers lvgl驱动源码
build 编译过程文件

c 复制代码
ls
rwxrwxr-x  2 pi pi   16384 8月  13 11:22 build/
-rw-rw-r--  1 pi pi   26339 8月  13 11:16 lv_conf.h
drwxrwxr-x  6 pi pi    4096 1月   4  2020 lv_drivers/
-rw-rw-r--  1 pi pi   11196 8月  13 09:19 lv_drv_conf.h
drwxrwxr-x 10 pi pi    4096 2月   7  2023 lvgl/
-rw-rw-r--  1 pi pi    2401 8月  13 11:22 main.c
-rw-rw-r--  1 pi pi    1956 8月  13 11:05 Makefile

修改配置文件lv_drv_conf.h

将#if 0修改为#if 1

c 复制代码
/**
 * @file lv_drv_conf.h
 *
 */

/*
 * COPY THIS FILE AS lv_drv_conf.h
 */

#if 1 /*Set it to "1" to enable the content*/

#ifndef LV_DRV_CONF_H
#define LV_DRV_CONF_H

#include "lv_conf.h"

将宏USE_FBDEV的值改为1,使能frame buffer设备

c 复制代码
/*-----------------------------------------
 *  Linux frame buffer device (/dev/fbx)
 *-----------------------------------------*/
#ifndef USE_FBDEV
#  define USE_FBDEV           1
#endif

#if USE_FBDEV
#  define FBDEV_PATH          "/dev/fb0"
#endif

修改lv_conf.h

将文件最开始的#if 0改为#if 1

c 复制代码
/* clang-format off */
#if 1 /*Set it to "1" to enable content*/

#ifndef LV_CONF_H
#define LV_CONF_H

#include <stdint.h>

使能宏LV_MEM_CUSTOM为1

c 复制代码
/*=========================
   MEMORY SETTINGS
 *=========================*/

/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
#define LV_MEM_CUSTOM 1
#if LV_MEM_CUSTOM == 0
    /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
    #define LV_MEM_SIZE (48U * 1024U)          /*[bytes]*/

    /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
    #define LV_MEM_ADR 0     /*0: unused*/
    /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
    #if LV_MEM_ADR == 0
        #undef LV_MEM_POOL_INCLUDE
        #undef LV_MEM_POOL_ALLOC
    #endif

#else       /*LV_MEM_CUSTOM*/
    #define LV_MEM_CUSTOM_INCLUDE <stdlib.h>   /*Header for the dynamic memory function*/
    #define LV_MEM_CUSTOM_ALLOC   malloc
    #define LV_MEM_CUSTOM_FREE    free
    #define LV_MEM_CUSTOM_REALLOC realloc
#endif     /*LV_MEM_CUSTOM*/

最后是比较关键的一个设置,TICK的配置,我们选择自己定义一个Tick定时器配置函数,在自己的应用程序中实现,源码用#if 0屏蔽

c 复制代码
#if 0	//原始代码
/*Use a custom tick source that tells the elapsed time in milliseconds.
 *It removes the need to manually update the tick with `lv_tick_inc()`)*/
#define LV_TICK_CUSTOM 0
#if LV_TICK_CUSTOM
    #define LV_TICK_CUSTOM_INCLUDE "Arduino.h"         /*Header for the system time function*/
    #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis())    /*Expression evaluating to current system time in ms*/
    /*If using lvgl as ESP32 component*/
    // #define LV_TICK_CUSTOM_INCLUDE "esp_timer.h"
    // #define LV_TICK_CUSTOM_SYS_TIME_EXPR ((esp_timer_get_time() / 1000LL))
#endif   /*LV_TICK_CUSTOM*/

#else	//新代码
/*Use a custom tick source that tells the elapsed time in milliseconds.
 *It removes the need to manually update the tick with `lv_tick_inc()`)*/
#define LV_TICK_CUSTOM 1
#if LV_TICK_CUSTOM
    #define LV_TICK_CUSTOM_INCLUDE <stdint.h>         /*Header for the system time function*/
    #define LV_TICK_CUSTOM_SYS_TIME_EXPR (custom_tick_get())    /*Expression evaluating to current system time in ms*/
#endif   /*LV_TICK_CUSTOM*/
#endif

使能music例程

c 复制代码
#define LV_FONT_MONTSERRAT_12 1
#define LV_FONT_MONTSERRAT_14 1
#define LV_FONT_MONTSERRAT_16 1

/*Music player demo*/
#define LV_USE_DEMO_MUSIC 1

修改lv_drivers/display/fbdev.c

不修改可能导致系统崩溃

c 复制代码
screensize = finfo.line_length * vinfo.yres;  

main.c内容

c 复制代码
#include "lvgl/lvgl.h"
//#include "lvgl/demos/lv_demos.h" //未使用 屏蔽
#include "lv_drivers/display/fbdev.h"
#include "lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>

#define DISP_BUF_SIZE (128 * 1024)

int main(void)
{
    /*LittlevGL init*/
    lv_init();

    /*Linux frame buffer device init*/
    fbdev_init();

    /*A small buffer for LittlevGL to draw the screen's content*/
    static lv_color_t buf[DISP_BUF_SIZE];

    /*Initialize a descriptor for the buffer*/
    static lv_disp_draw_buf_t disp_buf;
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);

    /*Initialize and register a display driver*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
		disp_drv.draw_buf   = &disp_buf;
    disp_drv.flush_cb   = fbdev_flush;
    //修改分辨率
    disp_drv.hor_res    = 280;
    disp_drv.ver_res    = 240;
    lv_disp_drv_register(&disp_drv);
#if 0   //未使用输入设备
    evdev_init();
    static lv_indev_drv_t indev_drv_1;
    lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
    indev_drv_1.type = LV_INDEV_TYPE_POINTER;

    /*This function will be called periodically (by the library) to get the mouse position and state*/
    indev_drv_1.read_cb = evdev_read;
    lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);


    /*Set a cursor for the mouse*/
    LV_IMG_DECLARE(mouse_cursor_icon)
    lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
    lv_img_set_src(cursor_obj, &mouse_cursor_icon);           /*Set the image source*/
    lv_indev_set_cursor(mouse_indev, cursor_obj);             /*Connect the image  object to the driver*/
#endif

    /*Create a Demo*/
    lv_demo_music();
    /*Handle LitlevGL tasks (tickless mode)*/
    while(1) {
        lv_timer_handler();
        usleep(5000);
    }

    return 0;
}

/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void)
{
    static uint64_t start_ms = 0;
    if(start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}

Makefile

c 复制代码
#
# Makefile
#
CC ?= gcc
LVGL_DIR_NAME ?= lvgl
LVGL_DIR ?= ${shell pwd}
CFLAGS ?= -O3 -g0 -I$(LVGL_DIR)/ -Wall -Wshadow -Wundef -Wmissing-prototypes -Wno-discarded-qualifiers -Wall -Wextra -Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith -fno-strict-aliasing -Wno-error=cpp -Wuninitialized -Wmaybe-uninitialized -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion -Wclobbered -Wdeprecated -Wempty-body -Wtype-limits -Wshift-negative-value -Wstack-usage=2048 -Wno-unused-value -Wno-unused-parameter -Wno-missing-field-initializers -Wuninitialized -Wmaybe-uninitialized -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wpointer-arith -Wno-cast-qual -Wmissing-prototypes -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wno-discarded-qualifiers -Wformat-security -Wno-ignored-qualifiers -Wno-sign-compare -std=c99
LDFLAGS ?= -lm
BIN = demo


#Collect the files to compile
MAINSRC = ./main.c

include $(LVGL_DIR)/lvgl/lvgl.mk
include $(LVGL_DIR)/lv_drivers/lv_drivers.mk
OBJ_DIR := $(LVGL_DIR)/build
#CSRCS +=$(LVGL_DIR)/my_ui/main.c 
##################################### 收集需要编译的源文件 #####################################
CSRCS += $(LVGL_DIR)/main.c
##################################### 将文件名替换为.o文件 #####################################

CXX_OBJCTS = $(patsubst  %.c, $(OBJ_DIR)/%.o, $(notdir $(CSRCS)))

SOURSE_DIR = $(dir $(CSRCS))

vpath %.c $(SOURSE_DIR)

$(OBJ_DIR)/%.o: %.c
        $(CC) $(CFLAGS) -c $< -o $@
        echo "CC $<"

all: $(CXX_OBJCTS)
        $(CC) -o $(BIN)  $(CXX_OBJCTS) $(LDFLAGS)
clean: 
        rm -f $(BIN) $(CXX_OBJCTS)

效果展示

相关推荐
昵称p2 个月前
lvgl
mcu·mqtt·操作系统·lvgl·任务创建
Mr_Chenph2 个月前
MicroPython rp2-LVGL 固件编译记录
lvgl·micropython·pico·固件
Projectsauron4 个月前
LVGL 控件之矩阵按钮(lv_buttonmatrix)
嵌入式·lvgl
1234567890@world4 个月前
LVGL | VisualStuio PC模拟器
lvgl
Projectsauron4 个月前
LVGL 控件之日历(lv_calendar)
嵌入式·lvgl
昵称p4 个月前
系统编程-lvgl
linux·lvgl·系统编程
启明智显4 个月前
【启明智显技术分享】工业级HMI芯片Model系列GUI合成到项目中的指南
嵌入式硬件·gui·lvgl·嵌入式开发·hmi方案
Sandman6z5 个月前
LVGL ArchLinux VSCode环境运行
ide·vscode·编辑器·lvgl·archlinux
xiaoyaoyou.xyz6 个月前
嵌入式UI开发-lvgl+wsl2+vscode系列:7、滚动(Scrolling)
ui·lvgl
xiaoyaoyou.xyz6 个月前
嵌入式UI开发-lvgl+wsl2+vscode系列:5、事件(Events)
单片机·ui·lvgl