本文來源電子發(fā)燒友社區(qū),作者:李先生, 帖子地址:https://bbs.elecfans.com/jishu_2307453_1_1.html
前言
本開發(fā)板帶一個135x130的TFT屏幕,使用的控制器是ST7735,SPI接口,16位。前兩篇已經(jīng)進行了屏幕的顯示測試,具備了移植GUI的條件,本篇我們移植LVGL。
參考
準備代碼
cd niobeu4_src/vendor/openvalley/niobeu4/demo/107_hdf_spi/
git clonehttps://github.com/lvgl/lvgl.git
移植概述
配置文件lv_conf.h
復(fù)制
lvgl/lv_conf_template.h
為
lvgl/lv_conf.h
將#if 0改為1,即直接#include “l(fā)v_conf.h”
將lv_conf.h添加到工程頭文件包含路徑。
即修改
vendor/openvalley/niobeu4/demo/107_hdf_spi/BUILD.gn
include_dirs = [
下添加一行"lvgl/",
底層驅(qū)動模板
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/examples/porting
下有對應(yīng)的模板文件,分別是顯示,文件系統(tǒng)和輸入設(shè)備的驅(qū)動模板。
lv_port_disp_template.c/h
lv_port_fs_template.c/h
lv_port_indev_template.c/h
暫時只移植顯示,所以復(fù)制lv_port_disp_template.c/h
到vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl下改名字為
lv_port_disp.c/h
將.c和.h里面的#if 0改為1
.c中#include "lv_port_disp_template.h"改為#include "lv_port_disp.h"
HAL層模板
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/src/hal
下
我們直接使用不修改
lv_hal_disp.c/h
lv_hal_indev.c/h
lv_hal_tick.c/h
lv_hal.h
添加文件
見工程配置,在gn文件中添加源碼。
需要移植的代碼
移植比較簡單,直接使用底層驅(qū)動模板根據(jù)實際實現(xiàn)修改lv_port_disp.c,并配置lv_conf.h即可。
頭文件包含模式
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_port_disp.h中
#define LV_LVGL_H_INCLUDE_SIMPLE 1
這樣需要將lv_conf.h所在路徑配置為工程頭文件包含路徑。
代碼中直接#include "lvgl.h"
否則是#include "../../lvgl.h"
分辨率配置
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_port_disp.h中
#define MY_DISP_HOR_RES 135
#define MY_DISP_VER_RES 130
初始化
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_port_disp.c中
實現(xiàn)disp_init
即調(diào)用自己的初始化函數(shù)LcdInit
緩沖區(qū)
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_port_disp.c中
lv_port_disp_init
注釋掉/* Example for 2) */
/* Example for 3) also set disp_drv.full_refresh = 1 below*/對應(yīng)的代碼
使用/* Example for 1) */
lv_port_disp_init
改函數(shù)調(diào)用disp_init
調(diào)用LcdInit實現(xiàn)初始化
刷新顯示
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_port_disp.c中
disp_flush
/*put_px(x, y,color_p)/改為
lcd_draw_point(x,y,color_p->full);
并調(diào)用LcdPush();
/*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)
{
if(disp_flush_enabled) {
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
int32_t x;
int32_t y;
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
/*Put a pixel to the display. For example:*/
/*put_px(x, y, *color_p)*/
lcd_draw_point(x,y,color_p->full);
color_p++;
}
}
LcdPush();
}
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
顏色深度
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_conf.h中
#define LV_COLOR_DEPTH 16
typedef LV_CONCAT3(lv_color, LV_COLOR_DEPTH, _t) lv_color_t;
則lv_color_t類型為lv_color_16_t
堆大小配置
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_conf.h中
#define LV_MEM_SIZE (10U * 1024U) /[bytes]/
按需提供堆大小,過大可能編譯不過,過小可能影響創(chuàng)建對象。
時間滴答
如果LV_TICK_CUSTOM為1則需要用戶提供相關(guān)接口
LV_TICK_CUSTOM_SYS_TIME_EXPR用于獲取當前毫秒值
和頭文件LV_TICK_CUSTOM_INCLUDE
在lv_conf.h中指定
否則使用lvgl/src/hal/lv_hal_tick.c的實現(xiàn)
每隔x毫秒調(diào)用lv_tick_inc(x),使用內(nèi)部計數(shù)器定時。
周期調(diào)用lv_tick_inc更新時間滴答,比如專門在某個定時線程中
while(1)
{
LOS_Msleep(5); /*Sleep for 5 millisecond*/
lv_tick_inc(5);
lv_timer_handler();
}
日志
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_conf.h中
#define LV_USE_LOG 0
改為
#define LV_USE_LOG 1使能日志
#define LV_LOG_LEVEL LV_LOG_LEVEL_TRACE設(shè)置日志,等級
LV_LOG_LEVEL_TRACE表示所有信息都打印
如果#define LV_LOG_PRINTF 0
則需要調(diào)用設(shè)置lv_log_register_print_cb()打印函數(shù)
否則使用printf,我們這里實現(xiàn)了printf所以設(shè)置為1
#define LV_LOG_USE_TIMESTAMP 1
使能打印時間
其他的模塊打印使能
#define LV_LOG_TRACE_MEM 1
#define LV_LOG_TRACE_TIMER 1
#define LV_LOG_TRACE_INDEV 1
#define LV_LOG_TRACE_DISP_REFR 1
#define LV_LOG_TRACE_EVENT 1
#define LV_LOG_TRACE_OBJ_CREATE 1
#define LV_LOG_TRACE_LAYOUT 1
#define LV_LOG_TRACE_ANIM 1
字體配置
vendor/openvalley/niobeu4/demo/107_hdf_spi/lvgl/lv_conf.h
中按需使能對應(yīng)的字體,如果有對應(yīng)編譯錯誤信息根據(jù)提示使能
#define LV_FONT_MONTSERRAT_12 1
#define LV_FONT_MONTSERRAT_14 1
#define LV_FONT_MONTSERRAT_16 1
工程配置
vendor/openvalley/niobeu4/demo/107_hdf_spi/BUILD.gn中添加源碼和頭文件包含路徑。
kernel_module(module_name){
sources = [
"spi_example.c",
"st7735s.c",
"lvgl/src/core/lv_disp.c",
"lvgl/src/core/lv_event.c",
"lvgl/src/core/lv_group.c",
"lvgl/src/core/lv_indev_scroll.c",
"lvgl/src/core/lv_indev.c",
"lvgl/src/core/lv_obj_class.c",
"lvgl/src/core/lv_obj_draw.c",
"lvgl/src/core/lv_obj_pos.c",
"lvgl/src/core/lv_obj_scroll.c",
"lvgl/src/core/lv_obj_style_gen.c",
"lvgl/src/core/lv_obj_style.c",
"lvgl/src/core/lv_obj_tree.c",
"lvgl/src/core/lv_obj.c",
"lvgl/src/core/lv_refr.c",
"lvgl/src/core/lv_theme.c",
"lvgl/src/draw/sw/lv_draw_sw_arc.c",
"lvgl/src/draw/sw/lv_draw_sw_blend.c",
"lvgl/src/draw/sw/lv_draw_sw_dither.c",
"lvgl/src/draw/sw/lv_draw_sw_gradient.c",
"lvgl/src/draw/sw/lv_draw_sw_img.c",
"lvgl/src/draw/sw/lv_draw_sw_layer.c",
"lvgl/src/draw/sw/lv_draw_sw_letter.c",
"lvgl/src/draw/sw/lv_draw_sw_line.c",
"lvgl/src/draw/sw/lv_draw_sw_polygon.c",
"lvgl/src/draw/sw/lv_draw_sw_rect.c",
"lvgl/src/draw/sw/lv_draw_sw_transform.c",
"lvgl/src/draw/sw/lv_draw_sw.c",
"lvgl/src/draw/lv_draw_arc.c",
"lvgl/src/draw/lv_draw_img.c",
"lvgl/src/draw/lv_draw_label.c",
"lvgl/src/draw/lv_draw_layer.c",
"lvgl/src/draw/lv_draw_line.c",
"lvgl/src/draw/lv_draw_mask.c",
"lvgl/src/draw/lv_draw_rect.c",
"lvgl/src/draw/lv_draw_transform.c",
"lvgl/src/draw/lv_draw_triangle.c",
"lvgl/src/draw/lv_draw.c",
"lvgl/src/draw/lv_img_buf.c",
"lvgl/src/draw/lv_img_cache.c",
"lvgl/src/draw/lv_img_decoder.c",
"lvgl/src/font/lv_font_fmt_txt.c",
"lvgl/src/font/lv_font.c",
"lvgl/src/font/lv_font_montserrat_12.c",
"lvgl/src/font/lv_font_montserrat_14.c",
"lvgl/src/font/lv_font_montserrat_16.c",
"lvgl/src/hal/lv_hal_disp.c",
"lvgl/src/hal/lv_hal_indev.c",
"lvgl/src/hal/lv_hal_tick.c",
"lvgl/src/layouts/flex/lv_flex.c",
"lvgl/src/layouts/grid/lv_grid.c",
"lvgl/src/libs/bmp/lv_bmp.c",
"lvgl/src/libs/ffmpeg/lv_ffmpeg.c",
"lvgl/src/libs/freetype/lv_freetype.c",
"lvgl/src/libs/fsdrv/lv_fs_fatfs.c",
"lvgl/src/libs/fsdrv/lv_fs_posix.c",
"lvgl/src/libs/fsdrv/lv_fs_stdio.c",
"lvgl/src/libs/fsdrv/lv_fs_win32.c",
"lvgl/src/libs/gif/gifdec.c",
"lvgl/src/libs/gif/lv_gif.c",
"lvgl/src/libs/png/lodepng.c",
"lvgl/src/libs/png/lv_png.c",
"lvgl/src/libs/qrcode/lv_qrcode.c",
"lvgl/src/libs/qrcode/qrcodegen.c",
"lvgl/src/libs/rlottie/lv_rlottie.c",
"lvgl/src/libs/sjpg/lv_sjpg.c",
"lvgl/src/libs/sjpg/tjpgd.c",
"lvgl/src/misc/lv_anim_timeline.c",
"lvgl/src/misc/lv_anim.c",
"lvgl/src/misc/lv_area.c",
"lvgl/src/misc/lv_async.c",
"lvgl/src/misc/lv_bidi.c",
"lvgl/src/misc/lv_color.c",
"lvgl/src/misc/lv_fs.c",
"lvgl/src/misc/lv_gc.c",
"lvgl/src/misc/lv_ll.c",
"lvgl/src/misc/lv_log.c",
"lvgl/src/misc/lv_lru.c",
"lvgl/src/misc/lv_malloc_builtin.c",
"lvgl/src/misc/lv_math.c",
"lvgl/src/misc/lv_mem.c",
"lvgl/src/misc/lv_memcpy_builtin.c",
"lvgl/src/misc/lv_printf.c",
"lvgl/src/misc/lv_style_gen.c",
"lvgl/src/misc/lv_style.c",
"lvgl/src/misc/lv_templ.c",
"lvgl/src/misc/lv_timer.c",
"lvgl/src/misc/lv_tlsf.c",
"lvgl/src/misc/lv_txt_ap.c",
"lvgl/src/misc/lv_txt.c",
"lvgl/src/misc/lv_utils.c",
"lvgl/src/others/file_explorer/lv_file_explorer.c",
"lvgl/src/others/fragment/lv_fragment_manager.c",
"lvgl/src/others/fragment/lv_fragment.c",
"lvgl/src/others/gridnav/lv_gridnav.c",
"lvgl/src/others/ime/lv_ime_pinyin.c",
"lvgl/src/others/imgfont/lv_imgfont.c",
"lvgl/src/others/monkey/lv_monkey.c",
"lvgl/src/others/msg/lv_msg.c",
"lvgl/src/others/snapshot/lv_snapshot.c",
"lvgl/src/themes/basic/lv_theme_basic.c",
"lvgl/src/themes/default/lv_theme_default.c",
"lvgl/src/themes/mono/lv_theme_mono.c",
"lvgl/src/widgets/windows/lv_win.c",
"lvgl/src/widgets/animimg/lv_animimg.c",
"lvgl/src/widgets/arc/lv_arc.c",
"lvgl/src/widgets/bar/lv_bar.c",
"lvgl/src/widgets/btn/lv_btn.c",
"lvgl/src/widgets/btnmatrix/lv_btnmatrix.c",
"lvgl/src/widgets/calendar/lv_calendar_header_arrow.c",
"lvgl/src/widgets/calendar/lv_calendar_header_dropdown.c",
"lvgl/src/widgets/calendar/lv_calendar.c",
"lvgl/src/widgets/canvas/lv_canvas.c",
"lvgl/src/widgets/chart/lv_chart.c",
"lvgl/src/widgets/checkbox/lv_checkbox.c",
"lvgl/src/widgets/colorwheel/lv_colorwheel.c",
"lvgl/src/widgets/dropdown/lv_dropdown.c",
"lvgl/src/widgets/img/lv_img.c",
"lvgl/src/widgets/imgbtn/lv_imgbtn.c",
"lvgl/src/widgets/keyboard/lv_keyboard.c",
"lvgl/src/widgets/label/lv_label.c",
"lvgl/src/widgets/led/lv_led.c",
"lvgl/src/widgets/line/lv_line.c",
"lvgl/src/widgets/list/lv_list.c",
"lvgl/src/widgets/menu/lv_menu.c",
"lvgl/src/widgets/meter/lv_meter.c",
"lvgl/src/widgets/msgbox/lv_msgbox.c",
"lvgl/src/widgets/objx_templ/lv_objx_templ.c",
"lvgl/src/widgets/roller/lv_roller.c",
"lvgl/src/widgets/slider/lv_slider.c",
"lvgl/src/widgets/span/lv_span.c",
"lvgl/src/widgets/spinbox/lv_spinbox.c",
"lvgl/src/widgets/spinner/lv_spinner.c",
"lvgl/src/widgets/switch/lv_switch.c",
"lvgl/src/widgets/table/lv_table.c",
"lvgl/src/widgets/tabview/lv_tabview.c",
"lvgl/src/widgets/textarea/lv_textarea.c",
"lvgl/src/widgets/tileview/lv_tileview.c",
"lvgl/lv_port_disp.c",
#"lvgl/demos/music/lv_demo_music_list.c",
#"lvgl/demos/music/lv_demo_music_main.c",
#"lvgl/demos/music/lv_demo_music.c",
"lvgl/demos/stress/lv_demo_stress.c",
]
include_dirs = [
"http://drivers/hdf_core/framework/include/platform/",
"http://drivers/hdf_core/framework/include/utils/",
"http://drivers/hdf_core/framework/support/platform/include/spi",
"http://drivers/hdf_core/adapter/khdf/liteos_m/osal/include/",
"http://drivers/hdf_core/framework/include/core/",
"http://drivers/hdf_core/framework/include/osal/",
"lvgl/",
"lvgl/src",
".",
]
測試代碼
vendor/openvalley/niobeu4/demo/107_hdf_spi/spi_example.c中
增加
#include "lvgl.h"
#include "lv_port_disp.h"
任務(wù)中
注意初始化
lv_init();在
lv_port_disp_init();前
再創(chuàng)建lc對象
再周期執(zhí)行
lv_task_handler();
另專門開任務(wù)周期調(diào)用
lv_tick_inc(5);
lv_timer_handler();
提供滴答和定時器處理。
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);
}
}
void lv_log_print(const char * buf)
{
printf("%srn",buf);
}
/**
* Create a button with a label and react on click event.
*/
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, 60, 25); /*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 lv_tick_handle(UINT32 arg)
{
while(1)
{
LOS_Msleep(5); /*Sleep for 5 millisecond*/
lv_tick_inc(5);
lv_timer_handler();
}
}
void StartHdfSPITest(void)
{
UINT32 g_lv_time_task;
TSK_INIT_PARAM_S task = { 0 };
task.pfnTaskEntry = (TSK_ENTRY_FUNC)lv_tick_handle;
task.pcName = "lv_time_task";
task.uwStackSize = 0x1000;
task.usTaskPrio = 25 - 1;
lv_init();
lv_port_disp_init();
lv_log_register_print_cb(lv_log_print);
LOS_TaskCreate(&g_lv_time_task, &task);
//lv_demo_stress();
lv_example_get_started_1();
while(1)
{
LOS_Msleep(1);
lv_task_handler();
}
}
執(zhí)行效果
創(chuàng)建了一個按鈕,由于輸入驅(qū)動還沒移植所以不能演示按鈕事件。
總結(jié)
-
開鴻智谷
+關(guān)注
關(guān)注
2文章
125瀏覽量
1150 -
NiobeU4
+關(guān)注
關(guān)注
3文章
31瀏覽量
505
發(fā)布評論請先 登錄
相關(guān)推薦
評論