<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何將lvgl粗略的移植到stm32f429上?

冬至子 ? 來源:麥芽二糖 ? 作者:麥芽二糖 ? 2023-10-23 16:40 ? 次閱讀

一、

上周將lvgl粗略的移植到stm32f429上,界面刷新問題沒有好好處理,看著非常非??D,今天初步處理了這個問題,效果還算可以了,后邊應該是可以更進一步優化。我們先在裸機上移植,以后移植到OS上。移植的視頻效果在結尾處。

二、移植步驟

1、提前準備一個移植好LCD、觸摸驅動的工程,并修改工程名。

2、獲取lvgl圖形庫源碼。

3、將源碼添加到提前準備好的工程。

4、修改配置lv_conf.h文件。

5、調用lvgl的初始化程序 lv_init()。

6、在lvgl中注冊顯示和輸入設備驅動程序。

7、在中斷服務函數中調用lv_tick_inc(x)以告知lvgl經過的時間。

8、每隔幾毫秒調用lv_timer_handle()來處理lvgl相關的任務。

三、提前準備一個移植好LCD、觸摸驅動的工程,并修改工程名

我的板子是用的野火的,所以我直接找一個野火的例程進行修改,就用這個觸摸屏的例程。

圖片

根據個人喜好更改文件夾名以及工程名,工程名需要是英文,這些我在這里不多說了,自己修改就好,當然也可以不修改。

修改工程的時候建議將Browse information勾上,勾上以后函數跳轉很方便,不過勾上以后第一次編譯程序會很慢,這個也看個人需求。

圖片

四、獲取lvgl源碼

新建文件夾使用git獲取源碼。

圖片

獲取成功后可以看到一個lvgl的文件夾,這就是源碼了。

圖片

不熟悉git的結尾處我也會提供一份源碼。

五、將源碼添加到提前準備好的工程,修改配置lv_conf.h文件

到目前我們準備好lvgl的源碼以及準備移植的工程。

圖片

1、將lvgl文件夾直接放到lvgl_porting中,然后在新建一個lvgl_app文件夾,后邊自己的lvgl應用程序可以放這里。

圖片

2、進入lvgl這個文件里可以看到以下文件

圖片

3、進入src文件夾后,按照下圖文件夾名字在keil工程中添加目錄。

圖片

圖片

4、然后除了以下目錄下文件不添加,其他c文件全部添加,注意有的目錄下還有文件夾,文件夾里的c文件也要添加,不要漏了。

圖片

圖片

圖片

gpu暫時也不需要添加。

5、將lv_conf_template.h復制到上一層目錄,并修改lv_conf_template.h為lv_conf.h,這個是一定要修改的,官方介紹的也是這樣,工程里也是使用的lv_conf.h的頭文件。

圖片

6、打開改名后的lv_conf.h,使能文件。同時可以看到這里配置的色彩深度是16位的,對應RGB565格式,一會兒我們LCD屏也是配置RGB565使用。其他配置暫時先不用改。

圖片

7、將lvgl->examples->porting中選中的文件復制到與lv_conf.h文件同一目錄下,并把template字眼去掉。分別為顯示設備的驅動接口和輸入設備的接口,我們一會兒完善。

圖片

圖片

8、在keil工程新建兩個目錄lvgl_porting,lvgl_demo。lvgl_porting放如下三個文件。lvgl_demo一會兒放例程。

圖片

9、添加所有目錄下的頭文件

圖片

10、然后開始編譯一下工程,如果你C文件添加正確,以及頭文件目錄配置正確,這個時候已經可以編譯通過了。如果這里編譯報錯可以參考我結尾處附上的工程文件進行參考。

圖片

六、按照LVGL的運行需求修改工程

Basically, every modern controller which is able to drive a display is suitable to run LVGL. The minimal requirements are:

  • 16, 32 or 64 bit microcontroller or processor
  • 16 MHz clock speed is recommended

  • Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended)
  • RAM:
    • Static RAM usage: ~2 kB depending on the used features and object types
    • Stack: > 2kB (> 8 kB is recommended)
    • Dynamic data (heap): > 4 KB (> 32 kB is recommended if using several objects). Set by LV_MEM_SIZE in lv_conf.h .
    • Display buffer: > "Horizontal resolution" pixels (> 10 × "Horizontal resolution" is recommended)
    • One frame buffer in the MCU or in an external display controller
  • C99 or newer compiler
  • Basic C (or C++) knowledge: pointers, structs, callbacks.

1、設置堆棧大小

圖片

2、配置C99模式

圖片

七、在lvgl中注冊顯示驅動程序

到目前為止我們基本沒修改任何代碼,只是使能了一些文件的宏,同時最繁瑣的事情我們已經做完了。接下來完善注冊顯示接口驅動以及設備輸入接口驅動。

顯示驅動程序

  • 定義一個或者兩個繪制緩沖區,用來渲染屏幕內容
  • 注冊顯示驅動
  • 補充刷新界面的回調函數

定義緩沖區流程

通過lv_disp_draw_buf_t 變量初始化,如下所示:

/* 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*/

注意,lv_disp_draw_buf_t 需要是靜態的、全局的或動態分配的,而不是超出范圍時銷毀的局部變量。

如上所示,有三個示例。繪制緩沖區可以比屏幕小,如果刷新整個界面,需要刷新幾次就好了,如果只有小區域發生變化(如只按下按鈕),則只刷新該區域。官方建議緩沖區的大小至少為屏幕寬度的1/10。

如果使用 一個緩沖區 ,LVGL 將屏幕內容繪制到該繪制緩沖區中并將其發送到顯示器。 這樣 LVGL 需要等到緩沖區的內容發送到顯示器,然后再在其中繪制新內容。

如果使用 兩個緩沖區 ,LVGL 可以繪制到一個緩沖區中,而另一個緩沖區的內容被發送到后臺顯示。應使用 DMA 或其他硬件將數據傳輸到顯示器,讓 MCU 同時繪制。這樣,顯示的渲染和刷新變得并行。

注冊顯示驅動流程

其實打開lv_port_disp.c文件中描述的比較清楚如下代碼。

/*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/


    static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/


    /*Set up the functions to access to your display*/


    /*Set the resolution of the display*/
    disp_drv.hor_res = 480;
    disp_drv.ver_res = 320;


    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;


    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_1;


    /*Required for Example 3)*/
    //disp_drv.full_refresh = 1


    /* Fill a memory array with a color if you have GPU.
     * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
     * But if you have a different GPU you can use with this callback.*/
    //disp_drv.gpu_fill_cb = gpu_fill;


    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);

注意,lv_disp_drv_t 也需要是靜態的、全局的或動態分配的,而不是超出范圍時銷毀的局部變量。

  • 配置屏幕的分辨率
  • 指定回調函數
  • 指向緩沖區
  • 注冊顯示驅動

實際操作

1、將lv_port_disp.c和lv_port_disp.h文件宏都打開,并修改.c文件中相應頭文件名字,將template去掉。

圖片

2、找到lv_port_disp_init()初始化函數,我們使用第一種方法,并修改屏幕寬度,我的屏幕是800*480的,所以我改為800。

圖片

如果你有外擴sram或者sdram這里可以配置與屏幕一樣大。

我這里有sdram我就放到sdram中了。

圖片

3、修改分辨率

圖片

回調函數disp_flush完善

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
  • *area中有繪制區域的起始xy地址和結束xy地址
  • *color_p,存放著從起始xy地址到結束xy地址的每一個像素顏色

知道了這兩個我們使用到參數后,我們需要編寫一個刷新函數LCD_FillRect_color()的。因為我們使用的這個工程已經配置好了DMA2D,我們直接用DMA2D傳輸,函數實現如下。

void LCD_FillRect_Color(int16_t x1, int16_t y1, int16_t x2, int16_t y2, lv_color_t *color)
{
    uint32_t dst_addr = 0;//需要更新顯存中內容的起始地址

    dst_addr = Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + 2*(800*y1 + x1);//計算需要更新的目標地址 800是屏幕寬度,2是每個像素占2個字節

    /* DMA2D Config */
    DMA2D- >CR      = 0x00000000UL; //配置DMA2D的傳輸模式為 內存到內存
    DMA2D- >FGMAR   = (uint32_t)color; //拷貝的源地址,繪制緩存區
    DMA2D- >OMAR    = (uint32_t)dst_addr; //拷貝的目標地址,即顯存位置
    DMA2D- >FGOR    = 0; //源地址的偏移地址,它被添加到每一行的末尾以確定下一行的起始地址
    DMA2D- >OOR     = (800 - (x2 - x1 +1)); //目標地址的偏移地址,它被添加到每一行的末尾以確定下一行的起始地址
    DMA2D- >FGPFCCR = LTDC_PIXEL_FORMAT_RGB565;  //設置顏色格式;
    DMA2D- >NLR     = (uint32_t)((x2 - x1 + 1) < < 16) | (uint16_t)(y2 - y1 + 1);// 設置拷貝數據的長度和寬度

    /* Start */
    DMA2D- >CR |= DMA2D_CR_START;

    while(DMA2D- >CR & DMA2D_CR_START) {}   
}

將我們準備好的繪制函數LCD_FillRect_Color添加進來。

/*Flush the content of the internal buffer the specific area on the display
 *You can use DMA or any hardware acceleration to do this operation in the background but
 *'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
    LCD_FillRect_Color(area- >x1, area- >y1, area- >x2, area- >y2, (lv_color_t *)color_p);
    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

回調函數完事兒。

顯示屏移植已經完成了,可以添加一個demo先點亮屏幕。

添加demo并修改main()函數

在main.c文件中添加頭文件

#include "./lvgl.h"
#include "../lv_port_disp.h"
#include "lv_demo_widgets.h"

修改顯示屏配置

圖片

調用如下初始化函數

圖片

添加demo文件,路徑:lvgldemoswidgets,并添加頭文件路徑。

圖片

進入lv_demo_widgets.c文件中,使能宏

圖片

將此處均設置為1

圖片

這個時候編譯不報錯是正確的。

八、在中斷服務函數中調用lv_tick_inc(x)以告知lvgl經過的時間

圖片

需要添加頭文件

#include "../lvgl/src/hal/lv_hal_tick.h"

九、每隔幾毫秒調用lv_timer_handle()來處理lvgl相關的任務

圖片

操作到現在,可以編譯下載測試了。

十、在lvgl中注冊輸入設備驅動程序

輸入設備可以是觸摸板、鼠標、鍵盤、編碼器、按鍵,我們使用觸摸板。

打開lv_port_indev.c文件,只留下觸摸板相關程序,其他程序全部刪除。

圖片

我們只需要把touchpad_read回調函數補充完整即可。

主要是提供當前的按壓狀態,釋放還是壓下,以及按下時的坐標即可,這里自己添加就好。

圖片

然后將lv_port_indev_init()添加到main()函數中即可。

到此已經移植完成了,剩下就是優化刷新程序以及lvgl控件的應用了。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • RGB
    RGB
    +關注

    關注

    4

    文章

    774

    瀏覽量

    57747
  • LCD觸摸屏
    +關注

    關注

    0

    文章

    11

    瀏覽量

    6664
  • STM32F429
    +關注

    關注

    0

    文章

    40

    瀏覽量

    10394
  • 裸機
    +關注

    關注

    0

    文章

    37

    瀏覽量

    6190
  • LVGL
    +關注

    關注

    0

    文章

    76

    瀏覽量

    2597
收藏 人收藏

    評論

    相關推薦

    STM32F429移植FreeRTOS

    STM32F429移植FreeRTOS一、環境Win10、Keil uVision5、STM32CubeMX、STM32F429IGT6二、準備工作2.1創建基于HAL庫的
    發表于 08-05 07:47

    如何利用STM32CubeMX移植LWIPSTM32F429開發板中

    STM32F429開發板中。LWIP移植的流程如下示:#mermaid-svg-9tEdrCmYirruZDai .label{font-family:'trebuchet ms', verdana
    發表于 08-11 08:27

    把SQLite移植STM32F429

    不知道自己是哪根筋搭錯了還是怎么回事,一時心血來潮,突發奇想,決定把SQLite移植STM32F429。在此記錄一下過程,也確認一下此事可行。先說一下結果:
    發表于 08-20 07:44

    STM32F429是怎樣移植TouchGFXRT-Thread系統

    如何去實現GUI和硬件的雙向交互呢?STM32F429是怎樣移植TouchGFXRT-Thread系統的?
    發表于 10-18 07:36

    STM32F429是如何移植FreeRTOS的

    STM32F429是如何移植FreeRTOS的?有哪些步驟?怎樣去獲取FreeRTOS源碼呢?
    發表于 10-22 08:33

    怎樣ThreadX GUIX移植STM32F429(MDK AC6)上去

    怎樣ThreadX GUIX移植STM32F429(MDK AC6)上去?有哪些注意事項?
    發表于 11-08 07:56

    怎樣ThreadX GUIX移植STM32F429(MDK AC5)上去呢

    怎樣ThreadX GUIX移植STM32F429(MDK AC5)上去呢?移植過程是怎樣的?有哪些注意事項?
    發表于 11-08 08:27

    MicroPython移植野火STM32F429開發板的過程

    最近通過參考網上的文章,成功MicroPython移植野火STM32F429開發板,給大家分享一下自己的
    發表于 02-09 06:16

    如何利用STM32CubeMX移植LWIPSTM32F429開發板中

    LWIPSTM32F429開發板中。LWIP移植的流程如下示:1、原理圖分析本文使用的硬件開發環境是STM32F407、LAN8720和RJ45(內置網絡變壓器),其連接原理圖如下圖
    發表于 02-21 06:24

    stm32f429怎么移植linux系統?

    stm32f429怎么移植linux系統,不用a系列芯片
    發表于 09-21 06:25

    STM32F429開發板用戶手冊】第1章 初學STM32F429的準備工作

    STM32F429開發板用戶手冊】第1章 初學STM32F429的準備工作
    發表于 12-04 13:51 ?20次下載
    【<b class='flag-5'>STM32F429</b>開發板用戶手冊】第1章 初學<b class='flag-5'>STM32F429</b>的準備工作

    STM32F429開發板用戶手冊】第8章 STM32F429的終極調試組件Event Recorder

    STM32F429開發板用戶手冊】第8章 STM32F429的終極調試組件Event Recorder
    發表于 12-04 14:06 ?16次下載
    【<b class='flag-5'>STM32F429</b>開發板用戶手冊】第8章 <b class='flag-5'>STM32F429</b>的終極調試組件Event Recorder

    [長文干貨]MicroPython移植到野火STM32F429開發板

    [長文干貨]MicroPython移植到野火STM32F429開發板
    發表于 12-05 18:51 ?27次下載
    [長文干貨]MicroPython<b class='flag-5'>移植</b>到野火<b class='flag-5'>STM32F429</b>開發板

    秉火stm32f429移植u-boot

    秉火stm32f429移植u-boot硬件平臺: 使用秉火stm32f429的核心板,搭配挑戰者野火stm32的底板。MCU: stm32
    發表于 12-07 13:21 ?20次下載
    秉火<b class='flag-5'>stm32f429</b><b class='flag-5'>移植</b>u-boot

    AN4658_從STM32F429、439系列到STM32F446系列的應用移植

    AN4658_從STM32F429、439系列到STM32F446系列的應用移植
    發表于 11-21 08:11 ?0次下載
    AN4658_從<b class='flag-5'>STM32F429</b>、439系列到<b class='flag-5'>STM32</b>F446系列的應用<b class='flag-5'>移植</b>
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>