wwwxxx国产_337p日本欧洲亚洲大胆张筱雨_免费在线看成人av_日本黄色不卡视频_国产精品成熟老女人_99视频一区_亚洲精品97久久中文字幕_免费精品视频在线_亚洲色图欧美视频_欧美一区二三区

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2177|回復: 1
收起左側

LVGL移植到STM32教程(附源碼)

[復制鏈接]
ID:1149337 發表于 2025-5-1 19:10 | 顯示全部樓層 |閱讀模式
LVGL全稱Light and Versatile Graphics Library,輕量級通用圖形庫。

LVGL是一個開源的ui圖形庫,能跑在各種單片機上(樹莓派、荔枝派也行)。支持按鈕,觸摸,編碼器旋鈕,鼠標等輸入設備。支持高級圖形效果,動畫、反鋸齒、透明度等。LVGL的界面非常精美,可以在官網的先感受一下他的強大,這是它demo的鏈接。

lvgl對處理器的要求很低,源自[官方文檔]。(docs.lvgl io/master/intro/index.html#requirements)


使用分辨率320*480的屏幕,驅動芯片LIL9486,16位色TN屏,觸摸是電阻屏,處理器stm32f103zet6,板子是自己畫的,可以使用正點原子的精英板,屏幕接口完全一樣,用的都是FSMC總線。

三、移植前準備工作
1.準備原有工程
本教程基于正點原子的觸摸屏實驗移植,源碼可以在正點原子資料下載中心下載。

不一定要用這個工程,只需要一個屏幕,能顯示能觸控就行,lvgl用到的屏幕接口只有一個:

/**
* @brief 在指定區域內填充指定顏色塊
* @param sx sy ex ey (sx,sy),(ex,ey):填充矩形對角坐標,區域大小為:(ex-sx+1)*(ey-sy+1)  
* @param color 要填充的顏色
*/
void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)

對于觸摸識別,只需要有一個當前觸摸的x、y坐標,有一個觸摸按下的標志。

if(tp_dev.sta&0x80)//tp_dev.sta為觸摸按下的標記,有觸摸的時候最高位標記為1,滿足if的條件
{
        last_x = tp_dev.x[0];//tp_dev.x[0]為觸摸芯片讀取的x坐標
                last_y = tp_dev.y[0];//tp_dev.y[0]為觸摸芯片讀取的y坐標
                data->point.x = last_x;//data->point.x為lvgl內部使用
                data->point.y = last_y;
                data->state = LV_INDEV_STATE_PR;//給lvgl標記按下的狀態
}
else
{
        data->point.x = last_x;
                data->point.y = last_y;
                data->state = LV_INDEV_STATE_REL
}





除此之外,還需要一個周期為1ms的定時器中斷,給lvgl提供心跳。

以上三點是lvgl最基本的需求。

我們先把觸摸屏實驗的名子改成touch(養成好習慣,改成英文名,防止各種坑),由于觸摸屏實驗沒有定時器中斷,我們先加一個,先把定時器中斷實驗中HARDWARE/TIMER文件夾復制到touch/HARDWARE

打開keil,先把添加進去的TIMER文件包含了,具體見下圖,都是些搬運代碼的基本操作。


編譯成功,0錯誤0警告。到此,我們的工程準備完畢,這是準備好的工程,點擊直接下載,本工程就是在正點原子觸摸屏實驗的基礎上加了個定時器中斷。

"..\OBJ\TOUCH.axf" - 0 Error(s), 0 Warning(s).
1
跑起來就是這樣,屏幕能顯示,且支持觸摸:

完美。


2.下載LVGL源碼
打開github,國內網絡環境訪問github有時候不太行,如果打不開請直接下載,這是lvgl v8.0.2版本的下載鏈接,
點擊lvgl在github的倉庫,依次點擊master、tags、v8.0.2

切換到V8.0.2分支后,再點code、下載zip

把下載好的lvgl-8.0.2.zip文件解壓,至此,源碼下載完畢


LVGL V8.2.0都有了,為什么你還下載V8.02?

問的好,為了減少徒手擼代碼的時間,我們后續使用另一款軟件,恩智浦的GUI Guider進行界面可視化設計,這個軟件的V1.3.x版本只支持到lvgl V8.0.2。


用這個軟件生成代碼,直接搬運到工程編譯,界面設計嘎嘎快,下圖是演示效果,因為主題不一樣,顏色有點區別。


四、開始移植
1.把源碼搬運到工程文件夾里
在touch目錄下新建一個lvgl文件夾

把lvgl-8.0.2\src文件夾直接復制到新建的lvgl文件夾里,這個src里面就是源碼

把lvgl-8.0.2\examples\porting文件夾復制到新建的lvgl文件夾里,這是移植用的接口

把lvgl-8.0.2目錄下的lvgl.h、lv_conf_template.h、LICENCE.txt、README.md一共4個文件復制到新建的lvgl文件夾里,后面兩個可以不用,不影響移植

現在,touch\lvgl目錄下一共這幾個文件:



搬運好了代碼,我們得給文件改個名字,不然文件內部包含的頭文件名字不一致

把touch\lvgl目錄下的lv_conf_template.h文件名字改成lv_conf.h


把touch\lvgl\porting目錄下所有文件名字的_template刪了,改完之后長這樣


至此,我們的代碼搬運工作結束。

2.把搬運好的代碼添加到keil工程
打開keil,點擊文件擴展按鈕,新建三個組,名字分別為LVGL_SRC、LVGL_PORTING、LVGL_DEMO

接下來就是愉快(無聊)的添加.C文件過程。

先對LVGL_SRC組添加文件,把touch\lvgl\src路徑下的所有.c文件都添加進去,你沒有聽錯,是所有.c文件,包括所有子目錄,可以結合Ctrl+A快捷鍵全選之后再點擊添加,提高效率。

注意,touch\lvgl\src\extra\widgets這個目錄下文件非常分散,要一個一個添加,不要漏了,LVGL_SRC組一共133個.c文件(一個一個數的),不想自己移植可以直接使用我移植好的工程文件,這是移植完的工程文件,適配正點原子精英板。

添加好之后:(一張圖顯示不下)


把touch\lvgl\porting路徑下所有的.c文件添加到LVGL_PORTING組,這個文件少,就三個
LVGL_DEMO組先不管,需要跑DEMO的時候再添加。


接下來包含頭文件。

把touch\lvgl、touch\lvgl\src、touch\lvgl\porting三個路徑包含。


好了,現在需要的庫都添加完了。

3.動手改代碼
先點一下編譯,發現 121 Error(s), 0 Warning(s)。

..\lvgl\src\widgets\../lv_conf_internal.h(41): error:  #5: cannot open source input file "../../lv_conf.h": No such file or directory
  #    include "../../lv_conf.h"                 /*Else assume lv_conf.h is next to the lvgl folder*/
..\lvgl\src\widgets\lv_textarea.c: 0 warnings, 1 error
compiling lv_port_fs.c...
compiling lv_port_indev.c...
"..\OBJ\TOUCH.axf" - 121 Error(s), 0 Warning(s).




編譯器找不到"…/…/lv_conf.h"這個文件,lv_conf.h就在touch\lvgl路徑下,我們剛才把lv_conf.h的路徑包含了,所有不用…/…/,直接在lv_conf_internal.h(41行)刪了就行

把lv_conf.h文件#if 0 改成#if 1

同樣的,把lv_port_disp.c、lv_port_disp.h、lv_port_indev.c、lv_port_indev.c四個文件的#if 0 都改成#if 1 ,這四個文件包含的頭文件名字還需修改,具體看下圖。這四個文件中的兩個.h文件中,路徑為#include "lvgl/lvgl.h"改成#include “lvgl.h”。


把keil改成C99模式,在usart.c的第48行,_sys_exit函數前面加一個void,不然在C99模式下編譯會報錯


//定義_sys_exit()以避免使用半主機模式   
void _sys_exit(int x)
{
        x = x;
}



點擊全部保存,我們先把keil關閉,在touch目錄下,對lvgl文件夾點右鍵-屬性,把只讀的選項取消勾選,應用于子文件夾和文件,避免keil重復編譯,不然每次點擊編譯,所有文件都編譯一遍,等一萬年。

打開keil,為了不讓keil每次都把所有代碼編譯一遍,在設置-Output選項中,不要勾選Create Batch File 創建批處理文件,在設置-Target選項中,不要勾選 使用交叉模塊優化,也不要勾選 use Micro LIB,因為LVGL有個二維碼的控件使用Micro LIB編譯會報錯。


好了,我們現在再次點擊編譯,發現又有6個錯誤。

"..\OBJ\TOUCH.axf" - 6 Error(s), 34 Warning(s).



原來是lv_port_disp.c文件里面有幾個宏定義沒有定義好。



我們在lv_conf.h中定義好屏幕的水平像素和垂直像素大小,順手把LV_COLOR_DEPTH 改成16位(根據實際情況改,如果屏幕是32位色就不用改)

/*====================
   COLOR SETTINGS
*====================*/

/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH     16

#define MY_DISP_HOR_RES     480
#define MY_DISP_VER_RES     320




把lv_port_disp.c的里面的example 2 和3都注釋了,只留example1,點擊編譯,編譯通過,警告不用管,大多是因為定義了函數但是沒有使用而報警告,不影響。


接著在timer.c中的定時器中斷中添加lvgl的心跳接口。

先在timer.c文件頂部包含lvgl.h

然后在定時器中斷中調用lv_tick_inc(1);

//定時器3中斷服務程序
void TIM3_IRQHandler(void)   //TIM3中斷
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //檢查TIM3更新中斷發生與否
                {
                        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中斷標志
                        lv_tick_inc(1);//lvgl的1ms中斷
                }
}



文件改動完畢后添加屏幕顯示和觸控支持

4.添加屏幕的接口
在lv_port_disp.c文件的頂部包含自己的lcd.h,用于調用lcd相關的接口

根據實際情況,在lv_port_disp.c文件中給disp_drv.hor_res和disp_drv.ver_res兩個參數賦值,可以是lcd初始化之后獲取的,也可以是固定的

在disp_flush函數中,注釋原來的for循環,把自己的LCD填充顏色的函數放進去。

至此,我們屏幕顯示的接口移植完畢,簡單吧


5.顯示測試
終于要到跑代碼的環節了,萬事萬物先從點燈開始。

LVGL有一個LED控件,在屏幕上顯示一個LED,可以開關、調亮度等,我們可以先跑起來看看。

在mian.c文件的頂上添加lvgl的頭文件。

#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"




注釋原有觸摸實驗的函數,增加lvgl初始化函數,死循環中放任務處理函數。

        lv_init();                          // lvgl系統初始化
        lv_port_disp_init();  // lvgl顯示接口初始化,放在lv_init()的后面
        lv_port_indev_init(); // lvgl輸入接口初始化,放在lv_init()的后面
         
        while (1)
        {
                lv_task_handler(); // lvgl的事務處理
        }






可以看到,keil報錯(紅色波浪下劃線),因為 lv_port_disp_init和lv_port_indev_init兩個函數找不到,需要我們在lv_port_disp.h和lv_port_indev.h文件中聲明這兩個函數。

lv_port_disp.h添加聲明:

void lv_port_disp_init(void);
1
lv_port_indev.h添加聲明:

void lv_port_indev_init(void);
1
添加完聲明后報錯消失。

接下來我們打開最初從github下載下來,解壓好的lvgl-8.0.2文件夾,在lvgl-8.0.2\examples\widgets\led路徑中打開lv_example_led_1.c文件,復制lv_example_led_1函數放在main.c文件中。

/**
* Create LED's with different brightness and color
*/
void lv_example_led_1(void)
{
    /*Create a LED and switch it OFF*/
    lv_obj_t * led1  = lv_led_create(lv_scr_act());
    lv_obj_align(led1, LV_ALIGN_CENTER, -80, 0);
    lv_led_off(led1);

    /*Copy the previous LED and set a brightness*/
    lv_obj_t * led2  = lv_led_create(lv_scr_act());
    lv_obj_align(led2, LV_ALIGN_CENTER, 0, 0);
    lv_led_set_brightness(led2, 150);
    lv_led_set_color(led2, lv_palette_main(LV_PALETTE_RED));

    /*Copy the previous LED and switch it ON*/
    lv_obj_t * led3  = lv_led_create(lv_scr_act());
    lv_obj_align(led3, LV_ALIGN_CENTER, 80, 0);
    lv_led_on(led3);
}




在mian.c文件的主函數初始化中調用lv_example_led_1,在死循環中調用lvgl的事務處理函數lv_task_handler。

lv_task_handler(); // lvgl的事務處理
1

編譯,下載,點燈成功。



6.添加觸摸的接口
和添加顯示驅動一樣,我們先在lv_port_indev.c文件的頂部包含自己的touch.h,用于調用touch相關的接口和引用相關變量。

由于我們只用到觸摸輸入,為了防止各種誤識別各種坑,先把其它的輸入設備注釋掉。


注釋好之后,lv_port_indev.c文件的touchpad_read函數改成如下,對觸摸芯片返回參數的具體的要求參見2.1小節觸摸代碼中的注釋。

/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;
    /*Save the pressed coordinates and the state*/
    if(tp_dev.sta&TP_PRES_DOWN)
    {
        last_x = tp_dev.x[0];
                last_y = tp_dev.y[0];
                data->point.x = last_x;
                data->point.y = last_y;
                data->state = LV_INDEV_STATE_PR;
    }
    else
    {
        data->point.x = last_x;
                data->point.y = last_y;
                data->state = LV_INDEV_STATE_REL;
    }
//        printf("x %d ,y %d \r\n",data->point.x,data->point.y);
    /*Set the last pressed coordinates*/
//    data->point.x = last_x;
//    data->point.y = last_y;
}


在mian.c文件的主函數的死循環中添加自己的觸摸掃描函數,以不斷更新tp_dev.x[0]和tp_dev.y[0]數值。

        while (1)
        {
                tp_dev.scan(0);           //觸摸掃描
                lv_task_handler(); // lvgl的事務處理
        }


至此,觸摸輸入移植完成,是不是依舊很簡單。



7.使用keypad_encoder DEMO綜合測試
在touch\lvgl目錄下新建demos文件夾,在此文件夾下新建lv_demo_keypad_encoder.c和lv_demo_keypad_encoder.h文件,復制以下代碼到這兩個新建的文件。

.c文件:

/**
* @file lv_demo_keypad_encoder.c
*
*/

/*********************
*      INCLUDES
*********************/
#include "lv_demo_keypad_encoder.h"
#include "lvgl.h"
#if 1

static void selectors_create(lv_obj_t * parent);
static void text_input_create(lv_obj_t * parent);
static void msgbox_create(void);

static void msgbox_event_cb(lv_event_t * e);
static void ta_event_cb(lv_event_t * e);

static lv_group_t*  g;
static lv_obj_t * tv;
static lv_obj_t * t1;
static lv_obj_t * t2;

void lv_demo_keypad_encoder(void)
{
    g = lv_group_create();
    lv_group_set_default(g);

    lv_indev_t* cur_drv = NULL;
    for (;;) {
        cur_drv = lv_indev_get_next(cur_drv);
        if (!cur_drv) {
            break;
        }

        if (cur_drv->driver->type == LV_INDEV_TYPE_KEYPAD) {
            lv_indev_set_group(cur_drv, g);
        }

        if (cur_drv->driver->type == LV_INDEV_TYPE_ENCODER) {
            lv_indev_set_group(cur_drv, g);
        }
    }

    tv = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, LV_DPI_DEF / 3);

    t1 = lv_tabview_add_tab(tv, "Selectors");
    t2 = lv_tabview_add_tab(tv, "Text input");

    selectors_create(t1);
    text_input_create(t2);

    msgbox_create();
}

/**********************
*   STATIC FUNCTIONS
**********************/

static void selectors_create(lv_obj_t * parent)
{
    lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
    lv_obj_set_flex_align(parent, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);

    lv_obj_t * obj;

    obj = lv_table_create(parent);
    lv_table_set_cell_value(obj, 0, 0, "00");
    lv_table_set_cell_value(obj, 0, 1, "01");
    lv_table_set_cell_value(obj, 1, 0, "10");
    lv_table_set_cell_value(obj, 1, 1, "11");
    lv_table_set_cell_value(obj, 2, 0, "20");
    lv_table_set_cell_value(obj, 2, 1, "21");
    lv_table_set_cell_value(obj, 3, 0, "30");
    lv_table_set_cell_value(obj, 3, 1, "31");
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    obj = lv_calendar_create(parent);
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    obj = lv_btnmatrix_create(parent);
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    obj = lv_checkbox_create(parent);
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    obj = lv_slider_create(parent);
    lv_slider_set_range(obj, 0, 10);
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    obj = lv_switch_create(parent);
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    obj = lv_spinbox_create(parent);
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    obj = lv_dropdown_create(parent);
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    obj = lv_roller_create(parent);
    lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS);

    lv_obj_t * list = lv_list_create(parent);
    lv_obj_update_layout(list);
    if(lv_obj_get_height(list) > lv_obj_get_content_height(parent)) {
        lv_obj_set_height(list, lv_obj_get_content_height(parent));
    }

    lv_list_add_btn(list, LV_SYMBOL_OK, "Apply");
    lv_list_add_btn(list, LV_SYMBOL_CLOSE, "Close");
    lv_list_add_btn(list, LV_SYMBOL_EYE_OPEN, "Show");
    lv_list_add_btn(list, LV_SYMBOL_EYE_CLOSE, "Hide");
    lv_list_add_btn(list, LV_SYMBOL_TRASH, "Delete");
    lv_list_add_btn(list, LV_SYMBOL_COPY, "Copy");
    lv_list_add_btn(list, LV_SYMBOL_PASTE, "Paste");
}

static void text_input_create(lv_obj_t * parent)
{
    lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);

    lv_obj_t * ta1 = lv_textarea_create(parent);
    lv_obj_set_width(ta1, LV_PCT(100));
    lv_textarea_set_one_line(ta1, true);
    lv_textarea_set_placeholder_text(ta1, "Click with an encoder to show a keyboard");

    lv_obj_t * ta2 = lv_textarea_create(parent);
    lv_obj_set_width(ta2, LV_PCT(100));
    lv_textarea_set_one_line(ta2, true);
    lv_textarea_set_placeholder_text(ta2, "Type something");

    lv_obj_t *kb = lv_keyboard_create(lv_scr_act());
    lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);

    lv_obj_add_event_cb(ta1, ta_event_cb, LV_EVENT_ALL, kb);
    lv_obj_add_event_cb(ta2, ta_event_cb, LV_EVENT_ALL, kb);
}

static void msgbox_create(void)
{
    static const char * btns[] = {"Ok", "Cancel", ""};
    lv_obj_t * mbox = lv_msgbox_create(NULL, "Hi", "Welcome to the keyboard and encoder demo", btns, false);
    lv_obj_add_event_cb(mbox, msgbox_event_cb, LV_EVENT_ALL, NULL);
    lv_group_focus_obj(lv_msgbox_get_btns(mbox));
    lv_obj_add_state(lv_msgbox_get_btns(mbox), LV_STATE_FOCUS_KEY);
#if LV_EX_MOUSEWHEEL
    lv_group_set_editing(g, true);
#endif
    lv_group_focus_freeze(g, true);

    lv_obj_align(mbox, LV_ALIGN_CENTER, 0, 0);

    lv_obj_t * bg = lv_obj_get_parent(mbox);
    lv_obj_set_style_bg_opa(bg, LV_OPA_70, 0);
    lv_obj_set_style_bg_color(bg, lv_palette_main(LV_PALETTE_GREY), 0);
}

static void msgbox_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * msgbox = lv_event_get_current_target(e);

    if(code == LV_EVENT_VALUE_CHANGED) {
        const char * txt = lv_msgbox_get_active_btn_text(msgbox);
        if(txt) {
            lv_msgbox_close(msgbox);
            lv_group_focus_freeze(g, false);
            lv_group_focus_obj(lv_obj_get_child(t1, 0));
            lv_obj_scroll_to(t1, 0, 0, LV_ANIM_OFF);

        }
    }
}

static void ta_event_cb(lv_event_t * e)
{
    lv_indev_t * indev = lv_indev_get_act();
    if(indev == NULL) return;
    lv_indev_type_t indev_type = lv_indev_get_type(indev);

    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * ta = lv_event_get_target(e);
    lv_obj_t * kb = lv_event_get_user_data(e);

    if(code == LV_EVENT_CLICKED && indev_type == LV_INDEV_TYPE_ENCODER) {
        lv_keyboard_set_textarea(kb, ta);
        lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
        lv_group_focus_obj(kb);
        lv_group_set_editing(lv_obj_get_group(kb), kb);
        lv_obj_set_height(tv, LV_VER_RES / 2);
        lv_obj_align(kb, LV_ALIGN_BOTTOM_MID, 0, 0);
    }

    if(code == LV_EVENT_READY || code == LV_EVENT_CANCEL) {
        lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
        lv_obj_set_height(tv, LV_VER_RES);
    }
}

#endif


.h文件:

/**
* @file lv_demo_keypad_encoder.h
*
*/

#ifndef LV_DEMO_KEYPAD_ENCODER_H
#define LV_DEMO_KEYPAD_ENCODER_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************
*      INCLUDES
*********************/
/*********************
*      DEFINES
*********************/

/**********************
*      TYPEDEFS
**********************/

/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_demo_keypad_encoder(void);

/**********************
*      MACROS
**********************/

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /*LV_DEMO_KEYPAD_ENCODER_H*/
在LVGL_DEMO組中添加lv_demo_keypad_encoder.c,并包含頭文件路徑。

在main中包含頭文件。

#include "lv_demo_keypad_encoder.h"
1
在初始化中調用demo接口,記得把之前的點燈注釋了。

//        lv_example_led_1();//LED控件
        lv_demo_keypad_encoder();
1
2


編譯下載,完美運行,觸摸也好使。

再放一遍之前的圖,這是移植完的工程文件,適配正點原子精英板。

注意:
LVGL在github倉庫有的V8.2的版本,里面有相關的demo,別的demo如果編譯報錯,可以在startup_stm32f10x_hd.s文件中修改這兩個參數來增加棧空間,注意要選擇合適的參數,本工程用的參數如下

Stack_Size      EQU     0x00000400
Heap_Size       EQU     0x00000200
1
2

至此,完成移植,收工。



五、總結
本文介紹了基于stm32f103zet6正點原子精英板移植LVGL的詳細過程,期間小編也遇到各種坑,比如移植完顯示之后屏幕一片漆黑,移植完觸控之后點了沒反應,這些小坑小編就先踩為敬。



當你學會了移植,領悟了精髓,各種處理器,各種屏幕,各種輸入設備都不是問題。

例如如在esp32上跑,下圖是240X240分辨率的屏幕,輸入設備是一個mpu6050(三軸加速度傳感器)。
(下圖的電路參考 稚暉君大佬的HoloCubic)



六.參考文章:
正點原子 LittleVGL開源圖形界面 教程
STM32CubeMX學習筆記(40)——LVGL嵌入式圖形庫使用
【LVGL學習之旅 01】移植LVGL到STM32
lvgl8.x 移植到 stm32f4
GITCODE開源社區

七.代碼匯總:
移植前代碼:在觸摸實驗的基礎上加了定時器中斷
移植后代碼:適配正點原子精英板
LVGL V8.0.2:本套教程使用的LVGL版

lvgl裸機-250102-2131-移植lvgl測試ok.7z

9.62 MB, 下載次數: 0, 下載積分: 黑幣 -5

完整代碼提供

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:875095 發表于 2025-5-3 22:49 | 顯示全部樓層
VERY THX
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
亚洲精品久久久久久下一站| 日韩porn| 成人欧美在线视频| 久久久久久99精品| 第一页在线观看| 中文字幕一区二区三区四区免费看 | 搡老女人一区二区三区视频tv| 国产在线播精品第三| 国产精品伦理| 在线能看的黄色| 99国产精品免费| 日韩精品一区二区三区丰满| 日韩成人在线网站| 欧美日韩免费做爰视频| 视频国产一区| a√免费观看在线网址www| a级片在线观看免费| 中文久久久久久| 国产精品永久在线| 欧美伊人久久久久久久久影院 | 曰本三级在线| 久久久久久久久影视| 久久中文字幕国产| 一区二区三区国产精品| 欧美fxxxxxx另类| 精品自拍一区| 精品偷拍激情视频在线观看| 51妺嘿嘿午夜福利| 一本久道久久综合| 欧美成人性生活| 精品久久久久久久大神国产| 欧美一级视频| 97精品资源在线观看| 写真片福利在线播放| 99精品视频免费观看视频| 日本丰满少妇裸体自慰| 亚洲综合日韩在线| 欧美电影精品一区二区| 国产999精品久久久久久| 国产精品jk白丝蜜臀av小说| 欧美男男激情freegay| 亚洲最大色图| 国产精品视频在| 日韩日韩日韩日韩日韩| 国产成人一区在线| 久久动漫网址| 97caopron在线视频| www.大网伊人| 人人在草线视频在线观看| 亚洲综合久久网| 性一交一黄一片| 日本一区二区在线视频| 97视频com| 日韩女优电影在线观看| 色噜噜狠狠成人中文综合| 国产高清成人在线| 日韩精品国产欧美| 欧美天堂影院| 国模雨婷捆绑高清在线| 国产xxxxx18| 四虎成人免费电影| 欧美精品亚洲精品日韩精品| 蜜桃视频无码区在线观看| 日本一区二区三区视频在线播放| 成人免费在线看片| 久精品免费视频| 欧美一区二区三区免费大片| 亚洲欧美激情在线| 久久国产综合精品| 999国产精品999久久久久久| 欧美少妇激情| 伊人222成人综合网| 中文字幕中文字幕在线中高清免费版 | 91狠狠综合久久久| www.午夜av| 日本黄色片一级片| 精品视频在线观看| 91chinesevideo永久地址| 亚洲愉拍自拍另类高清精品| 91在线视频播放| 黄色精品一区| 三级欧美日韩| 免费成人直播| 国产一区二区三区影视| 精品美女在线观看视频在线观看 | 欧美精品亚洲精品| 国产va免费精品高清在线观看| 影音av资源网| 欧美激情亚洲综合一区| 日韩一区二区三区在线观看| 亚洲欧美一区二区三区久本道91| 日韩av电影天堂| 99国产精品一区二区| 一本一道久久综合狠狠老| 91综合久久爱com| 在线看片福利| 日韩理伦片在线| 国产女主播在线| 日本在线中文电影| 777免费视频| 青娱乐在线视频观看| 天天摸天天操天天爽| 91av福利| 国产高潮av| 春暖花开成人亚洲区| sm性调教片在线观看| 手机av免费在线| 日韩精品黄色| 日韩在线影院| 国产激情欧美| 成人一区视频| 日本午夜精品久久久| 欧美三区美女| 亚洲深爱激情| 国产精品呻吟| 成人av网站免费| 99久久综合国产精品| 成人综合在线观看| 不卡的av在线| 亚洲大片免费看| 亚洲精品乱码久久久久久| 中文字幕国产一区| 久久精品日韩一区二区三区| 一区二区三区欧美日韩| 久久综合88| 欧美特黄一区| 成人精品高清在线| 精品久久久久久久久久久 | 99re在线| 国产精品一区二区三区不卡| 欧美精品尤物在线| caopor在线视频| 成人性生生活性生交12| 国产美女免费无遮挡| 欧美日韩国产黄色| 一区二区三区免费观看视频| 国内爆初菊对白视频| 亚洲国产精品18久久久久久| 人妻视频一区二区三区| 视频一区二区精品的福利| 欧美妇乱xxxxx视频| 情趣视频在线观看| jizzjizz在线观看| 免费在线中文字幕| 日韩精选视频| 哺乳一区二区三区中文视频| 亚洲自啪免费| 亚洲欧美色综合| 亚洲精品资源在线| 久久伊人精品一区二区三区| 秋霞福利视频| 国产精品熟女久久久久久| 自拍偷拍校园春色| 又污又黄的网站| 国产高清大尺度一区二区不卡| 免费a级片网站| 成人av网页| 日本午夜在线| 91麻豆精品一二三区在线| 欧美视频成人| 最新国产の精品合集bt伙计| 精品久久久国产精品999| 中文字幕亚洲欧美在线| 欧美亚州一区二区三区| 欧洲亚洲成人| 青青草超碰在线| 国产电影一区| 亚洲人成精品久久久| 外国成人激情视频| 玖玖精品视频| 成人免费av资源| 91精品国产91久久综合桃花 | 一区二区三区蜜桃网| 在线精品视频视频中文字幕| 久久久免费电影| 亚洲精品欧美日韩| 亚洲 欧美 另类人妖| 手机看片福利视频| 国产成人一区二区在线观看| 任你躁av一区二区三区| 亚洲av无码一区二区二三区| 五月天婷婷丁香| wwwav网站| 免费影视观看网站入口| 金瓶狂野欧美性猛交xxxx| 久久中文亚洲字幕| 国产精品久久久久桃色tv| 日韩一区二区三区免费观看| 久久久精品一品道一区| 精品无人国产偷自产在线| 国产一区高清视频| 成年人午夜免费视频| 久久久久亚洲av无码专区 | 成人综合影院| 欧美色爱综合| 久久国产福利国产秒拍| 亚洲免费在线观看视频| 欧美国产日本在线| 精品国产一区二区三区麻豆小说 | 中文视频在线| 国精产品一区一区三区mba下载| 亚洲最新色图| 欧美日韩国产丝袜另类| 精品国产一区二区三区久久久狼 | 亚洲最大成人av| 又黄又湿又爽又免费又色| 小h片在线观看| 久久99热99| 亚洲精品国产精品国产自| 视频二区一区| 三叶草欧洲码在线| 国产精品呻吟久久| gogogo高清在线观看免费完整版| 欧美在线首页| 欧美视频中文字幕| 久久人人九九| 五月天丁香社区| 青青草国产在线| 国产成人免费精品| 久久久99精品免费观看不卡| 色在人av网站天堂精品| 国产精品人人爽人人爽| 天天干天天爽天天操| 黄色美女网站在线观看| 亚洲素人在线| 五月天久久比比资源色| 91国产精品91| wwwxxxx在线观看| 国产精品你懂的在线观看| 欧美男男gaygay1069| av av在线| 国产黄色大片网站| 性网站在线看| 美女久久久久| 精品日韩美女的视频高清| 91嫩草在线| 国产精品无码专区| 丰满少妇在线观看网站| 精品无人乱码一区二区三区| 91蜜桃视频在线| 亚洲视频欧洲视频| 欧美另类变人与禽xxxxx| 欧美日本黄视频| 国内精品国产三级国产aⅴ久| 国内精品久久久久久久久久| 91九色国产在线播放| 99久久精品费精品国产一区二区| 97色在线播放视频| aaaaa一级片| 三级黄色网址| 久久国产精品久久w女人spa| 欧美高清dvd| 国产又粗又长又爽视频| 欧美特级特黄aaaaaa在线看| 国产成人免费| 亚洲成人久久影院| 日本高清视频一区二区三区| 一区二区精品视频在线观看| 韩国成人漫画| 亚洲欧美日韩久久精品| 好吊色欧美一区二区三区视频| 亚洲天堂一区在线观看| 亚洲精品97久久久babes| 啪啪亚洲精品| 91精品国产色综合久久| 国产深夜男女无套内射| 亚洲综合免费视频| 高清av一区| 天天色天天爱天天射综合| 日韩精品久久久毛片一区二区| 精品人妻一区二区三区含羞草| 国产资源一区| 日本高清视频一区二区| 精品少妇在线视频| 在线看污网站| 伊人激情综合| 欧美日韩一区二区三区四区五区 | 久青草视频在线观看| 26uuu亚洲电影在线观看| 日本一区二区高清| 欧美激情专区| 天堂中文资源在线观看| 亚洲区小说区图片区qvod按摩| 欧美一区二区三区小说| 污色网站在线观看| 亚洲色图狠狠干| 成人免费无遮挡| 夜夜嗨av一区二区三区四季av | 日韩在线观看一区| 欧美亚洲动漫精品| 97成人在线观看视频| 午夜久久久久久久久久| 成午夜精品一区二区三区软件| 日韩一区二区在线观看视频| 岛国av免费在线| 青青操免费在线视频| 欧美家庭影院| 亚洲图片欧美综合| 国产精品区免费视频| 国产高清第一页| 神马久久av| 欧美日韩色一区| 91看片在线免费观看| 麻豆免费网站| 97se亚洲国产综合在线| 日韩电影免费观看在| 国产又白又嫩又爽又黄| 亚洲图片久久| 在线观看91久久久久久| 神马午夜精品91| 国产视频三级在线观看播放| 国产清纯白嫩初高生在线观看91 | 欧美激情在线视频二区| 国产成人在线观看网站| 经典三级久久| 在线影视一区二区三区| 一级一片免费播放| 国产高清在线观看视频| 欧美日韩播放| 大胆人体色综合| 日日夜夜综合网| 男人的天堂免费在线视频| 国产喷白浆一区二区三区| 亚洲乱码一区二区三区三上悠亚 | 成人亚洲网站| 欧美精品一区二区三| 免费看涩涩视频| 男同在线观看| 亚洲黄色小视频| 亚洲老女人av| 欧美69xxxx| 中文在线资源观看网站视频免费不卡 | 精品成a人在线观看| 人妻熟人中文字幕一区二区| 亚洲欧美在线成人| 亚洲激情视频在线观看| 午夜爽爽爽男女免费观看| 日本一区二区三区中文字幕| 日韩欧美国产黄色| www.国产二区| 国产成人精品视频一区| 久久99国产精品免费| 欧美精品一区二区三区四区五区| 人人插人人射| 成人av网站免费观看| av动漫在线播放| 一区二区三区四区在线免费视频| 亚洲人成亚洲人成在线观看图片| 国产综合免费视频| 天天色av.com| 日本一区二区综合亚洲| 日韩欧美精品在线观看视频| 成人在线免费公开观看视频| 日本高清不卡一区| 国产美女免费网站| 精品视频91| 久久久亚洲影院| 亚洲av少妇一区二区在线观看| 国产精品一区毛片| 国内成+人亚洲| 成人拍拍拍免费视频网站| 日韩理论片在线| 中文字幕99页| 欧美videos粗暴| 欧美老女人在线视频| 熟妇人妻中文av无码| 精品一区精品二区高清| www.黄色网址.com| 麻豆av资源| 亚洲乱码日产精品bd| 无码国产精品一区二区高潮| 欧美特大特白屁股xxxx| 日韩视频精品在线| 好男人www在线视频| 久久福利视频一区二区| 97干在线视频| 三上悠亚一区| 欧美日韩在线视频一区二区| www.涩涩爱| 狠狠做深爱婷婷综合一区| 久久99视频精品| 天天干天天色天天| 国产传媒欧美日韩成人| 久草资源站在线观看| sis001亚洲原创区| 中文字幕免费国产精品| 日韩一级片免费在线观看| 国内精品国产三级国产a久久| 久久av免费一区| 在线手机福利影院| 日韩理论片在线| 一区二区三区伦理片| 日日夜夜人人| 国产精品亚洲一区二区三区在线 | 精品一区二区三区在线| 99蜜桃在线观看免费视频网站| jizzjizzjizz在线观看| 国产亚洲女人久久久久毛片| 国产69精品久久久久久久| 在线免费观看污|