为了配置一个Display,一个lv_disp_buf_t类型的变量和一个lv_disp_drv_t类型的变量必须要初始化。

  • lv_disp_buf_t 包含内部的图像buffer
  • lv_disp_drv_t 包含与Display交互的回调函数,并进行绘图相关的操作

Display buffer

lv_disp_buf_t可以像这样初始化:

/*A static or global variable to store the buffers*/
static lv_disp_buf_t disp_buf;/*Static or global buffer(s). The second buffer is optional*/
static lv_color_t buf_1[MY_DISP_HOR_RES * 10];
static lv_color_t buf_2[MY_DISP_HOR_RES * 10];/*Initialize `disp_buf` with the buffer(s) */
lv_disp_buf_init(&disp_buf, buf_1, buf_2, MY_DISP_HOR_RES*10);

关于buffer的大小,有三种可能的配置:

  1. 单buffer LVGL绘制屏幕的内容,然后发送给display。buffer可以比屏幕小。这种情况下,大的区域会被分成小块来绘制。如果只有小块的区域发生了变化(例如按钮被按下),那么只有这些区域会刷新。
  2. 双非屏幕大小的buffer 有了两个buffer,LVGL就可以在其中一个buffer绘制的同时,在后台将另一个buffer中的内容发送给Display。为了能够让绘制和发送同时运行,需要使用DMA或者其他硬件。这种情况下,渲染和刷新是并行的。与单buffer类似,如果buffer比需要绘制的区域小,LVGL也是分块绘制的。
  3. 双屏幕大小的buffer 与上一种情况相比,LVGL总是一次提供整个屏幕的内容,而不是分块。这种情况下,驱动可以仅仅是将frame buffer的地址改成从LVGL接收到的buffer的地址。因此,在MCU有LCD/TFT接口,frame buffer位于RAM的情况下,这种方式是最佳的。

可以用benchmask来测试你显示配置的性能。

Display driver

一旦buffer初始化完成,就需要初始化Display Driver了。在最简单的情况下,只需要设置lv_disp_drv_t的下述两个域:

  • buffer 指向lv_disp_buf_t变量的指针
  • flush_cb 一个用于将buffer的内容复制到Display特定区域的回调函数。lv_disp_flush_ready()需要在回调函数的最后调用。LVGL可能会分块渲染屏幕,因此flush_ch可能会被多次调用。可以调用lv_disp_flush_is_last()来查看当前是否是渲染的最后一块。

下面是一些可选的域:

  • hor_res Display的水平分辨率。默认值是lv_conf.h中定义的LV_HOR_RES_MAX。
  • ver_res Display的垂直分辨率。默认值是lv_conf.h中定义的LV_VER_RES_MAX。
  • color_chroma_key 透明图像的颜色。默认值是lv_conf.h中定义的LV_COLOR_TRANSP。
  • user_data driver的用户数据,其类型可以在lv_conf.h中修改。
  • anti-aliasing 是否使用反锯齿(平滑边缘)。默认值是lv_conf.h中定义的LV_ANTIALIAS。
  • rotatedsw_rotate 见rotation这一章节。
  • screen_transp 如果设置为1,屏幕就能有透明或者半透明的style。lv_conf.h中的LV_COLOR_SCREEN_TRANSP必须要打开。

为了使用GPU,可以使用下面的这些回调:

  • gpu_fill_cb 用颜色填充内存中的一块区域。
  • gpu_blent_cb 用不透明度渲染两个内存buffers。
  • gpu_wait_cb 当GPU还在处理LVGL数据的时候,如果任何GPU函数返回了,就会使用这个函数以确保GPU渲染准备就绪。

需要注意的是,这些函数需要将图形绘制到内存,而不是display。

当使用单色屏,灰度屏和其他非标准RGB屏幕的时候,还有一些可选的回调能让工作更简单。

  • rounder_cb 改变区域的坐标以重新绘制。例如,2X2的像素点可以变换成2X8。如果显示控制器只能刷新刷新固定高度或者固定宽度区域的时候,这个回调就会有用(例如8像素高的单色屏)。
  • set_px_cb 写display buffer的定制函数。当display是特殊颜色格式的时候,可以用于存储像素。(例如1位的单色屏,2位的灰度屏)。这种情况下,lv_disp_buf_t中的buffer大小只需要是给定区域的数据量大小。这个回调在“双屏幕大小的buffer”这一配置下不生效。
  • monitor_cb 从这个回调中可以知道多长时间刷新了多少数据。
  • clean_dcache_cb 清除display相关的任意cache。

为了设置lv_disp_drv_t类型的变量的域,这个变量首先要用lv_disp_drv_init(&disp_drv)来初始化,最后要用lv_disp_drv_register(&disp_drv)来注册。

以上这些组合在一起,是这个样子的:

lv_disp_drv_t disp_drv;                 /*A variable to hold the drivers. Can be local variable*/
lv_disp_drv_init(&disp_drv);            /*Basic initialization*/
disp_drv.buffer = &disp_buf;            /*Set an initialized buffer*/
disp_drv.flush_cb = my_flush_cb;        /*Set a flush callback to draw to the display*/
lv_disp_t * disp;
disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/

下面是一些回调的示例:

void my_flush_cb(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, y;for(y = area->y1; y <= area->y2; y++) {for(x = area->x1; x <= area->x2; x++) {put_px(x, y, *color_p)color_p++;}}/* IMPORTANT!!!* Inform the graphics library that you are ready with the flushing*/lv_disp_flush_ready(disp_drv);
}void my_gpu_fill_cb(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, const lv_area_t * dest_area, const lv_area_t * fill_area, lv_color_t color);
{/*It's an example code which should be done by your GPU*/uint32_t x, y;dest_buf += dest_width * fill_area->y1; /*Go to the first line*/for(y = fill_area->y1; y < fill_area->y2; y++) {for(x = fill_area->x1; x < fill_area->x2; x++) {dest_buf[x] = color;}dest_buf+=dest_width;    /*Go to the next line*/}
}void my_gpu_blend_cb(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
{/*It's an example code which should be done by your GPU*/uint32_t i;for(i = 0; i < length; i++) {dest[i] = lv_color_mix(dest[i], src[i], opa);}
}void my_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t * area)
{/* Update the areas as needed. Can be only larger.* For example to always have lines 8 px height:*/area->y1 = area->y1 & 0x07;area->y2 = (area->y2 & 0x07) + 8;
}void my_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa)
{/* Write to the buffer as required for the display.* Write only 1-bit for monochrome displays mapped vertically:*/buf += buf_w * (y >> 3) + x;if(lv_color_brightness(color) > 128) (*buf) |= (1 << (y % 8));else (*buf) &= ~(1 << (y % 8));
}void my_monitor_cb(lv_disp_drv_t * disp_drv, uint32_t time, uint32_t px)
{printf("%d px refreshed in %d ms\n", time, ms);
}void my_clean_dcache_cb(lv_disp_drv_t * disp_drv, uint32)
{/* Example for Cortex-M (CMSIS) */SCB_CleanInvalidateDCache();
}

Rotation

LVGL支持以90度为增量的屏幕旋转。可以选择使用软件旋转或者硬件旋转。

如果选择软件旋转(sw_rotate标志位设置为1),LVGL会自动进行旋转。对驱动来说,屏幕的宽度和高度没有改变。正常的将像素刷新到display即可。软件旋转不需要改flush_cb回调。

软件旋转有可见的性能消耗,所以我们也需要使用硬件旋转。在这一模式下,LVGL就好像交换了屏幕的宽度和高度一样,将图像绘制到buffer。你需要自己来实现旋转像素。

初始化时候的默认旋转,可以用rotated标志位来设置。可用的选项有LV_DISP_ROT_NONE,LV_DISP_ROT_90,LV_DISP_ROT_180和LV_DISP_ROT_270。旋转的角度取决于硬件设备顺时针旋转的方向。这样LV_DISP_ROT_90意味着硬件设备顺时针旋转了90度,那么显示就要逆时针旋转90度。

对于从7.10.0以及更老版本升级上来的用户,上述的旋转枚举值与老系统用0和1来表示是否旋转90度是兼容的。所以老的代码也能使用。从兼容性考虑,软件旋转默认也是关闭的。

显示的旋转也可以在运行时用lv_disp_set_rotation(disp, rot)接口来改变。

支持软件旋转是一个新的特性,所以在你的配置下可能会存在bug。如果你遇到了bug,请在GitHub上提Issue。

LVGL官方文档-7.11.0-4-Porting-Display interface相关推荐

  1. LVGL官方文档-7.11.0-5-Porting-Input device interface

    Types of input devices 配置输入设备的时候,需要初始化一个lv_indev_drv_t类型的变量: lv_indev_drv_t indev_drv; lv_indev_drv_ ...

  2. LVGL官方文档-7.11.0-14-Overview-Displays

    Multiple display support 在LVGL中,可以存在多个Display,每个都有他们各自的Driver和Object.唯一的限制是这些Display的颜色深度要一样(由LV_COL ...

  3. LVGL官方文档-7.11.0-8-Porting-Logging

    默认情况下,LVGL不是线程安全的. 但是,在下列情况下,调用LVGL相关函数是安全的. 在Event中. 在lv_task中. Tasks and threads 如果需要使用正常的Task或者是线 ...

  4. Harbor安装教程-完全根据官方文档2.6.0版本

    说明: 版本2.6.0 一.安装要求 硬件 硬件类型 最小要求 建议 CPU 2 CPU 4 CPU 内存 4 GB 8GB 硬盘 40 GB 160 GB 软件 软件名称 版本 Docker eng ...

  5. tensorflow官方文档_Tensorflow 2.0 Preview 官方文档

    TensorFlow 2.0目前放出了Preview版本.目前想了解TensorFlow 2.0最快的方式就是查看官方API中的变化.本文列举一些从TF官方API中看出的TF 2.0的改进. Tens ...

  6. django官方文档1.11编翻:1-1-1概述

    django概述 因为django是在快节奏的编辑环境下开发的,它旨在使常见的Web开发任务变得快速而简单. 这是一个关于如何用django编写数据库驱动的Web应用程序的非正式概述. 本文档的目的是 ...

  7. (6)APB总线协议——(官方文档阅读APB3.0)

    第一章:简介 1.1APB3介绍 低速总线协议 时钟上升沿采样,每次数据传输需要两个时钟周期 可与AHB/AXI接口连接 第二章:数据传输 2.1写传输 2.1.1无等待状态 分析: 写传输从地址.写 ...

  8. 官方文档太辣鸡?TensorFlow 2.0开源工具书,30天「无痛」上手

    本文转载自机器之心. 项目作者:lyhue1991 「官方文档排布凌乱.搜索难用.API 丑陋不堪--」这是很多人对 TensorFlow 官方文档的吐槽.但吐槽归吐槽,到了工业界,你是无论如何也绕不 ...

  9. tensorflow官方文档_开源分享:最好的TensorFlow入门教程

    如果一门技术的学习曲线过于陡峭,那么我们在入门时的场景往往是,一鼓作气,没入门,再而衰,三而竭.演绎一出从入门到放弃的败走麦城. 今天发现一个入门TensorFlow的宝藏,迫不及待的分享给大家.这个 ...

最新文章

  1. java void传参,Java中的传参
  2. Nature:首个完全复现人眼的仿生眼问世,港科大造出半球形人工视网膜,感光性能超过人眼460倍...
  3. mysql5.1修改登陆密码_mysql 5.1版本修改密码及远程登录mysql数据库的方法
  4. [转载]用消息队列和消息应用状态表来消除分布式事务
  5. 【Node】新手入门 基于Express,Sequelize、IIS的MVC项目
  6. centos 云服务器部署Node.js项目
  7. 纯css 无视宽高设置垂直水平居中
  8. java如果把字符串转成对象_为什么Java中的字符串对象是不可变的,有什么好处?...
  9. Oracle 11G R2(11.0.2.4.0) RAC打PSU(11.2.0.4.11.2.0.4.171017)
  10. mysql sql语句 参数化_参数化SQL语句
  11. 计算机万维考试题,计算机培训 万维考试系统选择题题库(含参考答案).pdf
  12. Vue3 的 Reactive 响应式到底是什么
  13. 视频教程- 项目管理工具(1) WBS-工作分解结构-研发管理
  14. 如何优化网站,网站推广优化一般流程有哪些
  15. 20个专业H5(HTML5)动画工具推荐
  16. sqlserver AlwaysOn实现读写分离配置及java/net代码实现
  17. Python字符串格式化的3种方法
  18. 国际工程施工中常发生的合同问题(FIDIC)(转)
  19. ECK安装elasticsearch集群及es配置x-pack
  20. C语言——生存期和存储类型、递归、递归求解汉诺塔、快速排序

热门文章

  1. 整理出来的200份Python零基础入门与数据分析资料,速领!
  2. CSS 霓虹灯效果 (二)
  3. md5模块和hashlib模块
  4. “任何特殊资源”都能搜,可别乱搜哦~
  5. ubuntu安装pr_Ubuntu16.04安装wps办公软件解决文字缺失
  6. linux 内核代码分析1 TI am335x
  7. 高瓴资本创始人张磊:美团点评有大格局价值观 我们长期看好
  8. GPB proto文件转C语言
  9. 【读期刊】基于卷积神经网络的方法对感应电动机进行故障诊断
  10. CelebA人脸属性数据集解析