前言

最近项目需要买了一个ESP-WROVER-E模块,这个模块内置了一个4MB的PSRAM,对于需要大内存运行的场景非常友好。



在我的项目中用到了LVGL这个第三方图形库,下面就讲一下如何最大化地在LVGL中使用这个PSRAM。

教程

在lv_conf.h文件中,找到下面的代码。

/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
#define LV_MEM_CUSTOM 1
#if LV_MEM_CUSTOM == 0/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/#define LV_MEM_SIZE (48U * 1024U)          /*[bytes]*//*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/#define LV_MEM_ADR 0     /*0: unused*//*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/#if LV_MEM_ADR == 0#undef LV_MEM_POOL_INCLUDE#undef LV_MEM_POOL_ALLOC#endif#else       /*LV_MEM_CUSTOM*/#define LV_MEM_CUSTOM_INCLUDE <stdlib.h>   /*Header for the dynamic memory function*/#define LV_MEM_CUSTOM_ALLOC   malloc#define LV_MEM_CUSTOM_FREE    free#define LV_MEM_CUSTOM_REALLOC realloc
#endif     /*LV_MEM_CUSTOM*/

默认情况下LV_MEM_CUSTOM为0,这时LVGL会自己弄一个内存池进行管理,这个内存池是使用ESP32的SRAM,而ESP32能用的SRAM实际大小也就320KB。
如果ESP32上自带PSRAM的话,可以将LV_MEM_CUSTOM设为1,这时LVGL将使用stdlib.h头文件内的函数分配内存,而使用这些函数分配内存是可以充分使用到SRAM和PSRAM的内存的。

接下来修改与显示有关的代码。官方会提供3个显示刷新的方案——单缓冲10行刷新、双缓冲10行刷新和双缓冲全像素刷新。如果我们的ESP32上自带PSRAM,那么肯定尽可能选择刷新速度最快的双缓冲全像素刷新方式,但在用之前函数最好还是计算一下内存的占用,大一点的屏幕在该模式下要占满4MB的内存也不是不可能的。

void Display::init(void)
{display_init();// 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_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*/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];            /*Another screen sized buffer*/lv_color_t* buf_3_1 = (lv_color_t*) heap_caps_malloc(MY_DISP_HOR_RES * MY_DISP_VER_RES, MALLOC_CAP_SPIRAM);lv_color_t* buf_3_2 = (lv_color_t*) heap_caps_malloc(MY_DISP_HOR_RES * MY_DISP_VER_RES, MALLOC_CAP_SPIRAM);lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, MY_DISP_VER_RES * MY_DISP_HOR_RES);   /*Initialize the display buffer*/static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/lv_disp_drv_init(&disp_drv);                    /*Basic initialization*//*Set the resolution of the display*/disp_drv.hor_res = MY_DISP_HOR_RES;disp_drv.ver_res = MY_DISP_VER_RES;/*Used to copy the buffer's content to the display*/disp_drv.flush_cb = my_disp_flush;disp_drv.full_refresh = 1;/*Set a display buffer*/disp_drv.draw_buf = &draw_buf_dsc_3;/*Finally register the driver*/lv_disp_drv_register(&disp_drv);
}

在开辟屏幕的2个缓冲区时,我并没有使用stdlib.h头文件中的malloc函数,而是使用esp_heap_caps.h头文件中的heap_caps_malloc函数,因为该函数可以决定内存空间开辟的方式,第二个参数填入MALLOC_CAP_SPIRAM,这样该空间会被强制开辟在PSRAM中。
如果我们用了双缓冲全像素刷新,记得在注册显示设备时加上下面的代码。

disp_drv.full_refresh = 1;

这样是告诉LVGL我们的程序可以进行全像素刷新。

接下来还可以进行一些额外的设置,我们可以在lv_conf.h文件找到下面的代码。

/*Default display refresh period. LVG will redraw changed areas with this period time*/
#define LV_DISP_DEF_REFR_PERIOD 20      /*[ms]*//*Input device read period in milliseconds*/
#define LV_INDEV_DEF_READ_PERIOD 10     /*[ms]*/

第一个设置的是屏幕的刷新频率,默认为30ms刷新一次,我设置到了20ms刷新一次,那么最高就可以有50fps的帧率。第二个是设置输入设备的采样频率,默认为20ms采样一次,我设置到了10ms,这样可以尽可能提高触摸的灵敏度。

总结

可能有同学在设置了上面的参数后仍然发现屏幕好像还是卡卡的,这是因为以上都是在软件层面进行的优化,软件的优化是有限的,不如直接在硬件上进行优化。
就比如,我使用的屏幕虽然只有240X240的分辨率,但它使用的是SPI协议进行通信,相比起使用8080并口的显示屏,刷新速度肯定是大打折扣的;前者每次传输1bit,但后者每次可以传输8bit或16bit,这个差距是巨大的。
又比如,PSRAM虽然有4MB的空间,看上去很大,但它走的也是SPI协议;而我们平时用的SRAM或SDRAM都是使用好几个管脚进行寻址和传数据,速度上面没得比。但PSRAM的好处就是空间大,SDRAM、SRAM的空间一般只能做几百KB。

【ESP32】Arduino+LVGL 如何使用PSRAM优化显示相关推荐

  1. 【ESP32 S3开发】在Arduino IDE中使用PSRAM

    一.前言 最近使用ESP32 WROOM开发语音识别项目时,需要使用阵列麦克风采集信号,并进行切片取出含有语音部分的片段,进而使用base64编码将语音上传到后端服务器进行识别. 在项目开发时,发现虽 ...

  2. 【arduino 问题记录】 psram: PSRAM ID read error: 0xffffffff

    问题描述:采用ESP32-s将数据通过4G模块发送到阿里云的时候,只要数据一发送,esp32-s就一直重新连接4G模块. 图一中红色框就是我要传输到阿里云的内容,蓝色框显示的就是报错信息,接下来显示的 ...

  3. 燃起来 ESP32移植LVGL最新版本8.2

    零. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:ESP-IDF基本介绍,主要会涉及模组,芯片,开发板的介绍,环境搭建,程序编译下载,启动流程等一些基本的操作,让你对 ...

  4. 服务器.esp文件,ESP32 Arduino教程:通过软接入点(soft AP)实现HTTP服务器-esp文件

    在本ESP32(http://www.dfrobot.com.cn/goods-1359.html)教程中,我们将检查如何设置一个异步HTTP web服务器,该设备作为软访问点运行. 本ESP32教程 ...

  5. 评审系统:查看互评信息实现及优化显示

    强烈推荐一个大神的人工智能的教程:http://www.captainbed.net/zhanghan [前言] 为了培养更多的人,最近组长准备将廊坊一中交接给下版人员,从而让更多的人从中受益:但是在 ...

  6. ESP32 Arduino Ticker定时库

    Ticker是ESP32 arduino的自带库,可以设置以固定时间间隔反复执行某个任务,特别适合以固定频率从传感器收集数据. 计时器本质上是一个计数器.让我们举一个简单的例子.如果给你一个可以从0到 ...

  7. 乐鑫ESP32移植LVGL 7.10

    零. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:ESP-IDF基本介绍,主要会涉及模组,芯片,开发板的介绍,环境搭建,程序编译下载,启动流程等一些基本的操作,让你对 ...

  8. ESP32+arduino智能浇水系统

    一.ESP32+arduino智能浇水系统 随着人类居住条件的改善及对生态生活环境的关注,花卉养殖得到社会和人类个体的重视.这些具有生命特征的植物需 要科学合理的人工照顾.本研究提出了利用ESP WR ...

  9. Arduino UNO+ MAX7219驱动8X8点阵显示+Proteus仿真

    Arduino UNO+ MAX7219驱动8X8点阵显示 Proteus仿真 所需库:LedControl 取模软件:pctolcd2002 图像取模:8X8点阵 取模注意,需要右移一个像素,请照着 ...

最新文章

  1. UA MATH567 高维统计专题2 Low-rank矩阵及其估计3 Rank RIP
  2. tensorflow:Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
  3. 【数据结构与算法】之深入解析“K个一组翻转链表”的求解思路与算法示例
  4. 使用DPAPI加密或解密你的数据
  5. hdu1024Max Sum Plus Plus
  6. 单体预聚合的目的是什么_高分子化学实验指导书-修改-2012
  7. python pip install syntaxerror_解决pip install xxx报错SyntaxError: invalid syntax的问题
  8. 6-1 稀疏矩阵求和 (70 分)
  9. 什么样的技术最后会成为CTO
  10. 分布式锁与实现(二)——基于ZooKeeper实现
  11. TOGAF 知识点整理
  12. JAVA数据库宾馆住宿系统_java+数据库 宾馆客房管理系统
  13. 开源项目:BottomBar
  14. CEC循环生态社区答疑XAG到底有多好的价值前景
  15. 贵州省那些大学有计算机专业,贵州大学的计算机专业全国排名第几?
  16. 哪个国家程序员最多?不是美国和中国,是这个‘落后’的亚洲国家
  17. 大话设计模式——外观模式
  18. Substance Painter:常用快捷键
  19. 科技代表未来发展方向 人工智能等四类67只科技蓝筹股值得长线布局
  20. 利用Crowbar抓取网页异步加载的内容 [Python俱乐部]

热门文章

  1. Kubernetes系列(一)基于CentOS8部署Kubernetes1.19集群
  2. 计算机无法检测电池损耗怎么办,笔记本电脑如何检测电池损耗程度-鲁大师检测电池损耗的方法 - 河东软件园...
  3. python str怎么用_python的str函数怎么使用
  4. conda使用清华镜像安装pytorch
  5. 要善于借势破局——宁向东的清华管理学课第4课
  6. 几家大厂求职与面试(一):Java必备,不看就是遗憾
  7. IC设计书籍信息收集
  8. 关于物联网的各种转换,16进制 二进制 10进制 效验总结
  9. C#删除word页眉页脚和最后一页
  10. android 蓝牙地址连接打印机,android 连接蓝牙打印机 BluetoothAdapter