“ 可以應用于嵌入式的GUI有很多,除了上一篇文章介紹的emWin,還有周立功的AWTK、Microsoft的GUIX以及TouchGFX等,本篇文章将介紹一種輕量級的GUI:LittleVGL”
硬體環境:STM32F429IGT6
軟體環境:STM32CubeMX v5.5.0
HAL庫版本:STM32CubeF4 Firmware Package V1.24.0
LittleVGL版本:v7.9.0
01
LittleVGL簡介
LittlevGL簡稱LVGL, 是一個使用C編寫的開源免費的GUI,可以應用在嵌入式裝置中。使用者可以從官網或者Github上下載下傳。
源碼:https://github.com/littlevgl/lvgl
其特點如下:
- 強大的子產品化程式設計能力,能夠建立包括按鍵,圖示,清單,滑塊,圖檔在内的功能
- 先進的圖形界面,包含動畫,抗撕裂,可調明暗度,柔和縮放等功能。
- 支援不同的輸入裝置包括鍵盤,滑鼠,觸摸屏,編碼器等。
- UTF-8編碼多語言支援。
- 多顯示器支援,可以同時使用多個TFT或單色顯示。
- 完整的可自定義圖形元素。
- 不限制晶片類型,硬體可無限制地在各種晶片上使用LVGL。
- 可自定義記憶體調用。
- 支援但不強制使用作業系統,外部存儲或GPU。
- 使用單一架構緩存支援複雜的圖形界面。
- 整個庫用C編寫最大程度地提高相容性。
對硬體的要求:
- 16,32或64位微處理器或晶片
- 建議使用大于16MHz的時脈速度
- 閃存/ROM:對于重要部件要求大于64KB(建議大于180KB)
- RAM:
- 靜态RAM使用:根據不同功能與對象2KB以内不等。
- 棧:大于2KB(建議大于8KB)。
- 堆:大于2KB(如果使用多個對象建議大于16KB)用lv_conf.h庫中的LV_MEM_SIZE來設定。
- 顯示緩存:大于“水準分辨率”像素值(建議大于10*“水準分辨率”像素值)。
02
移植前準備
1.底層驅動
首先完成硬體的底層驅動,包括LCD顯示,觸摸屏等。本例以STM32F429驅動7寸RGB接口屏為例,底層程式可參考之前的文章《STM32CubeMX之LTDC接口》
2.源碼下載下傳
下載下傳源碼和例程。
源碼:https://github.com/littlevgl/lvgl
例程:https://github.com/littlevgl/lv_examples
将下載下傳并解壓後的兩個檔案夾複制到工程目錄,如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CN3ATMxkTM2IGOyI2MjNGNzYzX4MzM1ATM3EzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
03
移植
1.添加檔案到工程
首先在工程目錄建立三個組:
lvgl/port下的兩個檔案。
首先将lvgl/src目錄及其子目錄下的全部檔案添加進去。(檔案較多就不展開了)
将示範例程中的其中一個添加到工程中,這裡選擇了lv_demo_widgets。
将lvgl/example/porting目錄下的兩組.c和.h檔案添加到lvgl/port下(這裡重命名了一下)。
2.接口程式編寫
lv_port_disp為顯示接口檔案,lv_port_indev為輸入接口(這裡是觸摸屏)檔案。
lv_port_disp檔案中需要修改兩個函數,lv_port_disp_init和disp_flush。這兩個函數的主要功能是完成顯示緩沖初始化,以及将顯示緩存中的内容顯示到LCD上。需要使用者根據顯示屏接口的不同自己完成相關程式。
//顯示接口初始化
void lv_port_disp_init(void)
{
static lv_disp_buf_t
//顯示緩沖區初始化,因為使用了SDRAM,是以可以設定為雙緩沖區
lv_disp_buf_init(&disp_buf, color_buf, color_buf2, COLOR_BUF_SIZE);
lv_disp_drv_t
lv_disp_drv_init(&disp_drv);
//螢幕分辨率
800;
480;
//注冊顯示驅動回調
disp_drv.flush_cb = disp_flush;
//注冊顯示緩沖區
disp_drv.buffer = &disp_buf;
#if
disp_drv.gpu_blend = gpu_blend;
disp_drv.gpu_fill = gpu_fill;
#endif
//注冊顯示驅動
lv_disp_drv_register(&disp_drv);
}
//把指定區域的顯示緩沖區内容寫入到螢幕上,使用DMA2D完成這個操作
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t
{
//把指定區域的顯示緩沖區内容寫入到螢幕
uint16_t*)color_p);
lv_disp_flush_ready(disp_drv);
}
touchpad_init和touchpad_read:
itialize your touchpad*/static void touchpad_init(void){/*Your code comes here*/ TOUCH_Init();}
/* Will be called by the library to read the touchpad */static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t{static lv_coord_t last_x = 0;static lv_coord_t last_y = 0;
/*Save the pressed coordinates and the state*/// if(touchpad_is_pressed()) {// touchpad_get_xy(&last_x, &last_y);// data->state = LV_INDEV_STATE_PR;// } else {// data->state = LV_INDEV_STATE_REL;// }
// /*Set the last pressed coordinates*/// data->point.x = last_x;// data->point.y = last_y;if(TOUCH_ReadXY(&last_x, &last_y)) { data->state = LV_INDEV_STATE_PR; }else { data->state = LV_INDEV_STATE_REL; } data->point.x = last_x; data->point.y = last_y;/*Return `false` because we are not buffering and no more data to read*/return false;}
3.頭檔案配置
接下來将源碼目錄下的lv_conf_template.h檔案包含到工程中,這裡重命名為lv_conf.h。
該檔案中包含了一些lvgl的基本配置,包括分辨率以及顔色模式等。
将示範例程目錄下的lv_ex_conf_template.h包含到工程中,這裡重命名為lv_ex_conf.h。該檔案主要是選擇使能哪一個示範例程。
4.其它
滴答定時器中斷中添加lvgl的時基函數:lv_tick_inc(1)
接下來在主函數中初始化以及demo調用的程式,lvgl初始化前需要完成觸摸屏和SDRAM等的初始化。需要注意的是lv_task_handler();函數需要循環調用,以便lvgl完成自身任務的調用。
另外移植過程中需要注意一些頭檔案的包含路徑,以及一些檔案開頭的#if 0改為#if 1等細節問題。
到此程式移植完成,編譯後運作檢視效果:
04
總結
可以看到,移植過程并不複雜,而且LVGL的控件豐富,相比于emWin接近于windows XP的預設主題,LVGL更接近于Android,界面美觀。但各種輔助工具不如emWin多,使用起來稍顯複雜。
歡迎關注公衆号"嵌入式技術開發",大家可以背景給我留言溝通交流。如果覺得該公衆号對你有所幫助,也歡迎推薦分享給其他人。