上一篇:
(STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(3)使用DMA
经过前几章的搭建,底层显示已经没有问题了,现在需要添加上层的库,我选择了比较火的开源GUI库--LVGL。而RT-Thread Studio支持直接添加LVGL代码库的。
在RT-Thread Settings中选择添加软件包:
直接搜索LVGL,然后添加:
然后保存 RT-Thread Settings 即可。
添加完成后我们需要把官方给的几个接口文件的模版添加到我们的应用代码里面,这些模版文件路径为:
packages\LVGL-latest\examples\porting
其中它们分别是:
最后还需要一个LVGL库的配置模版lv_conf_template.h,它在packages目录下。 把这几个文件名字中的模版后缀(template)去掉,添加到application文件夹下:
这时候编译会报一些错误:
主要是lvgl_thread_entry函数中找不到相关函数的定义:
看名字也该知道这几个就是我们刚才添加的模版文件相关的。我们仔细看一下这lv_rt_thread_port.c 这个文件,发现里面包含一个自动初始化的 lvgl_thread_init 函数,然后这个函数创建了一个 "LVGL" 的线程,现在是线程入口函数找不到相关定义。可以看出来,RT-Thread Studio已经帮我们生成好一部分代码了,我们现在只需修改接口模版文件适配我们的板子即可。
这里我暂时不使用lvgl的文件管理和输入设备,只保留显示:
打开几个模版文件可以看到,其实文件都被宏定义#if 0给注释掉了,所以现在使用哪个开哪个模块,但是lv_conf.h是必须打开的。然后修改模版文件中的头文件,也把后缀去掉:
然后在工程编译命令中添加宏定义 LV_LVGL_H_INCLUDE_SIMPLE :
应用后保存。然后在 lv_port_disp.c 中修改屏幕大小,根据实际硬件设置:
然后LVGL给了三种初始化的方法,可以参考:
https://www.xyhtml5.com/22577.html
这里我选用第三种,把另外两种注释掉即可:
然后这个函数下面对buf的引用修改一下,修改为刚才使用方式3创建的:
然后我们只需要完善两个接口函数disp_init和disp_flush即可:
注意这里坐标系是朝下的:
在mlcd.c中添加函数,这里使用区域绘制函数(如果使用一个点一个点的描点函数,则会非常卡):
其实就是套个壳,然后直接在disp_flush中调用:
注意这里调用的mlcd_fill_rectangle其实最底层调用的是ST7735_FillRGBRect,这个函数的参数是宽、高,而不是坐标!我们想刷新整个屏幕时,刷新的区域是坐标(0,0)到(159,79)的矩形范围,但是转化为宽高则是起点为(0,0),宽为160,高为80的范围。我一开始没有+1,导致lvgl绘制出来的画面都是斜的,调试了很久都没有发现原因,太坑了。
最后再开启两个宏定义:
我们还需要给告诉LVGL时间,可以把lv_tick_inc加到SysTick_Handler函数里,参数单位是毫秒:
或者使用LVGL的宏定义,修改如下,注意头文件要换成你自己对应芯片的头文件:
以上两个方法只能选其一。
再修改一下LVGL分配的内存,原始直接分配了128K,太大了,现在修改为10K:
可以修改lv_hal_disp.h中的 LV_DEF_REFR_PERIOD去修改FPS的上限,否则最高30!
如果发现显示的颜色有异常,可能是因为颜色是uint16类型的,但是SPI传输是uint8类型的,所以要注意大小端,可以在ST7735_FillRGBRect函数中修改:
写一个简单的文本显示测试一下:
int main(void)
{
key_init();
lv_obj_t* label = lv_label_create(lv_scr_act());
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);//过长会滚动
lv_obj_set_pos(label, 0, 0);
lv_obj_set_size(label, 100, 16);
lv_label_set_text(label, "Something project V1.0!");
while (1)
{
rt_thread_mdelay(1000);
}
return RT_EOK;
}
很丝滑~
推荐:
LVGL显示优化—基本优化