背景介绍
近几年,由于半导体行业的大力发展,配备图形界面的嵌入式设备已经越来越多的出现在我们的生活中。传统家电,比如洗衣机、微波炉,原始的机械按键都逐渐被显示触控按键替代;穿戴设备,配备显示屏的电子款手表手环,开始占据越来越大的市场份额;汽车领域,开始使用触控屏按键取代传统机械按键,LCD仪表盘也几乎将指针仪表盘淘汰。因此,能够进行界面显示、交互的微控制器也越来越受市场的青睐。
恩智浦i.MX RT系列MCU性能强大、主频高,并且其中部分MCU配备了图形处理外设,是绘制图形界面非常好的选择。
本文通过一个基于恩智浦推出的LVGL图形设计工具GUI Guider,和运行在i.MX RT1170上的图形界面工程,来介绍在i.MX RT系列MCU上进行图形界面的设计。
工程演示视频如下所示:
界面设计软件GUI Guider
GUI Guider是恩智浦为LVGL推出的一个GUI软件设计工具,旨在让客户在使用恩智浦芯片开发LVGL图形界面工程时,能够更方便的设计出精美的界面。
打开工具,选择新建项目,接着可以选择你所用的LVGL版本以及你所用的MCU、显示屏、项目模板等。需要注意的是,本项目选用1280*720的显示屏(即landscape模式),在设备选择时注意不要选成720*1280。
图1. GUI Guider工程创建&屏幕选择
在界面基本创建好之后,GUI Guider工程如下图所示:
图2. 界面创建完成
本文只用GUI Guider做界面布局,界面的图标都用了贴图控件,并未选择工具中的其他功能控件。
如果想了解GUI Guider的用法以及各种控件的知识,可以翻阅本站前期的文章和NXP官方网站,在此不对GUI Guider做过多的介绍。
功能任务
在GUI Guider工程创建完成后,可以在对应的文件夹下找到创建好的工程文件(GUI-Guider-Projectsxxxxgenerated),其中包含了在工具中绘制的界面文件、添加的事件文件及图片字体的存储文件等。
值得注意的是,当我们创建好界面工程,开始添加自己的逻辑功能代码时,需要放在’custom’文件夹中,如果放在了你工程的源文件中(GUI-Guider-ProjectsxxxxsdkCoresource),那么当你不小心进行了工程的更新之后,你所写的逻辑功能代码将会被覆盖,别问我是怎么知道的。。。
介绍完了在GUI Guider中创建工程的注意事项之后,开始介绍本文的功能任务。
1、LVGL任务 利用GUI Guider创建的LVGL工程,可以参考SDK中的“SDK_2_12_0_MIMXRT1170-EVKoardsevkmimxrt1170lvgl_exampleslvgl_guider”,两者具有相同的结构。 在前面的演示视频中,可以看到,本工程模拟一个汽车仪表盘,在开机以及行驶过程中的显示情景。本工程用于展示其显示功能并未展示GUI的交互功能,绝大部分都是用了贴图来进行界面的填充,想要达到动画的效果,可以通过创建、删除图像控件或者对图像控件进行透明度设定来实现。 在LVGL中参考如下两种方法:
lv_obj_create(lv_obj_t * obj) //创建对象
lv_obj_del(lv_obj_t * obj) //删除对象,结合创建对象功能以实现动画效果;
lv_style_set_img_opa(lv_style_t * style, lv_opa_t value) //设置某个样式的透明度值
lv_obj_add_style(lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector) //给所选的图像添加透明度为0或者1的样式,以实现动画效果;
本工程所选用的方式为设置图像透明度。先利用GUI Guider工具将所需要的全部图像按照上下层顺序贴好,注意,一定要确定好放置的次序,否则在后续添加逻辑代码实现动画效果时会与预期效果不同。
比如界面中的右转向灯,在设置相应的位置后,在工具右侧‘Attributes’栏下面,可以通过‘Opacity’选项设置其初始透明度。
图3.设置对象透明度
在后续程序运行中,再通过逻辑函数修改各图像控件的透明度来达到动画的效果。
为了充分利用有限的存储空间,我们往往需要将代码进行最大化的“瘦身”。而在LVGL工程中,很重要的一点,就是将我们没有用到的模块裁剪掉。打开’ sdkCoresource’文件夹下的lv_conf.h文件,我们可以看到有许多开关宏,LVGL中的控件都通过这些开关宏来确定是否加入编译。这里我们将没有用到的控件,比如Arc, Bar, Checkbox等都关闭其宏定义,这样可以减少编译的文件,从而给代码“瘦身”。
图4. 进行LVGL控件裁剪
2.RTC任务
在常见的汽车仪表盘中,都会有日期时间的显示。本工程中在界面绘制时也添加上了此模块。在上面视频演示中可以看到,在初始开机界面没有添加此部分,而后在表盘界面就添加上。我们需要做的是在GUI Guider布局界面时,在对应位置添加上对应格式的文本控件。
图5. 添加日期、时间对象
在界面布局完成后,添加我们的逻辑代码。首先进行RTC模块的初始化,通过宏设定初始的日期以及时间,添加时钟任务,并设定好每一秒钟进行计时的更新。再添加时间文本转换函数以及文本更新函数,就可以开始进行日期、时钟的显示。
但是,我总不能每次都通过修改宏来设定时间吧?别急,本工程还添加了运行中修改时间的功能。接着往下看。
3. SHELL命令任务
SHELL命令任务可以帮助在程序运行时候进行负载分析等功能。本工程中添加了通过SHELL命令设置时间的功能,现在就来以此功能为例,讲讲SHELL命令任务的添加。
首先添加一个SHELL_TASK线程,在此线程中,进行虚拟串口的配置,SHELL命令的添加等操作。在’settime’命令中,以“settime y/m/d/h/m/s”的格式进行日期及时间的设置,之后你所设置的文本将被传到RTC任务中设置时间的函数中,这样就达成了利用SHELL命令,通过USB口设置当前时间的功能。
图6. SHELL命令修改界面时间
为了配合SHELL命令任务,在时钟任务中,需要将更新时间函数分为手动更新和自动更新。手动更新时,SHELL任务中配置一个值,当时钟任务判定这个值为手动配置信号时,将SHELL任务中更新的日期时间值传到时钟任务中,完成时间修改操作;自动更新则是当时钟任务判定到非手动更新信号,则进行时间的自动更新,不过需要注意的是,当我们进行自动更新,调用更新函数时,需要在界面配置函数完成日期时间文本控件的创建之后,否则函数运行会出错,这里也通过一个来自LVGL任务中创建日期时间文本控件之后的值,来进行时间自动更新的操作。
if (g_timeupdated) { /* Set RTC time to default time and date and start the RTC*/ SNVS_HP_RTC_StopTimer(SNVS); SNVS_HP_RTC_SetDatetime(SNVS, &g_rtcdate); SNVS_HP_RTC_StartTimer(SNVS); rtcDate = g_rtcdate; g_timeupdated = 0; } else { /* Get date time */ SNVS_HP_RTC_GetDatetime(SNVS, &rtcDate); if (s_time_initialized){ draw_date_Time_update(); } }
总结
在创建图形界面工程的时候,我们可以先利用GUI Guider工具将所需要的界面布局设计好,对于各控件,可以在工具中修改其各项参数,但值得注意的是,工具中并未包含所有的参数,有些时候我们可以通过自己修改代码来进行界面的设置。之后将没有用到的模块裁剪掉,以减少代码的大小。
在界面创建完成之后,我们可以添加自己的逻辑代码,实现自己想要的效果。
本文以一个汽车仪表盘图形界面的工程为例,给出了其开发的过程以供参考。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !