5336|0

337

帖子

2

TA的资源

纯净的硅(初级)

楼主
 

【GD32E503评测】+ littlegl移植到GD32E503V-EVAL [复制链接]

LittlevGL移植到GD32E503V

前面已经成功的移植了tos到GD32E503V处理器上,基于tos,将LittlevGL移植到GD32E503V-eval开发板。

LittlevGL介绍

LittlevGL是一个免费的开放源代码图形库,它提供创建嵌入式GUI所需的一切,它具有易于使用的图形元素,精美的视觉效果和低内存占用。

特性:

16, 32 or 64 bit microcontroller or processor

16 MHz clock speed

8 kB RAM for static data and >2 KB RAM for dynamic data (graphical objects)

64 kB program memory (flash)

支持GPU

硬件连接关系

    LittleGL系统需要LCD显示器和触摸屏输入两样主要的硬件设备。

图 LCD和触摸屏接口

GD32E503V-EVAL开发板使用EXMC模块来控制LCD。通过GPIO模拟SPI接口连接触摸屏。

LCD和触摸屏接口

GD32E503V 端口

D0~D15

EXMC_D0~EXMC_D15

LCD_CS

PD7

LCD_RS

EXMC_A23

LCD_WR

PD5

LCD_RD

PD4

LCD_RST

NRST

TP_MISO

PA6

TP_MOSI

PA7

TP_SCK

PA5

TP_INT

PE5

TP_CS

PE6

 

驱动代码

  1. LCD驱动

我们在官方的驱动中已经包含了LCD的驱动代码,这里不详细解释。

  1. 触摸屏驱动

官方驱动中包含了触摸屏驱动代码,直接使用就可以,不详细解释。

LittleGL移植

  1. 目录结构

还包括一个example目录,我们在测试的时候会选择其中的一个加入工程中。

  1. 输入设备的移植

输入设备在lvgl/port/lv_port_indev.c中,包括触摸屏,鼠标,键盘,编码器,和按键输入五中输入手段。

本次仅移植触摸屏输入方式,在void lv_port_indev_init(void)函数中,除触摸屏输入的初始化外,其它输入方式暂时隐藏起来。

触摸屏需要完成如下几个函数的移植:

  1. static void touchpad_init(void)函数的移植,这个函数用来完成触摸屏的初始化工作,可以将官方提供的触摸屏初始化函数在此处调用。

touch_panel_gpio_configure();

  1. static bool touchpad_is_pressed(void)函数的移植,这个函数用来完成触摸屏被点击后的检测通知函数,将触摸屏的中断输入引脚PE5的状态检测放到这里。
  2. static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)函数的移植,这个函数用来读取点击的触摸屏的位置信息。

static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)

{

    /*Your code comes here*/

uint16_t touch_ad_x,touch_ad_y;

touch_ad_xy_get(&touch_ad_x, &touch_ad_y);

    (*x) = touch_coordinate_x_get(touch_ad_x);

    (*y) = LCD_Y - touch_coordinate_y_get(touch_ad_y);

}

  1. 显示设备的移植

显示设备在lvgl/port/lv_port_disp.c中,包括显示设备初始化,和显示内容刷新及显示缓存的定义。

在void lv_port_disp_init(void)中,重点需要移植的内容:

  1. 显示设备的初始化

static void disp_init(void)函数,将官方驱动中,显示设备的初始化函数放在这个函数中,完成显示设备初始化。

  1. 显示缓存设置

这个是显存初始化中的一段说明,如下说明了显存包含3种类型的缓存,第一种为分配若干行的显示内容大小的内存作为显存,这是最小的显存分配方式,对于嵌入式系统中使用最广范的一种,通常分配为20行的内存空间;

第二种为分配两个大小相同的显示缓冲区,每个显示缓冲区为若干行显示内容对应的内存。这种方式通常采用DMA的方式刷新显示混存。

第三种为分配两个大小相同的显示缓冲区,每个显示缓冲区的大小为整个屏幕对应的显示内容对应的内存大小,这种方式对于屏幕的刷新速度是最快的,但是占用的内存也是最多的。

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

     *      LittlevGL will draw the display's content here and writes it to your display

     *

     * 2. Create TWO buffer with some rows:

     *      LittlevGL 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 LittlevGL 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 LittlevGL 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 * 20];                      /*A buffer for 20 rows*/

    lv_disp_buf_init(&disp_buf_1, buf1_1, NULL, LV_HOR_RES_MAX * 20);   /*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 * 40];                        /*A buffer for 10 rows*/

//    static lv_color_t buf2_2[LV_HOR_RES_MAX * 40];                        /*An other buffer for 10 rows*/

//    lv_disp_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 40);   /*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*/

对于本次的显示缓存,采用第一种分配方式,20行的显示内容对应的内存大小。

  1. 屏幕尺寸大小定义

这个地方重新定义了屏幕的尺寸,GD32E503V-eval的评估板对应的显示器为320x240,因此填充为如下。

    /*Set the resolution of the display*/

    disp_drv.hor_res = 240;

    disp_drv.ver_res = 320;

  1. 显示刷新函数的移植

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)的移植是最重要的物理设备接口函数,完成从显示缓存到LCD显示内容刷新的接口函数,利用官方提供的驱动接口,填充为:

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

    lcd_point_set(x, y,color_p->full);

            color_p++;

        }

    }

 

    /* IMPORTANT!!!

     * Inform the graphics library that you are ready with the flushing*/

    lv_disp_flush_ready(disp_drv);

}

  1. 运行的其它移植

为了保证LittleGL的正确运行,还需要添加如下几个部分的添加。

  1. 1ms定时器的添加

在系统的1ms定时器,必须添加lv_tick_inc(1);的调用,用于gui的内容定时。

  1. 运行任务的添加

为了让gui显示允许,需要创建一个任务来定时的刷新gui的函数。

基于tos的gui运行任务,通常要求任务堆栈不小于4K,优先级应略高。

#define LVGL_TASK_STK_SIZE       4096

extern void lvgl_task_entry(void *arg);

osThreadDef(lvgl_task_entry, osPriorityNormal, 1, LVGL_TASK_STK_SIZE);

在任务中应定时调用gui的处理函数。

void lvgl_task_entry(void *arg)

{

lv_init();

    lv_port_disp_init();

    lv_port_indev_init();

demo_create();

    while (1) {

    lv_task_handler();

        tos_task_delay(30);

    }

}

    到此LittleGL的gui移植已经基本完成。

 

LittleGL demon测试展示

我们在前面移植的基础上,添加example中的demo来展示一下实际的显示效果。  

 

 

 

 

此帖出自GD32 MCU论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表