如何一步一步地优化LVGL的丝滑度

news2024/11/18 5:40:16

经过一番周折将LVGL移植到了STM32F407单片机上,底层驱动的LCD是st7789,移植时的条件和环境如下:

●LVGL用的是单缓冲,一次刷新10行;

●刷新函数用的是最原始的一个一个打点的方式;

●ST7789底层发送数据用的是软件spi;

在这些环境下,刷屏就是在拉窗帘,特别慢。

接下来,一步一步地进行优化。

软件SPI→硬件SPI

将硬件SPI改成软件SPI,其实效果并没有什么提升,甚至可以说毫无改进。

注意,这里SPI虽然只用发送,但是接收的代码也不能省略,要不然没效果,千万注意。

虽然硬件SPI相比软件SPI没什么改善,但是硬件SPI可以结合DMA使用。

硬件SPI+DMA

结合LCD屏幕的指针自增进行区域批量赋值,不再一个一个地打点了,而是一次性填充整个区域。

Lvgl的打点调用如下

刷屏函数如下

使用DMA之后,效果提升比较明显,页面切换几乎是瞬间完成,但是还是有闪烁的感觉。

这里有一些问题需要注意下。

不知道为什么,DMA操作8位时能用,操作16位时就不好用了,虽然也把spi和DMA都改成了操作16位,还是不行,所以暂时使用8位;

理论上来说SPI的位数和DMA的位数应该是独立的,一个是发送的字节单位,一个是搬运的字节单位;暂时没搞明白,就统一使用8位吧。

另外,spi的时钟不能太低

估计是太慢的话,spi发送的速度跟不上DMA搬运数据的速度,spi的数据会被冲掉;

再就是SPI的发送和DMA的发送是可以共存的。

ST7789的驱动里涉及到发送指令和发送数据,如果是一次性的数据发送,可以使用DMA,也可以使用SPI

使用spi发送

使用dma发送

考虑到使用DMA来刷新屏幕数据可以结合lvgl的缓冲,所以上面选用spi的发送方式,然后DMA专门用来刷数据;

前面我是独立于lvgl,在LCD的驱动里给DMA专门又开了个内存空间

但其实,可以直接使用lvgl开辟的显存空间,重复申请就浪费了加倍的空间了,也省去了数据复制的步骤了。

但这样又有个问题,那就是颜色像素是个16位的数组,我DMA操作的是8位的数据,前面说了,DMA操作16位的不知道为啥不好使,所以这里面肯定要有些转化,或者解决DMA不能搬运16位数据的原因。怎么办呢?

继续往下看。

SPI+DMA+LVGL双缓冲

参考:LVGL非全尺寸双显存—SPI+DMA(中断刷新) - 哔哩哔哩

配置lvgl为双缓冲

注意下面的别忘了同步修改。

然后将上面三个静态变量的声明放到外面去,因为这里是在函数内部,属于局部静态变量,后面需要全局使用,就会识别不到,因此要上升成全局变量。

在使用LVGL的双缓冲时,DMA初始化时的发送地址可以先设置为双缓存的第一个空间,此时,将LCD的初始化函数直接放在lv_port_disp_template.c中,并且传递进入第一个缓冲区的地址。

之前单独为DMA开辟的发送空间可以去掉。

接下来开始改造刷新函数

Lvgl双缓冲的切换是lvgl自动进行的,我们不用去处理指针切换和数据交替填充的操作,只需要在刷新函数里获取对应的颜色数据的地址,就是当前要发送的数据地址,是lvgl已经帮我们切换好了双缓冲的指针。

在disp_flush函数里我们直接填充数据,接口不变。

同时有一个考虑:DMA发送数据时,之前是强行死循环等待DMA发送完成

我们现在将其改成DMA传输完成中断的方式来进行,然后在DMA传输完成中断里通知lvgl进行下一次刷新,也就是将lv_disp_flush_ready(disp_drv);函数放到DMA中断里去,这样就又有了问题,那就是这个通知函数里的disp_drv是个局部变量,想要挪到外部,就得借助一个中间的全局变量,因此,再定义一个全局的变量,类型和disp_drv的类型一致

同时,考虑到DMA一次只能发送一个字节的数据,因此我们将color_p强行转换成8位数据类型的指针。

于是,刷新函数disp_flush如下:

接下来,就要继续改造打点函数了

我们先计算下,DMA一次最多能发送65535个数据,我配置的是8位的,也就是一次最多能发送65535个字节,一个像素2个字节,那么就是说一次最多能发送32767个像素,如果屏幕是320*240的,那么一次最多能发送102行,所以,设置双缓冲时,我们的缓冲大小不要超过102行,我们这里先将缓冲设置成20行,也就是每次刷新,可以直接使用DMA发完,不必让DMA也分次发送。

DMA使能函数调整

另外,别忘了配置DMA的传输完成中断

然后按照上面说过的思路在lv_port_disp_template.c文件中写上DMA的传输完成中断,并在里面放置通知函数。

在这一过程中,其实有个隐含的答案,那就是上面提过的,关于像素是16位的,但是DMA只能处理8位数据的问题。

其实,DMA所识别的起始地址,就是个32位的地址,不管目标数据本身是什么类型,只要把首地址传给DMA即可,DMA从首地址开始,按照DMA配置的位数来搬运数据,DMA并不关心这个地址原来本身是什么类型的数据。

所以,LVGL传过来的是地址,我们只要把地址转成uint32_t然后传递给DMA,DMA就会按照初始化时配置的位数来搬运,它才不管你原来的数据是多少位的。

至此,DMA+LVGL双缓冲已完成,编译下载运行看看效果。

运行后,发现颜色不大对,原来是红绿蓝,现在变成了青紫黄,这种情况,就想到了一个颜色配置项LV_COLOR_16_SWAP,把它改成1。

再编译下载运行

颜色正常,速度也还挺好。

当然,如果想要再快,可以使用全屏幕双缓冲,此时,SRAM空间不够的话就可以将其放在外部SRAM中,用空间来换时间。我这个项目到这里帧率为35,已经够用了,就不再优化了。后续有特别的需要再说吧。

更多优化参考

LVGL显示优化—基本优化 - 哔哩哔哩

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1476210.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

寒假开学在即,怎么寄行李才能便宜省钱呢?

在度过了一个充实愉快的假期之后,小伙伴们就要踏上新的征程了,来面对新学期的到来,可是,面对这么多不知道怎么安排的行李可就把人给愁死了,如果通过驿站寄行李的话,又要花费一大笔快递费了,可是…

IAudioManager.cpp源码解读

IAudioManager.cpp源码如下: 源码路径:https://cs.android.com/android/platform/superproject/main//main:frameworks/native/services/audiomanager/IAudioManager.cpp;drc84410fbd18148d422d3581201c67f1a72a6658c4;l147?hlzh-cn /** Copyright (C)…

基于springboot实现线上阅读系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现线上阅读系统演示 摘要 随着社会发展速度的愈来愈快,以及社会压力变化的越来越快速,致使很多人采取各种不同的方法进行解压。大多数人的稀释压力的方法,是捧一本书籍,心情地让自己沉浸在情节里面,以…

【Linux】TCP应用与相关API守护进程

需要云服务器等云产品来学习Linux的同学可以移步/–>腾讯云<–/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;优惠多多。&#xff08;联系我有折扣哦&#xff09; 文章目录 1. 相关使用接口2. 代码实现2.1 日志组件2.2 Server端2.3 Client端2.3 bug解决 3. 守…

动态规划|【斐波那契数列模型 】|面试题08.01三步问题

目录 题目 思路 普通思路 动态规划思路 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 代码 空间优化 题目 题目链接 面试题 08.01. 三步问题https://leetcode.cn/problems/three-steps-problem-lcci/ 三步问题。有个小孩正在上楼梯&#xff0c;楼梯有n…

【JAVA日志】关于日志系统的架构讨论

目录 1.日志系统概述 2.环境搭建 3.应用如何推日志到MQ 4.logstash如何去MQ中取日志 5.如何兼顾分布式链路追踪 1.日志系统概述 关于日志系统&#xff0c;其要支撑的核心能力无非是日志的存储以及查看&#xff0c;最好的查看方式当然是实现可视化。目前市面上有成熟的解决…

今天面试了一个工作4年的测试工程师,一问连自动化基础都不知道,还反过来怼我..

金三银四黄金期&#xff0c;我们公司也开始大量招人了&#xff0c;我这次是公司招聘的面试官之一&#xff0c;主要负责一些技术上的考核&#xff0c;这段时间还真让我碰到了不少奇葩求职者 昨天公司的HR小席刚跟我吐槽&#xff1a;这几个星期没有哪天不加班的&#xff01;各种…

LTD264次升级 | 对接AsiaPay • 人民币买外币商品 •知识付费订单可关闭 • 专栏支持VIP免支付购买

​ 1、对接AsiaPay第三方支付平台&#xff0c;支持人民币买外币商品&#xff1b; 2、知识付费购买优化 3、账号绑定的微信号可解除绑定&#xff1b; 4、其他已知问题修复与优化&#xff1b; 01 商城 1) 新增海外跨境支付系统AsiaPay 在本次升级中&#xff0c;商城支付系统新增…

【面试题】在浏览器地址栏输入URL后会发生什么

1. 地址栏输入后的本地操作 当我们在浏览器的地址栏中&#xff0c;输入xxx内容后&#xff0c;浏览器的进程首先会判断输入的内容&#xff1a; 如果是普通的字符&#xff0c;那浏览器会使用默认的搜索引擎去对于输入的xxx生成URL。如若输入的是网址&#xff0c;那浏览器会拼接…

StarRocks实战——滴滴OLAP的技术实践与发展方向

原文大佬的这篇StarRocks实践文章整体写的很深入&#xff0c;介绍了StarRocks数仓架构设计、物化视图加速实时看板、全局字典精确去重等内容&#xff0c;这里直接摘抄下来用作学习和知识沉淀。 目录 一、背景介绍 1.1 滴滴OLAP的发展历程 1.2 OLAP引擎存在的痛点 1.2.1 运维…

在 Jupyter Notebook 中查看所使用的 Python 版本和 Python 解释器路径

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 我们在做 Python 开发时&#xff0c;有时在我们的服务器上可能安装了多个 Python 版本。 使用 conda info --envs 可以列出所有的 conda 环境。当在 Linux 服务器上使用 which python 命令时&#xff0…

【数据结构与算法】回溯法解题20240229

【数据结构与算法】回溯法解题20240229 一、46. 全排列1、以[1,2,3]为例&#xff0c;抽象成树形结构2、回溯三部曲 二、LCR 084. 全排列 II1、以[1,1,2]为例&#xff0c;抽象成树形结构 三、面试题 08.07. 无重复字符串的排列组合四、面试题 08.08. 有重复字符串的排列组合 一、…

代码随想录-力扣刷题-总结笔记01

代码随想录&#xff1a;代码随想录力扣&#xff1a;力扣 (LeetCode) 全球极客挚爱的技术成长平台 目录 01、代码随想录 00、琐碎知识点 01、数组 02、链表 03、哈希表 04、字符串 05、双指针法 06、栈与队列 6.1、栈 6.2、队列 07、二叉树 7.1、前中后序-递归遍历 …

UTONMOS元宇宙游戏发展趋势是什么?

UTONMOS元宇宙游戏的发展趋势包括以下几个方面&#xff1a; 更加真实的体验&#xff1a;随着技术的进步&#xff0c;UTONMOS元宇宙游戏将提供更加逼真的视觉、听觉和触觉体验&#xff0c;让玩家更加身临其境。 社交互动&#xff1a;UTONMOS元宇宙游戏将越来越注重社交互动&am…

Premiere水墨风格婚纱照片婚礼视频模板|PR婚庆后期剪辑模板

时尚大气水墨风格婚纱照片展示&#xff0c;婚礼视频制作PR模板&#xff0c;婚庆后期剪辑模板MOGRT。 主要特点&#xff1a;高清&#xff08;19201080&#xff09;分辨率/30帧/秒&#xff0c;Premiere Pro 2022或更高版本软件&#xff0c;易于定制&#xff0c;持续时间00:50秒&a…

猫头虎分享已解决Bug || 虚拟网络问题(Virtual Network Issue):VirtualNetworkError, VNetFailure

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

IPD(集成产品开发)—核心思想

企业发展到一定阶段就会遇到管理瓶颈&#xff0c;IPD流程是一种高度结构化的产品开发流程&#xff0c;它集成了业界很多优秀的产品开发方法论&#xff0c;像搭积木一样的组合成一种非常有效的流程。如果我们能根据企业的规模和行业特点&#xff0c;对全流程的IPD进行合适的裁剪…

陪诊小程序:温暖您的就医之路,让关怀触手可及

随着社会的进步和科技的发展&#xff0c;人们对于医疗健康的需求日益增长。然而&#xff0c;在繁忙的生活节奏中&#xff0c;许多人在面对就医时却面临着无人陪伴的困境。为了解决这一问题&#xff0c;陪诊小程序应运而生。 陪诊小程序是一种便捷、高效、人性化的医疗服务应用…

Python正则表达式:从基础到高级应用的全面总结与实战【第103篇—JSON模块】

Python正则表达式&#xff1a;从基础到高级应用的全面总结与实战 正则表达式是一种强大的文本匹配和处理工具&#xff0c;广泛应用于文本处理、数据抽取、表单验证等领域。本文将从正则表达式的基础知识出发&#xff0c;逐步深入&#xff0c;最终结合代码实战&#xff0c;带你…

【代码随想录python笔记整理】第十四课 · 链表的基础操作 2

前言:本笔记仅仅只是对内容的整理和自行消化&#xff0c;并不是完整内容&#xff0c;如有侵权&#xff0c;联系立删。 一、分析题目要求 在前面一课中&#xff0c;我们学习了链表的创建以及新元素的插入&#xff0c;并且我们学会了打印链表中的元素。这节课我们依托上节课的基础…