我们重视您的隐私
通过点击「允许所有 Cookie」,代表您同意在您的设备上存储 Cookie 以增强网站浏览体验、分析网站使用情况并协助我们的营销和网站效能优化工作。您可以在我们的隐私权政策中找到有关于此的更多信息。
TouchGFX 是由 STMicroelectronics 提供的嵌入式系统设计的图形用户界面(GUI)开发框架,旨在针对 STM32 微控制器(MCU)芯片,提供设计对象情景显示的能力,协助 STM MCU 用户构建流畅、精美、多样化的 UI 页面。
以下示例以 TouchGFX 版本 4.23.2 为例:
图1. TouchGFX 启动界面,可见选项 Example、Demo、Create Board chip 等页面
TouchGFX 程序架构部分采用 Model-View-Presenter(MVP)模式为主轴,如图2所示,具备以下优势:
各层分离(Separation of Concerns): 程序代码在不同阶段有各自的维护方式,便于用户编写界面并与底层进行通信,结构清晰易于理解,具备高度可复用性。
单元测试(Unit Testing): 上层的 View 可与 GFX 生成的代码直接作用,更容易进行独立验证。
图2. TouchGFX 各层关系图(MVP)
View: 由 GFX 生成的显示页面,是界面设计的第一阶段。通常作为 MVP 架构上层的被动端,处理所有 UI 界面设计信息,并根据所使用对象的属性,生成相应的显示内容。
Model: 是处理与发送数据的主要核心。一些传输的通信数据包在经过判断或处理后,将通过 Presenter 向 View 发出指令,改变 View 当前显示的内容与对象状态。
Presenter: 作为 View 与 Model 的通信桥梁,可从 Model 获取数据,使函数得以重复使用。
由于固件(Firmware,简称 FW)的设计理念着重于以 Model 作为命令处理的主控,因此可绘制出如图3所示的架构图。
系统底层会根据不同接口(如 CAN 总线、RS485、UART、蓝牙、Wi-Fi 等)进行端口处理,将数据转发至 Model 进行通信,再通过 Presenter 传递至 View,最终实现对象状态的切换。
图3. 多接口与 MVP 架构之间的通信
因此,我们可以通过两个示例说明数据交换的流程:
Sample 1: Host 发送 CANopen 指令给 Device(图4)
当 Host 发送 CANopen 指令时,CANopen 协议将通过 Interface 端口接收数据包,并由 CAN task 解析内容。解析后的数据将传送至 Model,由 Model 更新数据库并执行相应命令操作。随后,结果通过 Presenter 传递至 View,完成界面更新。
图4. Host 发送命令示例
Sample 2: 用户触控 Device UI 元件,并回传 touch event 至 Host(图5)
当用户点击具有触摸功能的对象时,View 会触发一个 click event,随后通过 User Event 经由 Presenter 传送至 Model。Model 再根据当前所使用的接口,将事件回传至 CAN task 中对应的代码,最终通过 CAN 端口发送 TX 数据包,通知 Host。
图5. 用户触控事件回传 Host 示例
在TouchGFX软件界面上,设计N页便会生成对应N组的View及Presenter,但只会有一组Model,用来做所有view page的控制。
当使用者设计出UI情境,包含图形、样貌、坐标、文字显示等,在点击Generate Code后,会在对应名称的view page生成程式码。
生成的资料夹分为 ..\generated\ 与 ..\gui\, 路径,通常 ..\generated\ 是设计页面显示的情境, ..\gui\ 是加入物件互动的逻辑。
我们可以透过这样的信息,去调用物件在各自页面上,并参考可设计与使用的代码。
以下是一个简单的说明步骤,讲解上述描述的部分:
例如:
1. 若我们先开启一个空专案,并点击Create建立一个Project(图6)。
图6. GFX开启专案画面
2. 在TouchGFX内会有预设的Screen1,我们新增一个新物件button,选择想要切换的图资后,执行Generate Code。(图7)
图7. Create Button示意
3. 接下来切换到专案名称的路径底下会多两个资料夹 gui 与 generated (图8):
图8. 专案资料夹内容
其中 generated 资料夹下放的是与GFX设计页面的基础代码,存在着Screen1组成元件的相关Command及function。都是由TouchGFX自动生成,不可被直接修改或取代。若变动页面的物件状态再重新生成代码,就会让generated资料夹下的代码更新。
同样地,可以发现GFX在执行Generate Code后,会在Screen1ViewBase.cpp底下生成 ..\generated\gui_generated\src\screen1_screen 的程式码(图9)
图9. Screen1ViewBase.cpp位置
若将 Screen1ViewBase.cpp 用 Notepad++ 打开来看(图10)。里面是建构出Screen1页面的属性与button资料的内容
- 设置Button坐标:
button1.setXY(63, 109);
- 设置Button图片ID:
button1.setBitmaps(TouchGfx::Bitmap(BITMAP_BUTTON_00_00_ID),TouchGfx::Bitmap(BITMAP_BUTTON_00_00_ID));
- 将Button物件加入页面使用:
Add(button1);
图10. Screen1ViewBase.cpp内容
XXXBase.cpp 命名的代码,会在Generate Code时重建并修改变更的属性数据。因此,若我们调整Button的位置、图片等,包括上述函数的Function也可能会发生变更。
至于 gui资料夹,则是TouchGFX保留给使用者撰写程序逻辑的位置(图8),所以MVP架构也建构在这之下(图11)、(图12),我们可以透过自己规划MVP的代码沟通方式,实践UI的设计方向。
图11.Model 所在路径
图12. Presenter and View所在路径
4. 我们可以设计出一个简单情境来做更详细的gui/generated设计说明:
- 撰写一个button与 text互动的逻辑控制。
- 当点击button一次时,text数值增加。
以下是实现此功能的作法:
拖拉2个物件,一个button: button1与一个Text: textArea1物件(图13)。
图13.放置Button控制的UI设计专案
点击右侧栏位的interactions,新增一个Button click Event,并选择在执行此动作后,会在程序里调用 add_number 这个函数(图14)
图14.新增一个Interaction1 Event
观察 Screen1ViewBase.cpp (图15)可以发现建立了 button1 及 textArea1 的相关属性代码。
并因为新增了interactions,生成了 buttonCallbackHandler 去承接button1触碰的event,当点击下去后,透过callback function寻找名为add_number的函数。
图15: Screen1ViewBase.cpp
Screen1ViewBase.hpp 的内容(图16)
图16: Content of Screen1ViewBase.hpp
在gui底下添加的Screen1View.cpp 及 Screen1View.hpp。
新增函数add_number,利用count参数进行数值累加(图17)(图18)
并用 Unicode: snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%02d", count);重新将变更后的count导入到textArea1中。
之后用textArea1.invalidate刷新数据。
图17. Screen1View.cpp内容
图18. Screen1View.hpp内容
执行模拟器后,即可确认每次点击 button1,textArea1(count value)会从0开始递增(图19)。
图19.显示模拟器结果
由此可以确认物件属性的定义通常建立在generated路径,使用者撰写逻辑执行代码则在 gui底下操作。
华凌提供的 Smart Display GUI Builder 是一款拖曳图控对象UI/UX的接口设计工具,为客户提供无需编程的使用服务,适合快速开发、设计有关的 ST MCU 产品;作为TouchGFX框架上的扩展延伸,GUI buidler整合了TouchGFX原有的Widget功能,其主要差异在支持多种不同的系统接口与通讯协议,让用户能够直接观察到指令是如何对Widget的控制变化。
以下是Builder的介绍:
https://www.winstar.com.tw/zh-cn/video/play/142.html
Smart Display GUI Builder 的设计与TouchGFX相关,包含fw撰写是使用stm32 mcu建构出的MVP为基底,里头的对象都是用现有的item加上逻辑所设计而成。
因此从 GUI Builder 所开放的对象中,有些项目我们可以使用现有的 TouchGFX UI Components 去实现对应的显示结果。
*补充说明片段
以下是一个简单的例子,采用 Builder 的 slider 为说明(图20):
图20.Builder slider属性页面
Builder Slider 的属性如下:
Size:
- Width: 618
- Height: 20
Positions:
- Background Position (X): 0
- Background Position (Y): 4
Indicator Position:
- Min: 0
- Max: 580
- Pos: 0
这些参数是可以对应到 TouchGFX 里面的 Slider Component 设置(图21)。
图21. TouchGFX的Slider属性
TouchGFX Slider 的属性如下:
Location:
- Width: 618
- Height: 20
Positions:
- Background Position (X): 0
- Background Position (Y): 4
Indicator Position:
- Min: 0
- Max: 580
- Y: 0
使用者可以透过 GFX 调整 Values 的 Start 值去模拟它在 Builder 上面执行的结果(图22),若将值设为100,可在 builder 模拟出相同结果(图23)。
图22. TouchGFX中调整Start = 100
图23. Builder中调整Test Value = 100
倘若我们将 GFX generate code 构建出的 Screen1ViewBase.cpp 拿来看(图24)
图24. Screen1ViewBase.cpp function
即可明白上列参数所用到的函数与程序可以如何被使用与修改,且这样的数字是与 GFX project 的设计直接有关系。也是当 Builder upload project 后,重新设定给 Device 的 Slider 初始参数。
假如 Host 对 Device 发送命令,去改变 Slider 的数值,则会在 MVP 架构中,在view 里面执行slider1.setValue() 去完成对象的变化(图25)。
图 25: Host sends slider command
以上是简易的 Builder 与 TouchGFX 的对象关联说明。
在确认 TouchGFX 有发表更新版本软件:4.24.0,可以发现有一些新的对象与功能可供使用,倘若我们需要做 Builder 是否能导入评估的话,可以优先尝试用 GFX 预设的范例来做 Demo 与研究(图26):
图26.各项范例Project
由于 4.24.0 版本有支持新的对象:QRcode
我们可以借此评估若导入 Builder 可用的参数与函数
以下用 QRcode 做范例说明:
1. 选择 BlankUI
2. 拉取 QRcode Container
3. 可观察能设定使用的属性有哪些(图27):
Location: (X, Y)
Configuration:
- QRVersion
- Scale
- Text
- Error Correction Code…
图27.QR code属性画面
相对的这些关于 QRcode 可以参考官网的说明图(图28)
图28.官网说明
在 Screen1ViewBase.cpp 产生的 function 中,确认属性能动用与使用的参数与设定(图29):
1.设定坐标:qrCode1.setXY(208, 224);
2.设定 QR code 版本:qrCode1.setQRCodeVersion(3);
3.设定 QR scale:qrCode1.setScale(5);
4.输入文字产生 QRcode 图码:
qrCode1.convertStringToQRCode("https://www.winstar.com.tw/zh-tw/");
图29. Screen1ViewBase.cpp 产生码
若未来 Builder 导入 QRcode 功能就可以开放这些能调整的参数给使用者设定。
https://support.TouchGfx.com/zh-TW/docs/category/introduction
https://www.eettaiwan.com/20200203np21/
https://zh.wikipedia.org/zh-tw/
https://www.winstar.com.tw/zh-cn/video/smartdisplay.html
通过点击「允许所有 Cookie」,代表您同意在您的设备上存储 Cookie 以增强网站浏览体验、分析网站使用情况并协助我们的营销和网站效能优化工作。您可以在我们的隐私权政策中找到有关于此的更多信息。