
在 Arduino 环境下为 掌控板3.0 移植 LVGL

说在前面
前一篇文章我向各位介绍了如何使用 PlatformIO 为 掌控板3.0 搭建 Arduino 开发环境,今天我们不妨更进一步,在这个环境上简单的移植一下 LVGL。
在很多文章和相关内容中我已经多次介绍了 LVGL,这是一个免费且开源的图形库,提供了创建嵌入式 GUI 所需的一切,包括易于使用的图形元素、美丽的视觉效果和低内存占用。
在掌控板3.0上,产品方使用了更高性能的 MCU,同时还有一块 320x172 的 TFT 彩屏,在官方的 MicroPython 环境中也默认打包了 LVGL 的 MicroPython 绑定,所以在我们的 Arduino 环境下使用 LVGL 是有必要的。
安装相关依赖库
首先你应该要新建一个 PIO 项目,如果你没有新建或者说你不知道我在说什么,建议你先去前一篇文章进行阅读与操作。
本次移植,我采用的方案是使用 TFT_eSPI
用作 LVGL 的支持驱动,首先进入 PIO Home,点击 PIO Home 侧边栏的 Libraries
,搜索 TFT_eSPI
,点击 Add to project
,再在弹出的窗口中按提示选择将被添加进的项目,最后点击 Add
即可。
安装 LVGL
同理。
配置及测试 TFT_eSPI
TFT_eSPI 是一个著名的 Arduino TFT 驱动库,我们首先要正确配置它并使其可用,为下一步使用 LVGL 做好基础。
我们的目标是在掌控板屏幕 (10, 10) 的地方正确显示一行蓝色文字“Hello World”,屏幕使用白色填充,实机效果如图:
我使用 User Setup 文件来进行配置。打开项目根目录下的 \.pio\libdeps\mpython_esp32s3_r8n16\TFT_eSPI\User_Setup.h
,按照以下截图进行修改。
左侧为原始内容,右侧为修改后内容。
注释掉开启的 ILI9341 驱动,开启 ST7789 驱动
配置屏幕宽高(事实上仅需要使 TFT_WIDTH
为 172 即可)
注释默认引脚配置,手动配置相关引脚,同时关闭颜色反转
一些杂项配置
需要注意的是,引脚部分我参考了官方 MicroPython 环境源码中的相关配置文件。
以及最后一个更改(line 377),我并不清楚 HSPI 是什么,但是不开启该特性将导致 Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
问题,开启了又会有 [ 989][E][esp32-hal-spi.c:215] spiAttachMISO(): HSPI Does not have default pins on ESP32S3!
报错,但此时可以正常点亮屏幕,我查询相关资料无果,希望读者能给出解答。
保存,进入 /scr/main.cpp
写入以下内容:
1 |
|
此时再编译并烧录,你将会看到如本章节开头的效果。
但是,大概率事实不是如此 /_ \
我有一个朋友之前在跟掌控板3.0写 framebuf 驱动的时候就遇到一个很匪夷所思的问题,就是屏幕方向的问题。具体问题我们不在这里叙述了,我们只看看他最后解决问题后探索出的一点事实:
这张图展示的是硬件上的方向,至于为什么使用官方 MicroPython 环境没问题,因为在软件上解决了。
在解决问题之前,不妨先看看当前的效果:
其实主要的问题是显示的内容左右镜像了,那我们才说的方向问题哪去了?其实 tft.setRotation(1);
这一行代码已经解决了方向问题,我们注释掉这一行重新编译烧录再看看效果:
可以看到内容的显示方式与上文的屏幕方向示意图基本一致。
针对屏幕显示镜像的问题,我想到的两种解决方案如下:
- 在配置文件中寻找是否有显示镜像相关的配置,如有,进行配置
- 在
setup()
函数内直接调用TFT_eSPI
实例的writecommand
方法,向屏幕发送0x80
命令(在 TFT_eSPI 里它有个上层封装,即TFT_MAD_MY
- 直接修改
TFT_eSPI
的setRotation(uint8_t r)
方法(修改内容就是加一行向屏幕发送命令,与上一种方法大同小异)
显然,(至少是我)会优先选择更简单,更具有可移植性,具有更小侵入性的方案一,但是我足足找了半个小时属实是没找到这样一行。没办法,只好选方案二或者方案三了。
后两者其实大同小异,本质都是向屏幕发送特定的命令使显示内容镜像。但是前者有个不太优雅的问题,阅读 setRotation(uint8_t r)
方法的实现可知,其的每一次操作均会覆盖原有命令,这意味着生产环境中我们1每使用一次该方法就要再写一行代码重新发送镜像命令,这哪里能忍,可复用性实在是太低了 (゚Д゚*)ノ
所以我最后还是在 更低侵入性 和 更高可复用性 之间选择了后者。
说回正题,setRotation(uint8_t r)
方法的实现在 /.pio/libdeps/mpython_esp32s3_r8n16/TFT_eSPI/TFT_Drivers/ST7789_Rotation.h
哦我还要提一嘴,setRotation(uint8_t r)
方法其实是个二次封装,各位一看实现就知道了,不用多说:
1 | /*************************************************************************************** |
好的,那我们怎么修改 ST7789 对应的内容呢,看一下我的修改:
1 | // This is the command sequence that rotates the ST7789 driver coordinate frame |
其实我就是把每一种匹配模式下 writedata
方法的传参更改了,改动的地方不多,但确实挺烧脑的,不信你可以试试自己改改,虽然不要一会就能改完,但最开始那种⌈左右脑互博⌋的体验正是那张示意图 猎奇 的体现。
配置及测试 LVGL
好的,准备工作这才结束,现在我们来配置 LVGL 并进行测试。我个人认为这一部分比前面的步骤要简单些,第一是该解决的显示问题我们基本已经解决了,驱动层没有问题了,第二是 LVGL 的相关资料通用性高一些,我可以直接抄袭借鉴 ¯_(ツ)_/¯
首先我们要找到 /.pio/libdeps/mpython_esp32s3_r8n16/lvgl/lv_conf_template.h
,这是 LVGL 的配置文件示例,我们将其复制一份放到 /.pio/libdeps/mpython_esp32s3_r8n16/
,并将其更名为 lv_conf.h
。
然后进行如下必要的修改:
说实话,我也不知道 line 1250 这个地方是否需要修改,因为好像不改照样用的了(?)
然后还有很多可自定义的可选项,这个看你自己了
接下来我们前往 /.pio/libdeps/mpython_esp32s3_r8n16/lvgl/examples/arduino/LVGL_Arduino/LVGL_Arduino.ino
,复制里面的内容,把这些代码扔到 /scr/main.cpp
里面。
PIO 下的 Arduino 不能省略任何文件包含命令(这条针对的就是 Arduino.h
),你要做的第一件事就是要在其中补全它:
1 |
然后在 line 20 附近,修改代码:
1 |
说个题外话,事实上这个 LV_DISPLAY_ROTATION_90
的值就是 1
(二次封装,不过更语义化了),并且下文的 lv_display_set_rotation(disp, TFT_ROTATION);
这个函数本身其实就是 setRotation(uint8_t r)
方法的二次封装(顺便还把面向对象砍了,因为 LVGL 用的是纯 C 的写法)
编译烧录,LVGL 已经在 掌控板3.0 跟 Arduino 打招呼了 (‾◡◝)
Hello Arduino, I’m LVGL
- 标题: 在 Arduino 环境下为 掌控板3.0 移植 LVGL
- 作者: W-Can1425
- 创建于 : 2025-08-31 13:34:40
- 更新于 : 2025-08-31 17:49:24
- 链接: https://can1425.flowecho.org/2025/08/31/20250831/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。