基于ST7789TFT移植LVGL

原创 嵌入式Lee 2024-05-26 08:00

一. 准备代码

https://github.com/lvgl/lvgl.git

下载指定版本,版本9和版本8变化有点大,我这里以用的比较多的版本8为例。

git clone --branch v8.4.0 https://github.com/lvgl/lvgl.git

删除不必要的文件,只保留src,examples/portingdemos文件夹,以及2h文件lv_conf_template.hlvgl.h

|-- demos|   |-- README.md|   |-- benchmark|   |-- keypad_encoder|   |-- lv_demos.h|   |-- lv_demos.mk|   |-- music|   |-- stress|   `-- widgets|-- examples|   `-- porting|-- lv_conf_template.h|-- lvgl.h`-- src    |-- core    |-- draw    |-- extra    |-- font    |-- hal    |-- lv_api_map.h    |-- lv_conf_internal.h    |-- lv_conf_kconfig.h    |-- lvgl.h    |-- misc`-- widgets

Src下是源码,按需添加无需修改

demos下是demo程序

examples/porting下有显示,输入,文件等移植模板

lv_conf_template.h是配置文件模板

lvgl.h是总的头文件

二. 添加源码到自己的工程

添加源码

lvgl/src/core/*.clvgl/src/draw/*.clvgl/src/draw/sw/*.clvgl/src/extra/*.clvgl/src/extra/layouts/flex/*.clvgl/src/extra/layouts/grid/*.clvgl/src/extra/libs/bmp/*.clvgl/src/extra/libs/ffmpeg/*.clvgl/src/extra/libs/freetype/*.clvgl/src/extra/libs/gif/*.clvgl/src/extra/libs/png/*.clvgl/src/extra/libs/qrcode/*.clvgl/src/extra/libs/rlottie/*.clvgl/src/extra/libs/sjpg/*.clvgl/src/extra/libs/tiny_ttf/*.clvgl/src/extra/others/fragment/*.clvgl/src/extra/others/grianav/*.clvgl/src/extra/others/ime/*.clvgl/src/extra/others/imgfont/*.clvgl/src/extra/others/monkey/*.clvgl/src/extra/others/msg/*.clvgl/src/extra/others/snapshot/*.clvgl/src/extra/themes/basic/*.clvgl/src/extra/themes/default/*.clvgl/src/extra/themes/mono/*.clvgl/src/extra/widgets/animimg/*.clvgl/src/extra/widgets/calendar/*.clvgl/src/extra/widgets/chart/*.clvgl/src/extra/widgets/colorwheel/*.clvgl/src/extra/widgets/imgbtn/*.clvgl/src/extra/widgets/keyboard/*.clvgl/src/extra/widgets/led/*.clvgl/src/extra/widgets/list/*.clvgl/src/extra/widgets/menu/*.clvgl/src/extra/widgets/meter/*.clvgl/src/extra/widgets/msgbox/*.clvgl/src/extra/widgets/span/*.clvgl/src/extra/widgets/spinbox/*.clvgl/src/extra/widgets/spinner/*.clvgl/src/extra/widgets/tabview/*.clvgl/src/extra/widgets/tileview/*.clvgl/src/extra/widgets/win/*.clvgl/src/font/*.clvgl/src/hal/*.clvgl/src/misc/*.clvgl/src/widgets/*.c

准备配置文件

复制lv_conf_template.hlv_conf.h放置在lvgl文件夹外和lvgl并列。

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

改为

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

准备显示适配文件

复制examples/porting下的lv_port_disp_template.c/h到工程目录,修改为

lv_port_disp.c/h

添加源码lv_port_disp.c到工程,有必要的话需要添加头文件lv_port_disp.h包含路径。

头文件包含路径

lvgl目录添加到头文件包含路径

完成以上工作后,基本完成了框架,但是还没有适配接口,编译还有问题,详细的适配见后面。

三. 适配

3.1 显示适配

前面已经准备好了lv_port_disp.clv_port_disp.h文件。

现在来实现接口,显示适配很简单,只需要实现自己的写点函数或者显示区域函数即可,最开始可以先适配为写点,后面再优化为写区域。

1.使能条件编译

lv_port_disp.c#if 0改为#if 1

lv_port_disp.h#if 0改为#if 1

2.头文件改名

#include "lv_port_disp_template.h"

改为

#include "lv_port_disp.h"

3.设置分辨率

#include

添加

#define MY_DISP_HOR_RES 240

#define MY_DISP_VER_RES 320

4.显示初始化

lv_port_disp_init中保留

Example for 1) 后的代码,注释掉

Example for 2)  Example for 3)后的代码,即使用一个行缓存。

 /* Example for 1) */    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*/
    /* Example for 2) */    //static lv_disp_draw_buf_t draw_buf_dsc_2;    //static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/    //static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/    //lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/
    /* Example for 3) also set disp_drv.full_refresh = 1 below*/    //static lv_disp_draw_buf_t draw_buf_dsc_3;    //static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*A screen sized buffer*/    //static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*Another screen sized buffer*/    //lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2,    //                      MY_DISP_VER_RES * LV_VER_RES_MAX);   /*Initialize the display buffer*/

实现初始化

static void disp_init(void){    st7789_itf_init();    /*You code here*/}

5.显示

disp_flush

/*put_px(x, y, *color_p)*/

后添加我们的写点函数

st7789_itf_set_pixel(x, y, *((uint16_t*)color_p));当然前面要包含头文件

#include "st7789_itf.h"

6.颜色格式设置

根据实际配置,我这里是RGB565,所以是16位。

lv_conf.h

#define LV_COLOR_DEPTH 16

这里还可以使用宏LV_COLOR_16_SWAP配置是否交换高低字节(即大小端交换),这适用于适配8位接口传输16位数据时的大小端对应。

LV_COLOR_16_SWAP配置为0不交换,配置为1交换。

7.调用初始化

注意在lv_init后调用lv_port_disp_init

#include "lv_port_disp.h"
lv_init();lv_port_disp_init();

4.1 适配时间戳

lvgl有两种方式获取时间戳,一种是

lv_conf.h中配置宏LV_TICK_CUSTOM0(默认)

然后周期调用lv_tick_inc,比如1ms调用一次即lv_tick_inc(1).

LV_TICK_CUSTOM配置为1

实现宏LV_TICK_CUSTOM_INCLUDE LV_TICK_CUSTOM_SYS_TIME_EXPR

分别是用户提供的实现时间戳获取的头文件和函数。

我这里使用前者,固定周期调用lv_tick_inc

4.2 适配日志打印于assert

lv_conf.h,设置

#define LV_USE_LOG 1 使能日志

设置日志等级,调试时可以设置LV_LOG_LEVEL_TRACE看详细过程,一般设置WARN即可。

#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN

设置打印接口,

#define LV_LOG_PRINTF 1,则使用printf,需要有stdio.h

#define LV_LOG_PRINTF 0,则需要调用lv_log_register_print_cb初始化打印,

比如

static void my_print(const char * buf)

{

wq_printf("%s\r\n",buf);

}

lv_log_register_print_cb(my_print);

lv_init();

lv_conf.h

LV_USE_ASSERT开头的宏设置为1,使能对应的assert

4.5 输入适配

下次再分享

4.6 文件系统适配

下次再分享

.简单测试

参考

examples/get_started/lv_example_get_started_1.c

代码如下:

#include "lvgl.h"#include "lv_port_disp.h"static void tick_callback(void){    lv_tick_inc(1);}
static void my_print(const char * buf){    wq_printf("%s\r\n",buf);}

static void btn_event_cb(lv_event_t * e){    lv_event_code_t code = lv_event_get_code(e);    lv_obj_t * btn = lv_event_get_target(e);    if(code == LV_EVENT_CLICKED) {        static uint8_t cnt = 0;        cnt++;
        /*Get the first child of the button which is the label and change its text*/        lv_obj_t * label = lv_obj_get_child(btn, 0);        lv_label_set_text_fmt(label, "Button: %d", cnt);    }}
/** * Create a button with a label and react on click event. */static void lv_example_get_started_1(void){    lv_obj_t * btn = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/    lv_obj_set_pos(btn, 10, 10);                            /*Set its position*/    lv_obj_set_size(btn, 120, 50);                          /*Set its size*/    lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);           /*Assign a callback to the button*/
    lv_obj_t * label = lv_label_create(btn);          /*Add a label to the button*/    lv_label_set_text(label, "Button");                     /*Set the labels text*/    lv_obj_center(label);}
void main(void){
    while(1)    {       
        lv_log_register_print_cb(my_print);        lv_init();        lv_port_disp_init();        os_hook_tick_register_callback(tick_callback);    lv_example_get_started_1();        while (1) {            uint32_t delay = lv_timer_handler();            if (delay < 1) delay = 1;            os_delay(delay);            st7789_itf_sync();        }        lv_deinit();    }    return;}

测试效果如下

DEMO测试

添加如下代码到自己的工程

lvgl/demos/benchmark/*.clvgl/demos/benchmark/assets/*.clvgl/demos/keypad_encoder/*.clvgl/demos/music/*.clvgl/demos/music/assets/*.clvgl/demos/stress/*.clvgl/demos/widgets/*.clvgl/demos/widgets/assets/*.c

lv_conf.h中将带DEMO的宏配置为1,可以挑选部分。

这里以MUSICDEMO为例,如果空间不够可以设置LV_DEMO_MUSIC_LARGE0

/*Music player demo*/#define LV_USE_DEMO_MUSIC 1#if LV_USE_DEMO_MUSIC    #define LV_DEMO_MUSIC_SQUARE    1    #define LV_DEMO_MUSIC_LANDSCAPE 1    #define LV_DEMO_MUSIC_ROUND     1    #define LV_DEMO_MUSIC_LARGE     0    #define LV_DEMO_MUSIC_AUTO_PLAY 1#endif

demo需要用到一些字体,lv_conf.h设置LV_FONT_MONTSERRAT_12LV_FONT_MONTSERRAT_22LV_FONT_MONTSERRAT_32,,LV_FONT_MONTSERRAT_16的宏为1

使能以下宏计算帧率

#define LV_USE_PERF_MONITOR 1 

代码如下

#include "lvgl.h"#include "demos/lv_demos.h"#include "lv_port_disp.h"#include "st7789_itf.h"
static void tick_callback(void){    lv_tick_inc(1);}
static void my_print(const char * buf){    wq_printf("%s\r\n",buf);}

void main(void){    while(1)    {        lv_log_register_print_cb(my_print);        lv_init();        lv_port_disp_init();        os_hook_tick_register_callback(tick_callback);        lv_demo_music();        uint32_t pre_time = os_get_ticks();        uint32_t cur_time = pre_time;        while (1) {            uint32_t delay = lv_timer_handler();            cur_time = os_get_ticks();            if(cur_time - pre_time >= 25)            {                pre_time = cur_time;                st7789_itf_sync();            }            if (delay < 1) delay = 1;            os_delay(delay);            //wq_printf("delay %d\r\n",delay);        }
        lv_deinit();    }    return;}

测试结果如下

六. 总结

LVGL的可移植性超级好,只需要实现一个简单的写点或者刷指定范围屏的接口即可,我们也可以其相关可移植性相关的设计。本分享实现了LVGL移植以及DEMO演示,后面可以考虑输入,文件系统相关移植,以及性能的优化。


评论 (0)
  • 导读Linux驱动程序领域再添新成员,PLIN驱动程序现已正式发布。这一新驱动程序为使用LIN接口的用户提供了一个便捷、高效的解决方案。本文将展示如何安装PLIN驱动程序,以及如何在Linux环境下进行基本的PLIN通信操作,确保您能够快速掌握并应用这一新工具。继我们在Linux环境下成功推出CAN/CAN FD接口驱动程序后,现在我们为LIN接口带来了同样兼容Linux的驱动程序。免费软件包中不仅包含了驱动程序本身,还提供实用工具和一份易于理解的快速入门指南。用户下载后,需要根据当前使用的Li
    虹科汽车智能互联 2025-04-21 14:56 58浏览
  • 一、‌基础原理验证与分析‌1、‌理解霍尔效应基本机制‌通过实验观察磁场中导体或半导体材料的电荷偏转现象,验证霍尔电压与磁场强度、电流方向的关系,直观认识洛伦兹力对载流子的作用‌。2、‌探索磁电效应关联性‌研究霍尔效应与材料电学特性(如载流子类型、浓度)的关联,揭示半导体材料的导电机制(如N型/P型半导体)。二、‌参数测量与标定‌1、‌关键物理量测量‌掌握霍尔元件灵敏度(KH)、霍尔系数(RH)、电导率(σ)及载流子迁移率(μ)的测量方法,为半导体材料性能评估提供数据支持。2、‌磁场强度与分布测定
    锦正茂科技 2025-04-21 13:03 36浏览
  •   电磁信号模拟平台解析   北京华盛恒辉电磁信号模拟平台作为模拟复杂电磁环境的系统,在无线通信、电子对抗等多领域广泛应用。以下从功能、技术特性、应用场景及发展趋势展开详细解读。   应用案例   目前,已有多个电磁信号模拟平台在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁信号模拟平台。这些成功案例为电磁信号模拟平台的推广和应用提供了有力支持。   一、核心功能   复杂电磁环境建模:构建贴近真实的电磁环境,涵盖各类干扰因素。   多通道信号模拟:模拟多通道电磁信号
    华盛恒辉l58ll334744 2025-04-21 15:10 91浏览
  •   有效数据智能分拣系统平台深度解析   一、系统概述   北京华盛恒辉有效数据智能分拣系统平台融合人工智能、机器视觉、物联网及大数据分析技术,为物流包裹、数据信息等提供高效精准的智能化分拣处理方案。通过自动化设备与智能算法协同运作,取代传统人工分拣模式,显著提升分拣效率、降低错误率,满足电商、快递及供应链不断增长的业务需求。   应用案例   目前,已有多个有效数据智能分拣系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润有效数据智能分拣系统。这些成功案例为有效数据智能分
    华盛恒辉l58ll334744 2025-04-21 16:22 117浏览
  • 北京贞光科技有限公司作为紫光同芯授权代理商,深耕电子元器件领域数十载,专为汽车与工业客户提供车规级安全芯片及配套服务。公司整合硬件供应、软件SDK与技术支持为一体,配备专业团队提供选型咨询与现场指导,助力客户实现完整的芯片应用解决方案。在全球芯片供应链重构的大背景下,我国车规级芯片产业正迎来前所未有的发展机遇。北京贞光科技有限公司作为紫光同芯授权代理商,深耕电子元器件领域数十载,专为汽车与工业客户提供车规级安全芯片及配套服务。公司整合硬件供应、软件SDK与技术支持为一体,配备专业团队提供选型咨询
    贞光科技 2025-04-21 16:10 71浏览
  •  霍尔效应自发现以来,已渗透至多个行业领域,其核心应用可归纳为以下几类:一、‌电子与半导体行业‌1、‌半导体器件开发与测试‌① 通过测量霍尔系数和电阻率,判断器件的导电类型(N型/P型)及载流子浓度分布,优化器件设计和制造工艺‌。② 监控晶圆掺杂水平和表面缺陷,提高集成电路良率‌。2、‌磁场传感器制造与校准‌测试霍尔传感器的灵敏度、线性度、响应时间等参数,确保其在汽车、工业控制等场景下的可靠性‌。3、‌电磁测量仪器‌基于霍尔电压与磁场强度的线性关系,开发高斯计、电流表、功率计等‌。二、
    锦正茂科技 2025-04-21 13:17 45浏览
  • 导读在当今快速发展的智能通讯领域,时间敏感网络(TSN)已成为确保网络通信高可靠性和低延迟的关键技术。IEEE 802.1 Qci作为TSN的一个重要组成部分,提供了一套强大的机制来管理网络流量,确保关键数据流的优先级和带宽得到保障。本文将深入探讨IEEE 802.1 Qci协议的基本概念、工作原理以及虹科提供的Qci解决方案,帮您理解如何通过精确的流量控制来提升网络的稳定性和效率。虹科TSN解决方案01# 技术简介时间敏感网络(TSN)通过IEEE 802.1 Qci标准定义了一种关
    虹科工业智能互联 2025-04-21 16:17 74浏览
  •   海上安全事件应急处置系统解析   北京华盛恒辉海上安全事件应急处置系统是为应对船舶碰撞、火灾等海上突发事件打造的综合管理体系,通过技术与协同机制,实现快速响应救援、优化资源配置,守护海上生命、财产与环境安全。以下从系统构成、功能、技术、应用及趋势展开阐述。   应用案例   目前,已有多个海上安全事件应急处置系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润海上安全事件应急处置系统。这些成功案例为海上安全事件应急处置系统的推广和应用提供了有力支持。   一、系统构成
    华盛恒辉l58ll334744 2025-04-21 15:50 68浏览
  •   有效数据智能分拣系统详解   北京华盛恒辉有效数据智能分拣系统融合人工智能、大数据分析与机器学习等前沿技术,实现海量数据自动化分类、筛选、整理及分配。凭借强大的数据处理效能,助力企业精准提取关键信息,优化决策流程,提升运营效率。以下从系统架构、核心功能、技术特性、应用场景及发展趋势展开解读。   应用案例   目前,已有多个有效数据智能分拣系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润有效数据智能分拣系统。这些成功案例为有效数据智能分拣系统的推广和应用提供了有力支持。
    华盛恒辉l58ll334744 2025-04-21 16:46 100浏览
  •   海上安全事件应急处置系统平台深度解析   一、平台概述   北京华盛恒辉海上安全事件应急处置系统平台融合现代信息技术、通信技术、GIS、大数据分析及 AI 等技术,旨在快速响应船舶碰撞、火灾、溢油等海上突发事件,实现科学决策与高效资源调配,保障海上生命财产安全、减少环境污染。   应用案例   目前,已有多个海上安全事件应急处置系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润海上安全事件应急处置系统。这些成功案例为海上安全事件应急处置系统的推广和应用提供了有力支持
    华盛恒辉l58ll334744 2025-04-21 15:21 85浏览
  • 精益生产咨询师证/精益管理专业人员证/精益生产工程师证虽然在名称上有一些差异,但其实实际区别并不大,目前类似的证书以ILSSI-CLMP较为得到国际上的认可,当然,你不会因为有一张精益生产咨询师证,而会有人马上请你做咨询师,因为除了知识之外,你还要有充足经验、热诚、沟通能力等等,这些也是我们招聘咨询师的基本要求。那么,有没有必要取得CLMP证书呢?这主要取决于你自己对职业发展的规划和自我提升的意志。CLMP是什么?CLMP的全称是Certified Lean Management Profess
    优思学院 2025-04-21 14:29 42浏览
  • 导读在汽车测试和现代工业领域,功耗控制与效率优化是工程师们不断追求的目标。虹科PCAN Router系列设备以其卓越的性能和灵活性,为CAN/CAN FD网络中的报文转换提供了高效解决方案。本文将探讨虹科PCAN Router系列设备如何在保持高效工作的同时,通过低功耗模式和高效唤醒功能,满足对能耗有严格要求的应用场景。虹科PCAN Router系列网关1 低功耗模式的优势与实现在实际的工作场景中,可能会出现一些对功耗要求存在限制的情况。鉴于此,可以灵活设置虹科PCAN Router系
    虹科汽车智能互联 2025-04-21 15:45 62浏览
  • 导读在智能汽车技术发展浪潮中,车辆控制系统的智能化、网络化已成为行业发展的必然趋势。虹科PEAK智行定位车控系统,集成了尖端科技,能够实现车辆全方位监控与控制。从实时GPS定位到CAN/CAN FD信号处理,虹科方案不仅提升了车辆的智能化水平,更在安全性和效率上迈出了革命性的一步。虹科PEAK智行定位车控系统,通过CAN/CAN FD信号实现车辆的精准控制,包括加减速、转弯、倒退等动作,模拟真实车辆平台的动态表现。该系统搭载了虹科各型号设备,通过紧密协作,实时反映车辆位置、总线报文等信息,实现车
    虹科汽车智能互联 2025-04-21 16:04 72浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦