目录
前言
硬件平台:RT-Thread ART-Pi STM32H750XBH6开发板 H750开发板
开发软件:RT-Thread Studio
显示屏:正点原子7寸RGB电容触摸液晶屏模块
相关组件:LCD、TouchGFX Library、I2C1、C++、ft5426。
参考博客:玩转ART-Pi(三)
参考视频:TouchGFX教程
官方资料:TouchGFX文档
实验目的:
- 为显示单片机采集到的数据而无需连接电脑做铺垫。
- 学习一下电容屏的图形驱动TouchGFX。
- 整个花里胡哨的界面玩儿。
一、基本配置
非小白直接跳过
1、创建基本工程
请移步至《RT-Thread Studio驱动SD卡》教程,参考一、创建基本工程 。建议重命名好区分。
2、配置RT-Thread Settings
双击左侧项目资源管理器下所建工程的“RT-Thread Settings”打开可视化配置。
二、驱动触摸屏
1、打开软件模拟I2C
屏幕触摸芯片是通过I2C驱动的,而RTT提供了软件模拟I2C功能,因此需要将此配置打开。
选中后右键点击详细配置查看具体配置,好像没什么需要配置的,暂且先放着。
到这I2C的配置还没算完,要到硬件-Hardware Drivices Config-On-chip Peripheral下使能I2C并使能I2C1。具体的pin number是什么意思暂时没想明白。
2、配置I2C
至于为什么是I2C1而不是2或3呢?来看看原理图就知道了。LCD显示用的是并行24位RGB接口,而TSI_IIC就是触摸的通信接口,用的是I2C1。
题外话:按照原理图里的提示,之后可以使用RTT官方推出的SPI屏幕跑柿饼UI实现双屏。(之后有空再研究研究)
3、添加触摸软件包
打开了I2C后还得添加对应的设备驱动才能正常使用设备,正点原子7寸电容屏用的是FT5246触摸芯片,因此得把对应的软件包加上。
通过软件包中心添加新的软件包。
搜索并点击添加软件包。
4、配置软件包
查看添加的软件包,选中后右键打开详细配置。
把samples使能就不需要我们再去做其他配置了,触摸屏直接能用。
5、触摸驱动验证
保存配置后编译工程并下载,使用Xshell查看串口信息。能看到当点击屏幕时串口会打印出触摸点的绝对位置。
三、驱动显示屏
1、使能LCD
要使用LCD先要打开硬件的支持,在硬件的片上外围设备里使能LCD。
在使能LCD时发现SDRAM也被使能了,这是因为MCU想要快速地将图像显示出来需要先将数据存进RAM中。
2、使能TouchGFX
如标题所述,既然要用TouchGFX驱动显示屏,那当然得打开库的使能了。
直接保存配置编译发现有报错,看到最近的一个错误显示“DMA2D”undeclared。
3、打开DMA2D和CRC使能
恰巧之前在参考别人博客(前言已贴出地址)的时候看到有看到CRC和DMA2D的使能,估计就是这里需要手动去打开了。
打开了配置之后保存重新编译,还看到有报错。
4、修改C++配置
这错报的有点迷,之前有去RTT的社区查过,没得出什么有用的信息。后来才发现是需要对C++进行配置。在配置过程中好像没有去打开C++但实际上却打开了,那应该是在添加TouchGFX Library时自动添加上的,毕竟TouchGFX底层是用C++写的。
为了解决这个bug,先确定当前选中的工程,然后点击左上角的“扳手”图标(编译右边那个)。
必须确保先选中了当前工程,打开到如下路径。
把1、2、4的复选框勾上,点击应用关闭。
5、修改屏幕尺寸
重新编译下载工程,查看效果。屏幕是驱动起来了,但是显示不正常。
打开lcd_port.h文件,修改屏幕的尺寸。我用的屏幕尺寸是1024*600的。
6、显示驱动验证
下面能看到屏幕已经能显示出了图像,但是点击滑动控件并无响应。
四、绑定触摸事件到TouchGFX
1、修改路径
首先进入如下目录:libraries - touchgfx_lib - TouchGFX - target - STM32TouchController.cpp,在该文件下可以实现对I2C1的初始化和触摸位置数据的传入。
之前packages - ft5246 - example_ft5246.c目录下对触摸屏的初始化可以去掉了,可以直接在STM32TouchController.cpp文件内完成初始化,而最快的方法就是直接改软件包的samples使能了。
2、修改参考
参考example_ft5246.c对I2C1的初始化及屏幕触摸点位置读取的代码。
- 初始化
struct rt_touch_config cfg;
cfg.dev_name = "i2c1";
rt_hw_ft5426_init("touch", &cfg);
touch = rt_device_find("touch");
rt_device_open(touch, RT_DEVICE_FLAG_RDONLY);
read_data = (struct rt_touch_data *)rt_calloc(1, sizeof(struct rt_touch_data));
- 读取触摸点
rt_device_read(touch, 0, read_data, 1);
if (read_data->event == RT_TOUCH_EVENT_DOWN)
{
rt_kprintf("down x: %03d y: %03d", read_data->x_coordinate, read_data->y_coordinate);
rt_kprintf(" t: %d\n", read_data->timestamp);
}
if (read_data->event == RT_TOUCH_EVENT_MOVE)
{
rt_kprintf("move x: %03d y: %03d", read_data->x_coordinate, read_data->y_coordinate);
rt_kprintf(" t: %d\n", read_data->timestamp);
}
if (read_data->event == RT_TOUCH_EVENT_UP)
{
rt_kprintf("up x: %03d y: %03d", read_data->x_coordinate, read_data->y_coordinate);
rt_kprintf(" t: %d\n\n", read_data->timestamp);
}
因为STM32TouchController.cpp是C++文件,C++对C的调用需要使用extern “C”对C语言的函数进行修饰。
extern "C"{
//C语言函数
}
当使用C++编译工程时会有一个特殊的宏“__cplusplus”被定义,因此可以结合起来使用。
#ifdef __cplusplus
extern "C"{
#endif
//C语言函数
#ifdef __cplusplus
}
#endif
3、修改后的代码
完整代码如下:
/**
******************************************************************************
* File Name : STM32TouchController.cpp
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE BEGIN STM32TouchController */
#include <STM32TouchController.hpp>
#include <rtthread.h>
rt_device_t touch;
struct rt_touch_data *read_data;
#ifdef __cplusplus
extern "C"{
#endif
#include "ft5426.h"
#include "touch.h"
#ifdef __cplusplus
}
#endif
void STM32TouchController::init()
{
/**
* Initialize touch controller and driver
*
*/
struct rt_touch_config cfg;
cfg.dev_name = "i2c1";
rt_hw_ft5426_init("touch", &cfg);
touch = rt_device_find("touch");
rt_device_open(touch, RT_DEVICE_FLAG_RDONLY);
read_data = (struct rt_touch_data *)rt_calloc(1, sizeof(struct rt_touch_data));
}
bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
/**
* By default sampleTouch returns false,
* return true if a touch has been detected, otherwise false.
*
* Coordinates are passed to the caller by reference by x and y.
*
* This function is called by the TouchGFX framework.
* By default sampleTouch is called every tick, this can be adjusted by HAL::setTouchSampleRate(int8_t);
*
*/
rt_device_read(touch, 0, read_data, 1);
if ((read_data->event == RT_TOUCH_EVENT_DOWN)|| (read_data->event == RT_TOUCH_EVENT_MOVE))
{
rt_kprintf("down x: %03d y: %03d", read_data->x_coordinate, read_data->y_coordinate);
rt_kprintf(" t: %d\n", read_data->timestamp);
//x和y为传回给touchGFX的位置。
y = read_data->x_coordinate;
x = read_data->y_coordinate;
return true;
}
else
{
return false;
}
}
/* USER CODE END STM32TouchController */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
4、触摸及显示验证
当滑动右侧控件时,左侧的列表会进行缩放。
五、优化显示
1、当前显示
一亿像素都拍不清🤣,但是很明显显示不全。
2、修改显示尺寸
首先使用TouchGFX Designer打开设计的界面,工程目录如下:
使用TouchGFX Designer打开后点击Run Simulator运行看结果,显然显示屏黑色区域外的位置是显示不出来的。
使用文本文档打开“ApplicationTemplate.touchgfx”,修改对应的长宽。
3、显示尺寸验证
修改完成后在TouchGFX Designe打开重新编译生成工程,然后在RT-Thread Studio也重新编译下载。控件已经能完全显示了。
4、美化背景
黑不溜的背景图受不了,从网络上先搞一张1024*600的图片下来,然后在TouchGFX Designe点击右上角的加号,打开后点击Image添加背景图。
选中刚添加的image控件,在右侧点击该选项添加外部图片,只支持PNG。
新添加的图片会将之前的所有图层都挡住,选中左侧新建的图片后点击图层按钮将此图层放到最底。
点击模拟器运行一下,nice。
5、最终效果
这样看起来舒服多了,拍照技术有待提高🤣。
总结
研究了一个星期总算搞出点小东西了,软件包里的readme对于初学者感觉还是有点笼统,后续研究一下开发板数据显示到屏幕和屏幕控件控制开发板硬件,打算整个实用调试工具耍耍😎。
附上代码下载链接,为什么不传到github?个人觉得教程描述已经很详细了,有疑问欢迎留言拒绝白嫖。