前言
工程基础:RT-Thread Studio TouchGFX驱动显示屏(可以参考着构建本文所需工程,文末附代码链接)
技术要点:TouchGFX MVP 架构、C++中调用C语言。
参考视频:TouchGFX教程(强烈建议新手观看,后半段有硬件双向交互原理讲解及演示)
参考博客:TouchGFX使用MVP架构来实现GUI和硬件的双向交互(原理也可参考这里,本文不再复述)
实验目的:
- 前一章已成功在7寸LCD上显示图像,继续加深对TouchGFX的学习。
- 单片机的图形界面相比电脑上位机的优势在于硬件资源丰富,硬件交互势在必行。
- 在公司产品做长时间运行测试时解放电脑,单片机采集到的数据实时解析处理并显示。
一、创建/导入工程
创建/导入工程二选一,目的是为了得到本次工程所需的基础代码。
(一)、新建工程
1、参考例子
使用RT-Thread Studio先创建出能正常显示和触摸的RT-Thread工程。可参考RT-Thread Studio TouchGFX驱动显示屏。
2、工程效果
随便跑的一个例程代码,加了个背景。
(二)、导入工程
若根据上述教程创建不出来,可以在本篇博客下方留言(都是小弟写的),会第一时间回答疑问并修改完善博客。当然,如果只对硬件交互感兴趣或其他原因也可以从这里下载我的代码快速上手。
1、先把下载的压缩包解压。
2、导入设置
打开RT-Thread Studio后点击左上角的文件、导入打开导入界面,选择RT-Thread文件夹下的RT-Thread Studio项目到工作空间中。
3、选择工程导入
点击右上角的浏览切换到解压文件所在的目录下点击确定,其他配置不需要改动。
4、编译下载
成功导入工程后,选中工程点击编译和下载即可。如果你用的屏幕尺寸和我的不同,请注意修改屏幕尺寸参数(之前的博客有交代)。
二、开发板 --> 显示屏
1、过程说明
如图所示,当开发板的按键被按下时,通过Model文件下的void Model::tick()函数获取到按键的事件,该函数在每一帧图像渲染前都会执行一遍;获取到事件之后需要通过MainPresenter.hpp和MainPresenter.cpp中自定义的虚函数将数据传到MainView.cpp和MainView.hpp的自定义函数中完成最终的显示。
2、按钮硬件
用户按钮PH4。
当用户按键按下时PH4为低电平,弹起时为高电平。
3、注册按钮
工程是在art_pi_blink_led基础上建立的,所以有LED灯的闪烁控制代码。
修改代码,验证按键是否能被正常捕获。(当按键按下LED灯亮,反之灭)
4、修改屏幕
打开TouchGFX工程,点击添加一个圆控件(Circle)并通过右侧的Color将控件改成其他颜色。
至此屏幕显示界面的修改完成。
5、Model.cpp
Model.cpp所在目录:
该目录下的Model::tick()函数在屏幕每次渲染显示前都会先执行一次,因此可以在这里实现按键的扫描。(之前main函数中的按键扫描测试可以删了)
修改后的代码:
- SIMULATOR:TouchGFX Designer模拟仿真时会定义该宏,使用该宏可以在模拟时将我们引入的函数屏蔽掉,避免无法仿真。
- external “C”:C函数在C++文件中被调用时需要以此声明才能被正确编译,其实这两个头文件里面已经有此声明了。
- Model::tick()逻辑:当按键被按下时,之前画的绿色圆形将被取反(隐藏/显示)。
- toggleLed():实现屏幕的控制函数,实际在MainPresenter.cpp中定义。
6、ModelListener.hpp
ModelListener.hpp所在目录:
在ModelListener.hpp文件内的public中toggleLed() 以虚函数的形式被定义, 以便在Model.cpp的tick()函数中被调用。因使用虚函数(virtual)定义,所以实际上toggleLed() 至此仍未被定义。
7、MainPresenter.hpp
MainPresenter.hpp所在目录:
因为在ModelListener.hpp文件中toggleLed()是以虚函数的方式被定义的,所以这里的声明也要使用virtual进行修饰。值得注意的是这里有对ModelListener.hpp进行包含。
因为使用了MainView& view,所以Presenter与View的连接可以通过“ view. ”的方式实现,从而在Presenter中调用View定义的函数。
8、MainPresenter.cpp
MainPresenter.cpp所在目录:
重点来了,说了这么久终于真正地对toggleLed()函数进行定义了。之前提到Presenter相当于Model和View连接的桥梁,Presenter通过虚函数的形式实现对Model的连接。(tips:点击函数左侧的绿色箭头可以快速跳转至被调用的地方ModelListener.hpp)
而Presenter与View的连接则通过“ view. ”的方式实现。
9、MainView.hpp
MainView.hpp所在目录:
在MainPresenter.cpp中想要以“ view.toggleled(); ”的方式调用toggleled()先得在此文件内对其进行声明。
10、MainView.cpp
MainView.cpp所在目录:
在此定义“ toggleled() ”函数实现控件的隐藏/显示。
11、MainViewBase.cpp
显示屏的相关控件可以在这里找到。只能看,不要改里面的代码!!!
12、结果验证
按下一次用户按键,实现一次屏幕中圆控件显示/隐藏的翻转。
三、显示屏 --> 开发板
1、过程说明
和之前的开发板控制显示屏相比,这是一个反向的控制过程。有了前面一些概念和实践的铺垫接下来就变得简单多了,首先使用TouchGFX在显示屏中添加一个按钮,然后添加一个事件将其与所添加的按键关联起来;当按下屏幕的按键,View中的函数被调用然后通过Presenter调用Model中我们添加的动作函数完成指定动作。
2、添加按键
3、绑定按键
4、生成代码
在完成按钮的添加及事件的绑定后点击右上角的生成代码即可自动完成代码的添加。之后来到MainViewBase.cpp文件中即可看到新添加的按键回调函数。(前面有每个文件所在目录的截图,之后不再复述)
MainViewBase.hpp亦可看到自动生成的虚函数。具体的函数名是在绑定事件时所修改的。
5、MainView.hpp
button()函数是当屏幕上的虚拟按键被按下时触发的,但是我们不能在MainViewBase.cpp中去实现它,因此在MainView.hpp中以虚函数的方式进行声明以便后面在MainView.cpp中定义。
6、MainView.cpp
在此实现button()函数,而button()函数向前调用MainPresenter.cpp中的函数。
7、MainPresenter.cpp
同理,定义一个中间函数让MainView去调用。
8、MainPresenter.hpp
老规矩,想要被调用得先声明。
9、Model.cpp
该文件中的led函数每调用一次开发板上的LED灯就会实现一次翻转。
10、Model.hpp
老规矩,懂的都懂。
11、结果验证
点击一次屏幕上的按键,开发板上的LED灯实现一次翻转。(有了前面的开发板 -> 屏幕的理解,这一实践视乎更容易理解了)代码下载:art_pi_touchGFX硬件交互(不用积分!!!)
四、进阶篇
虽然单纯点个灯也算是与硬件交互了,但是似乎有点太简单了所以加上了显示CUP使用率的显示和页面的切换。具体步骤就不再详述了,有了之前的工程应该问题不大。
现在好像上传不了视频,可在哔哩哔哩上看效果(小更改,连接LED的IO换到蜂鸣器了)。代码下载:art_pi_touchGFX硬件交互1.1
总结
上一篇博客似乎反响不错,所以花了一周的时间把硬件交互的整理了出来。虽然写博客很耗时间,但是在表达的过程中能加深理解又能帮到其他人还是挺不错的。
下一步打算做个串口接收工具,能把串口接收到的数据实时通过EasyFlash保存到SD卡的同时也显示在屏幕上,但对相关控件还不太熟悉,希望感兴趣有想法的能留个言给点思路。