1.引言
越来越多的智能设备会在 MCU 上实现图形界面,而 TouchGFX 是专门用于 ST MCU上的图形界面设计软件,使图形界面在 MCU 上能达到类似智能手机的显示效果。TouchGFX 图形引擎包括三部分:搜集、更新、渲染。其中在搜集阶段,图形引擎从外部环境收集事件,这些事件通常是触摸和按钮事件。TouchGFX 采样并将事件传递到应用程序,这样原始触摸动作就被转换为更具体的应用程序的触摸事件。例如,点击(用户在显示屏上按下或松开手指)、拖动(用户触摸显示屏并在显示屏上移动手指)、手势(用户向一个方向快速移动手指,然后松开)等功能,这些操作都会被图形引擎识别并转发给当前活动的 UI 元素。
本文主要介绍 TouchGFX 从显示器的触摸控制器读取触摸坐标,并将其传递给应用程序的方法及原理,使开发者能够很容易的在 TouchGFX 生成的代码中添加触摸功能。
2.TouchGFX 抽象层架构
TouchGFX 引擎通过 实例化了的HAL子类来访问 HAL。这些子类由 TouchGFX Generator生成,Generator 是创建抽象层的主要工具,可以生成反映 STM32CubeMX 配置的 HAL 部分,以及 CMSIS V1 或 V2 的 OSAL。通常 HAL 的架构如下图 1 所示。
TouchGFX 抽象层(Abstraction Layer,简称 AL)具有一套特殊的职责, 职责要么在AL (HAL)的硬件部分实现,要么在与 TouchGFX Engine 同步的 AL 部分实现,典型的做法是通过 RTOS (OSAL)来实现。图 2 总结了 TouchGFX AL 的主要职责,其中有一项任务就是报告触摸与物理按钮事件,TouchGFX 将原始触摸动作转换为具体的触摸事件,并转发给当前活动的 UI 元素。
3.触摸功能实现步骤
要实现触摸功能,首先需通过 STM32CubeMX 正确配置触摸控制器和 MCU,并添加相应驱动代码,保证 MCU 通过 I2C 或其他接口从触摸控制器读取信息,最后在TouchController 接口函数中添加相应的实现代码。
3.1. STM32CubeMX 配置
为了实现与触摸控制器的通讯,大多数触摸控制器都会连接至 I2C 总线,因此需要在STM32CubeMX 中对 I2C 外设进行设置。许多 STM32 MCU 具有多个 I2C 外设,因此需选择正确的 I2C 进行配置,此外还需配置相关 GPIO,图 3 是 I2C 在 STM32CubeMX 中的配置界面,开发者需要根据触摸控制器驱动芯片进行正确配置。
配置好 I2C 后,还需添加 I2C 的驱动代码,如果没有用于触摸控制器的驱动代码,则需要从头开始编写。STM32Cube 固件库中提供了一些 I2C 通讯的驱动程序,开发者可以从中参考相关代码进行修改使用。根据触摸控制器的数据手册,为确保通过读取寄存器可以获取触摸坐标,首先要检查的是触摸控制器的 I2C 地址,然后读取“设备 ID”寄存器,以进行测试,然后测试是否可以从触摸控制器接收到正确的 x 值和 y 值。
3.2. 在接口函数中添加实现代码
在渲染新的一帧之前,TouchGFX 引擎从 TouchController 和 ButtonController 接口收集外部输入。通过引擎将触摸控制器的坐标转换为点击、拖动和手势事件,并传递至应用程序。一些触摸控制器能够报告多个触摸点,TouchGFX 不支持此功能,通常,只需选择第一个触摸点。
TouchGFX 引擎在收集输入时,引擎会调用 tc 对象的 sampleTouch()函数。TouchGFX Generator 会生成一个 TouchController 类,并将接口函数定义为空。在STM32TouchController.hpp 中会声明了 init()和 sampleTouch()两个成员函数,开发者需要做的就是在 STM32TouchController.cpp 源文件中添加相应的实现代码,在 init()函数中添加触摸控制器的初始化代码,在 sampleTouch()函数中添加相应实现代码,将读取的触摸坐标值分配给 x 和 y,并返回是否检测到触摸。
其中有多种实现 sampleTouch()函数的方法:一种是在 sampleTouch()中轮询,另一种是基于中断实现。在 sampleTouch() 中轮询:通过发送请求并轮询结果,从硬件触摸控制器(通常为 I2C) 读取触摸状态和触摸坐标,默认情况下,该函数每个 tick 时间被调用一次, 如下图 5 所示。
基于中断:I2C 读取命令由定时器定期启动,或作为对触摸硬件外部中断的响应而启动。图 6 中 STM32TouchController.cpp 代码显示了 sampleTouch 如何在 RTOS 的系统中实现。当触摸事件产生时,I2C 会产生中断,并将数据通过消息队列或全局变量提供给STM32TouchController。
小结
本文介绍了 TouchGFX 从显示器的触摸控制器读取触摸坐标,并将其传递给应用程序的方法及原理。通过 STM32CubeMX 来初始化 I2C 外设,添加相应的驱动代码,然后在STM32TouchController.cpp 源文件中实现 init()和 sampleTouch()函数,开发者就能够很容易的为 TouchGFX 工程添加触摸功能。