其他分享
首页 > 其他分享> > LittleV GUI移植用于ST7789——显示配置

LittleV GUI移植用于ST7789——显示配置

作者:互联网

Step 1 — 准备移植所需文件

从lvgl官网下载到的文件中,主要需要以下选中的文件或文件夹:

image

在自己的工程中新建文件夹,命名为lvgl,将上述选中文件全部提取至该文件夹中,完整的工程文件树如下:

image

其中:

Step 2 — 修改和补充相关的文件

1. porting文件夹中的文件

porting文件夹中个包含以下文件:

image

其中:

本随笔中将重点讨论GUI系统的移植,因此此处仅说明disp的模板文件的修改:

/**********************
 * GLOBAL PROTOTYPES
 **********************/
void lv_port_disp_init(void);
    /**
     * LVGL requires a buffer where it internally draws the widgets.
     * Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
     * The buffer has to be greater than 1 display row
     *
     * There are 3 buffering configurations:
     * 1. Create ONE buffer:
     *      LVGL will draw the display's content here and writes it to your display
     *
     * 2. Create TWO buffer:
     *      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. Double buffering
     *      Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
     *      This way LVGL will always provide the whole rendered screen in `flush_cb`
     *      and you only need to change the frame buffer's address.
     */

    /* Example for 1) */
    #define MY_DISP_HOR_RES   256U
    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];            /*An other 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*/

    disp_drv.hor_res = 240;
    disp_drv.ver_res = 240;
/*Initialize your display and the required peripherals.*/
static void disp_init(void)
{
    st7789_init();
}
/*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*/

//    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)*/
//            st7789_draw_pixel(x, y, color_p->full);
//            color_p++;
//        }
//    }

    uint16_t  x1, y1, x2, y2, size;

    x1 = area->x1;
    y1 = area->y1;
    x2 = area->x2;
    y2 = area->y2;
    size = (x2 - x1 + 1) * (y2 - y1 + 1);

    st7789_set_address(x1, y1, x2, y2);
    st7789_cfg_dcx_set();
    st7789_cfg_spi_write((uint8_t*)color_p, size * 2);

    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

2. 修改lv_conf.h文件

3. 添加时基

听闻LVGL自带非抢占式操作系统,需要时基支持,此处可采用系统自带的滴答定时器中断来实现,如下:

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
  lv_tick_inc(1);

  /* USER CODE END SysTick_IRQn 1 */
}

Step 3 — 工程属性设置修改

在路径中加入相关的文件路径,如下:

image

在源文件位置中添加相关文件夹,如下:

image

Step 4 — LVGL相关函数的调用

首先需经过初始化,如下:

  /* USER CODE BEGIN 2 */
  lv_init();
  lv_port_disp_init();

  /* USER CODE END 2 */

其次,非常重要的一步,需要在while (1)循环中调用lv_task_handler()函数,如下:

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    lv_task_handler();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

考虑到函数的使用相对复杂,因此此时库中的例子将有非常重要的参考意义,在使用自带的例子时,只需包含头文件lv_examples.h即可调用其自带的例子,例如:

  /* USER CODE BEGIN 2 */
  lv_init();
  lv_port_disp_init();
  lv_example_keyboard_1();

  /* USER CODE END 2 */

最终显示效果如下:

image

Step 5 — LVGL库的剪裁

在实际使用中,完成上述移植后,系统的Flash占用率非常高,如下:

image

为此,应考虑进行合理的剪裁。很遗憾,我尝试过,但并没有成功。

标签:disp,draw,buffer,GUI,display,lv,ST7789,buf,LittleV
来源: https://www.cnblogs.com/xixizhk/p/15531756.html