RTT下移植LVGL到W601_显示驱动移植

RTT下移植LVGL到W601_显示驱动移植

声明

个人学习笔记,不保证正确

效果展示

移植lvgl到w601

工程源码

工程源码

参考资料

https://blog.csdn.net/h451884098/article/details/119086173

http://www.openedv.com/docs/book-videos/zdyzshipin/4free/littleVGL.html

环境

win10

keil5

硬件

正点原子w601开发板

步骤流程

1.在06_driver_lcd基础上添加lvgl

添加软件包

RTT下移植LVGL到W601_显示驱动移植_第1张图片

RTT下移植LVGL到W601_显示驱动移植_第2张图片

RTT下移植LVGL到W601_显示驱动移植_第3张图片

RTT下移植LVGL到W601_显示驱动移植_第4张图片

更新软件包
 pkgs --update

RTT下移植LVGL到W601_显示驱动移植_第5张图片

生成keil工程
scons --target=mdk5

RTT下移植LVGL到W601_显示驱动移植_第6张图片

2.添加配置文件

添加配置文件

lvg提供了一个配置模板

RTT下移植LVGL到W601_显示驱动移植_第7张图片

将lv_conf_template.h复制到上级目录,并将文件名修改为lv_conf.h

RTT下移植LVGL到W601_显示驱动移植_第8张图片

使能配置文件

RTT下移植LVGL到W601_显示驱动移植_第9张图片

移植显示接口

1.lvgl官方提供了一个模板,复制文件,并修该为文件名为lv_port_disp

RTT下移植LVGL到W601_显示驱动移植_第10张图片

2.在工程中添加文件,并适配驱动

#include "lv_port_disp.h"
#include "lvgl.h"
#define MY_DISP_HOR_RES 240
static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);

void lv_port_disp_init(void)
{
  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*/

  static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
  lv_disp_drv_init(&disp_drv);   /*Basic initialization*/

  disp_drv.hor_res = 240;
  disp_drv.ver_res = 240;
  disp_drv.flush_cb = disp_flush;
  disp_drv.draw_buf = &draw_buf_dsc_1;
  lv_disp_drv_register(&disp_drv);
}

#include 
#include 
static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
  int32_t x;
  int32_t y;
  uint8_t temp_data;
  const rt_uint8_t *start_addr = (const rt_uint8_t *)color_p;

  for (y = area->y1; y <= area->y2; y++)
  {
    for (x = area->x1; x <= area->x2; x++)
    {
      temp_data = color_p->full; //低八位
      color_p->full = (color_p->full >> 8) + (temp_data << 8);
      color_p++;
    }
  }
  lcd_show_image(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1, start_addr);
  lv_disp_flush_ready(disp_drv);
}

3.添加初始化

/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2019-05-07     yangjie      first implementation
 */

#include 
#include 
#include 
#include 
#include 

#define DBG_TAG "MIAN"
#define DBG_LVL DBG_LOG

#include 

static rt_thread_t lvgl_tid = RT_NULL;
static rt_timer_t lvgl_timer = RT_NULL;

#include "lv_port_disp.h"
#include "lv_obj.h"

void demo(void)
{
    lv_obj_t *label1 = lv_label_create(lv_scr_act());
    lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP); /*Break the long lines*/
    lv_label_set_recolor(label1, true);                 /*Enable re-coloring by commands in the text*/
    lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label, align the lines to the center "
                              "and wrap long text automatically.");
    lv_obj_set_width(label1, 150); /*Set smaller width to make the lines wrap*/
    lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0);
    lv_obj_align(label1, LV_ALIGN_CENTER, 0, -40);

    lv_obj_t *label2 = lv_label_create(lv_scr_act());
    lv_label_set_long_mode(label2, LV_LABEL_LONG_SCROLL_CIRCULAR); /*Circular scroll*/
    lv_obj_set_width(label2, 150);
    lv_label_set_text(label2, "It is a circularly scrolling text. ");
    lv_obj_align(label2, LV_ALIGN_CENTER, 0, 40);
}
MSH_CMD_EXPORT(demo, demo);

static void lvgl_thread_entry(void *parameter)
{

    lv_init();
    lv_port_disp_init();
    demo();
    while (1)
    {
        lv_task_handler();
        rt_thread_mdelay(5); /* 官方手册是提议至少 5 ms */
    }
}

static void lvgl_timeout(void *parameter)
{
    lv_tick_inc(10); /* 因为一个时钟是 10ms */
}

int main(void)
{
    char ret;
    uint32_t tick;
    lcd_clear(WHITE);

    lvgl_tid = rt_thread_create("lvgl",
                                lvgl_thread_entry,
                                RT_NULL,
                                4096, /* stack size */
                                12,   /* priority */
                                5);   /* time slice */
    if (lvgl_tid != RT_NULL)
        rt_thread_startup(lvgl_tid);

    lvgl_timer = rt_timer_create("lvgl_timer",
                                 lvgl_timeout,
                                 RT_NULL,
                                 1, /* 超时时间,单位是时钟节拍 */
                                 RT_TIMER_FLAG_PERIODIC);
    if (lvgl_timer != RT_NULL)
        rt_timer_start(lvgl_timer);

    return 0;
}

踩坑记录

一开始驱动显示适配的是打点函数,导致刷新一个页面要二十几秒,在这基础上不停的优化,结果还是要十几秒,

被逼无奈开始认真看代码,突然发现回调其实就是画一片区域

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

你可能感兴趣的:(W601,单片机,嵌入式硬件)