在线时间2408 小时
UID3327992
注册时间2018-4-5
NXP金币3315
TA的每日心情 | 奋斗 昨天 14:38 |
---|
签到天数: 1947 天 [LV.Master]伴坛终老
版主
- 积分
- 17356
- 最后登录
- 2024-5-3
|
GUI Guider是恩智浦推出的一个PC端开发工具,专门用于开发LVGL GUI界面的图形化开发工具。LVGL是一个非常不错的开源gui,一直想试一试的。这次主要分享自己移植lvgl,以及利用GUI Guider开发基于lvgl的界面设计。 GUI Guider早就安装了1.0版本,也试着创建项目看了看,发现目前支持的开发板有点少,而且自己还没有那些板子。就一直想着移植到其他板子上玩玩。这次研究了一下,也参考网上的一些资料,成功移到自己的板子上了。现在来分享一下本次研究过程。
初始计划是先移植lvgl在自己的板子上无OS运行,然后再移植GUI Guider设计的界面代码,再实现输入设备操作。
本次板子使用的LPC55S69开发板,外带ili9488控制LCD,lcd屏320*480分辨率。lcd驱动已经完成,准备移植lvgl。首先将lvgl代码复制到工程目录下。
然后在lvgl目录下新建lvgl_app和lvgl_port这2个文件夹,lvgl_app主要放设计的应用文件,lvgl_port主要放需要移植的文件。
如下图,将lvgl的example/port目录下移植文件复制到lvgl_port目录下。
参考网上移植方法修改lcd对接lvgl的驱动显示接口文件lv_port_disp_xxxl.c。
- void lv_port_disp_init(void)
- {
- /*-------------------------
- * Initialize your display
- * -----------------------*/
- disp_init();
- /*-----------------------------
- * Create a buffer for drawing
- *----------------------------*/
- /* LVGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row
- *
- * There are three buffering configurations:
- * 1. Create ONE buffer with some rows:
- * LVGL will draw the display's content here and writes it to your display
- *
- * 2. Create TWO buffer with some rows:
- * LVGL will draw the display's content to a buffer and writes it your display.
- * You should use DMA to write the buffer's content to the display.
- * It will enable LVGL to draw the next part of the screen to the other buffer while
- * the data is being sent form the first buffer. It makes rendering and flushing parallel.
- *
- * 3. Create TWO screen-sized buffer:
- * Similar to 2) but the buffer have to be screen sized. When LVGL is ready it will give the
- * whole frame to display. This way you only need to change the frame buffer's address instead of
- * copying the pixels.
- * */
- /* Example for 1) */
- static lv_disp_buf_t disp_buf_1;
- static lv_color_t buf1_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/
- lv_disp_buf_init(&disp_buf_1, buf1_1, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
- // /* Example for 2) */
- // static lv_disp_buf_t disp_buf_2;
- // static lv_color_t buf2_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/
- // static lv_color_t buf2_2[LV_HOR_RES_MAX * 10]; /*An other buffer for 10 rows*/
- // lv_disp_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
- // /* Example for 3) */
- // static lv_disp_buf_t disp_buf_3;
- // static lv_color_t buf3_1[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*A screen sized buffer*/
- // static lv_color_t buf3_2[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*An other screen sized buffer*/
- // lv_disp_buf_init(&disp_buf_3, buf3_1, buf3_2, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/
- /*-----------------------------------
- * Register the display in LVGL
- *----------------------------------*/
- 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 = LV_HOR_RES_MAX;
- disp_drv.ver_res = LV_VER_RES_MAX;
- /*Used to copy the buffer's content to the display*/
- disp_drv.flush_cb = disp_flush;
- /*Set a display buffer*/
- disp_drv.buffer = &disp_buf_1;
- #if LV_USE_GPU
- /*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/
- /*Blend two color array using opacity*/
- disp_drv.gpu_blend_cb = gpu_blend;
- /*Fill a memory array with a color*/
- disp_drv.gpu_fill_cb = gpu_fill;
- #endif
- /*Finally register the driver*/
- lv_disp_drv_register(&disp_drv);
- }
复制代码- 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*/
- // 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)*/
- // color_p++;
- // }
- // }
- lcd_fill_buff(area->x1,area->y1,area->x2,area->y2,(uint8_t *)color_p);
-
- /* IMPORTANT!!!
- * Inform the graphics library that you are ready with the flushing*/
- lv_disp_flush_ready(disp_drv);
- }
复制代码 主要是这2个函数内容,暂时不用GPU加速之内。
再就是配置lv_conf.h文件,关于lvgl的一些配置信息。
主函数修改移植如下:主要是定时器SysTick
- void SysTick_Handler(void)
- {
- lv_tick_inc(1);
- }
- void lv_example_btn_1(void)
- {
- lv_obj_t * label;
- lv_obj_t * btn1 = lv_btn_create(lv_scr_act(),NULL);
- lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, -40);
- label = lv_label_create(btn1,NULL);
- lv_label_set_text(label, "Button");
- lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), NULL);
- lv_obj_align(btn2,NULL, LV_ALIGN_CENTER, 0, 40);
- label = lv_label_create(btn2,NULL);
- lv_label_set_text(label, "Toggle");
- }
- /*******************************************************************************
- * Code
- ******************************************************************************/
- /*!
- * @brief Main function
- */
- int main(void)
- {
- char ch;
- int i;
- /* Init board hardware. */
- /* set BOD VBAT level to 1.65V */
- POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
- /* attach main clock divide to FLEXCOMM0 (debug console) */
- CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
- BOARD_InitPins();
- BOARD_InitBootClocks();
- BOARD_InitDebugConsole();
- init_cycle_counter(false);
- PRINTF("hello world.\r\n");
- lcd_init();
- lcd_clear(0xf800);
-
- lv_init();
- extern void lv_port_disp_init(void);
- lv_port_disp_init();
-
- lv_example_btn_1();
-
- while (1)
- {
- lv_task_handler();
- }
- }
复制代码
现在基本完成了移植,然后准备编译下载看看效果。这里要特别注意:需要配置堆栈大小。我就是在这里遇到坑了。按上面移植之后一直显示不正常,而且程序跑飞了。
后面参考网上移植的说要配置堆栈至少0x800大小,然后我就去找堆栈配置看看。在这里一般堆栈是在汇编*.s文件中,结果发现汇编文件中没有堆栈配置,最后找到KEIL的配置下修改了堆栈大小。
最后重新编译下载,终于成功显示。
效果如下
移植过程写的比较简单,具体参考如下代码:
lpc55s69_lcd.rar
(7.21 MB, 下载次数: 32)
|
|