Simple移植到GD32E230

关于SimpleGUI与本工程的背景介绍

我们在使用单片机进行屏幕现实的过程中,经常会遇到一个问题。直接裸机进行文字与图形显示不够灵活,如果需要做一些菜单等功能非常麻烦。所以在这种应用中,我们需要引入轻量化的GUI,最常见的应该是LVGL。但LVGL对小容量,低性能的单片机并不友好,需要占用很多资源,其中大部分的功能也不需要用到。
SimpleGUI是一款针对单色显示屏设计的接口库,impleGUI相比于传统的GUI框架,SimpleGUI移除了诸如心跳、绘图缓冲、图层等概念,仅提供各种各样的绘图接口、以及由这些绘图接口绘制出的更复杂的图形组件,以此来降低整整体对系统资源的需求。
在尽量节省资源的前提下。simpleGUI提供了Simple GUI提供了:
- 点、线、基本几何图形、单色位图、文字等的绘制功能。
- 列表、进度条、滚动条、提示框、曲线图等复杂部件的显示功能
这些功能足够支持相当一部分的应用开发了。但SimpleGUI毕竟是一个单色屏的GUI,但是我们现在往往应用的都是IPS彩色屏幕了。
那么SimpleGUI能不能应用于彩色屏幕呢,如果我们放弃在菜单栏,曲线图的应用中进行彩色显示,只显示单色,而在图片显示等其他需要彩色显示的场景自己进行填充绘图等操作,还是可以用到GUI的功能降低开发难度的。所以:
本文致力于将SimpleGUI移植于GD32E230单片机上,并应用于1.14英寸彩色IPS屏幕。
在这里介绍一下基本的思路:为GUI建立一个135*240分辨率的bool存储区域,进行显存的显示,对应GUI的读点写点。另外写一个函数将显存中的点进行着色,每次着色一小块的显示区域,然后刷新到屏幕上去。这是一个尽量兼顾存储压力,显示刷新速度,UI流畅度的设计。
建立工程

首先,请先依照个人习惯,创建一个空白的用于目标平台的工程。工程应保证能够正常编译且添加的代码能够在目标平台上正常运行。 然后请在您的空白工程中实现LCD屏幕驱动。
建立屏幕缓存

开辟一块内存空间为屏幕作为缓存时使用。
屏幕的像素数据存储在一个名为LCD_BUFFER的缓冲区中,该缓冲区是一个uint8_t数组,每个元素包含8位,每位代表一个像素的状态(亮或灭)。
实现写点函数

我们需要计算给定坐标的像素在LCD_BUFFER中的位置。由于每个uint8_t元素包含8个像素,所以我们需要确定目标像素位于哪个字节以及在该字节中的哪个位。
实现读点函数

我们需要计算给定坐标的像素在LCD_BUFFER中的位置。由于每个uint8_t元素包含8个像素,所以我们需要确定目标像素位于哪个字节以及在该字节中的哪个位。
实现清屏函数

将数组所有元素清零实现清屏
实现刷新函数

这个函数遍历LCD缓冲区的每一行,然后对于每一行,它遍历每个像素,检查并设置对应的颜色值到一个临时的buffer数组中。最后,它会将这个buffer数组写入到LCD的当前行。
配置工程1

添加引用路径
配置工程2

为三个文件夹各建一个组
配置工程3




分别添加文件
找到配置文件

接下来打开GUI\inc目录下的SGUI_Config.h文件,大致内容如下:
配置文件的修改

此文件中定义了SimpleGUI中用于全局配置的宏定义,默认状态下是为了在VirtualSDK环境下运行而配置的,所以直接编译会产生一些错误,为了规避这些错误,我们需要对文件项目做如下修改:
- 将宏_SIMPLE_GUI_IN_VIRTUAL_SDK_的定义注释掉。
- 将宏_SIMPLE_GUI_ENABLE_DYNAMIC_MEMORY_的定义注释掉。
此修改完成如下图:
配置DemoProc中的驱动调用

接下来添加演示代码中必要的驱动程序调用。
首先,需要将LCD驱动代码头文件引用至DemoProc.c
然后,需要打开DemoProc.c,并定位到InitializeHMIEngineObj函数,演示程序在这里向设备对象模型注册屏幕设备的操作接口。
定位Error语句

在这个函数中我们可以找到一句宏定义。
模仿上方的代码复制下来对接自己的屏幕驱动

在代码中,我们向设备对象模型注册了屏幕的读点、写点、清空、同步四个动作的操作接口。读点和写点分别是读取和写入屏幕上一个像素的值(0或1,通常0代表灭、1代表亮)必须注册;清空为清除屏幕的内容,如果没有注册,请将此位置置为NULL,SimpleGUI在处理时会通过像色操作清空屏幕,效率稍差;同步操作意为将显示缓存中的内容同步到屏幕显示,只有在启用显示缓存时才会用到。
这里的的显示缓存并不是由SimpleGUI来开辟和管理,而是由开发者来定义和操作。现实情况是因为现在几乎所有的单色屏幕,操作都是以字节为单位,一次控制八个像素,如果只想控制其中一个点而不影响其他七个点的话,那么就需要将这个字节读取出来,按位操作写回去。但是这些屏幕控制器在通过串行接口(IIC/SPI)通信时,通常只能接受写入操作,无法读取点,而且就算再并行操作下,读取操作也会比写入操作慢得多。
基于以上情况,我自己使用的解决方案就是在芯片内部开辟一处二维数组作为显示缓存,程序的读写都针对这个显示缓存进行操作,在操作完成后再调用同步函数,将显示缓存中的内容集中写入的屏幕。这样做的好处就是,第一,针对片内运存的操作肯定快于直接操作外设接口;第二,避免了读取屏幕的操作,对于屏幕设备来说只有写操作,大大提升了运行速度;第二,基于前一点,屏幕将可以不考虑读操作,直接工作再串行模式下,节省了GPIO的使用。
调用SimpleGUI

在main.c中引用DemoProc.h头文件
调用SimpleGUI

在初始化主程序以后调用下面两个函数,实现SimpleGUI的初始化与demo程序的运行。
下载运行

现在就可以下载运行了,可以看到Demo程序的运行结果。









