TouchGFX界面开发 | 添加触摸屏驱动

news2024/11/25 15:47:44

使用STM32CubeMX移植TouchGFX 一文中介绍了如何用TouchGFX点亮屏幕,但是此时屏幕还没有触摸的功能。下面将介绍如何添加触摸屏驱动到TouchGFX中

一、STM32CubeMX配置

在使用STM32CubeMX移植TouchGFX 文中的STM32CubeMX配置基础上,再激活一个定时器,用来给IIC通信提供微秒(us)延时。本文通过软件来模拟IIC通信,因此不使用STM32CubeMX来进行IIC配置

在这里插入图片描述

二、MKD-ARM KEIL中添加触摸芯片驱动

本文中的RGB (800 * 480)屏触摸驱动IC为FT5206芯片,该驱动芯片通过 4 根线与外部连接:CT_RST(PI8), CT_INT(PH7), CT_SDA(PI3), CT_SCL(PH6)。由于通过软件来模拟IIC通信,因此不使用STM32CubeMX来进行配置

2.1 添加微秒延时函数

在自动生成的tim.c文件中添加微秒延时函数,并在tim.h中声明

void delay_us(uint16_t us)
{
	uint16_t differ = 0xffff - us -5;
	__HAL_TIM_SET_COUNTER(&htim6, differ);
	HAL_TIM_Base_Start(&htim6);
	
	while(differ < 0xffff - 5){
		differ = __HAL_TIM_GET_COUNTER(&htim6);
	}
	
	HAL_TIM_Base_Stop(&htim6);
}
2.2 软件模拟IIC通信
  • IIC通信头文件:在工程中添加IIC通信头文件ctiic.h
#ifndef __CT_IIC_H
#define __CT_IIC_H

#include "main.h"

#define IIC_SDA_PORT	GPIOI
#define IIC_SDA_PIN		GPIO_PIN_3

#define IIC_SCL_PORT	GPIOH
#define IIC_SCL_PIN		GPIO_PIN_6

#define SET_SDA_PIN_H	HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET)
#define SET_SDA_PIN_L	HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET)

#define SET_SCL_PIN_H	HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET)
#define SET_SCL_PIN_L	HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET)


void SET_SDA_DIR_OUT(void);
void SET_SDA_DIR_IN(void);
uint8_t READ_IIC_SDA(void);
void WRITE_IIC_SDA(uint8_t state);

void IIC_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
uint8_t IIC_Wait_Ack(void);
void IIC_Ack(void);
void IIC_NAck(void);
void IIC_Send_Byte(uint8_t txd);
uint8_t IIC_Read_Byte(unsigned char ack);

#endif
  • IIC通信源文件:在工程中添加IIC通信源文件ctiic.c
#include "ctiic.h"
#include "tim.h"

void SET_SDA_DIR_OUT(void)
{
	GPIO_InitTypeDef GPIO_Initure;
    
  GPIO_Initure.Pin   = IIC_SDA_PIN;            
  GPIO_Initure.Mode  = GPIO_MODE_OUTPUT_PP;  
  GPIO_Initure.Pull  = GPIO_PULLUP;          
  GPIO_Initure.Speed = GPIO_SPEED_HIGH;
	
  HAL_GPIO_Init(IIC_SDA_PORT, &GPIO_Initure);     
}
	

void SET_SDA_DIR_IN(void)
{
	GPIO_InitTypeDef GPIO_Initure;
    
  GPIO_Initure.Pin   = IIC_SDA_PIN;            
  GPIO_Initure.Mode  = GPIO_MODE_INPUT;  
  GPIO_Initure.Pull  = GPIO_PULLUP;          
  GPIO_Initure.Speed = GPIO_SPEED_HIGH;
	
  HAL_GPIO_Init(IIC_SDA_PORT, &GPIO_Initure);     
}	

uint8_t READ_IIC_SDA(void)
{
	return HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN);
}	

void WRITE_IIC_SDA(uint8_t state)
{
	HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, state);
}	


void IIC_Init()
{
	GPIO_InitTypeDef GPIO_Initure;
	__HAL_RCC_GPIOI_CLK_ENABLE();
	__HAL_RCC_GPIOH_CLK_ENABLE();
    
  GPIO_Initure.Pin   = IIC_SCL_PIN;            
  GPIO_Initure.Mode  = GPIO_MODE_OUTPUT_PP;  
  GPIO_Initure.Pull  = GPIO_PULLUP;          
  GPIO_Initure.Speed = GPIO_SPEED_HIGH;	
  HAL_GPIO_Init(IIC_SCL_PORT, &GPIO_Initure);   	
	
	GPIO_Initure.Pin   = IIC_SDA_PIN;            
  HAL_GPIO_Init(IIC_SDA_PORT, &GPIO_Initure);

	SET_SDA_PIN_H;
	SET_SCL_PIN_H;
}	

void IIC_Start()
{
	SET_SDA_DIR_OUT();
	SET_SDA_PIN_H;
	SET_SCL_PIN_H;
	delay_us(30);
	SET_SDA_PIN_L;
	delay_us(2);
	SET_SCL_PIN_L;
}	



void IIC_Stop(void)
{
	SET_SDA_DIR_OUT();
	SET_SCL_PIN_L;
	SET_SDA_PIN_L;
	delay_us(30);
	SET_SCL_PIN_H;
	delay_us(2);
	SET_SDA_PIN_H;
}



uint8_t IIC_Wait_Ack(void)
{
	uint8_t ucErrTime = 0;
	SET_SDA_DIR_IN();
	SET_SDA_PIN_H;
	SET_SCL_PIN_H;
	delay_us(2);
	while(READ_IIC_SDA()){
		ucErrTime++;
		if(ucErrTime > 250){
			IIC_Stop();
			return 1;
		}
		delay_us(2);
	}
	SET_SCL_PIN_L;
	return 0;

}	

void IIC_Ack(void)
{
	SET_SCL_PIN_L;
	SET_SDA_DIR_OUT();
	SET_SDA_PIN_L;
	delay_us(2);
	SET_SCL_PIN_H;
	delay_us(2);
	SET_SCL_PIN_L;
}	

void IIC_NAck(void)
{
	SET_SCL_PIN_L;
	SET_SDA_DIR_OUT();
	SET_SDA_PIN_H;
	delay_us(2);
	SET_SCL_PIN_H;
	delay_us(2);
	SET_SCL_PIN_L;

}	

void IIC_Send_Byte(uint8_t txd)
{
  uint8_t t;   
	SET_SDA_DIR_OUT();
	SET_SCL_PIN_L;
	for(t=0;t<8;t++){              
    WRITE_IIC_SDA((txd&0x80)>>7);
    txd <<= 1; 
		delay_us(2);	      
		SET_SCL_PIN_H;
	  delay_us(2);
	  SET_SCL_PIN_L;
		delay_us(2);	
  }	 
}	

uint8_t IIC_Read_Byte(unsigned char ack)
{
	uint8_t i,receive = 0;
	SET_SDA_DIR_IN();
	delay_us(30);
	for(i=0;i<8;i++ )
	{ 
		SET_SCL_PIN_L;
		delay_us(2);
		SET_SCL_PIN_H;	 
		receive <<= 1;
		if(READ_IIC_SDA())
			receive++; 
		delay_us(2); 
	}	  				 
	if (!ack)
		IIC_NAck();
	else 
		IIC_Ack();   
 	return receive;

}	
2.3 FT5206芯片驱动
  • 在工程中添加FT5206芯片驱动头文件ft5206.h
#ifndef __FT5206_H
#define __FT5206_H

#include "ctiic.h"

#define FT_CMD_WR 				0X70    	
#define FT_CMD_RD 				0X71		
  
#define FT_DEVIDE_MODE 			0x00   		
#define FT_REG_NUM_FINGER       0x02		

#define FT_TP1_REG 				0X03	  	
#define FT_TP2_REG 				0X09		
#define FT_TP3_REG 				0X0F		
#define FT_TP4_REG 				0X15		
#define FT_TP5_REG 				0X1B		

#define	FT_ID_G_LIB_VERSION		0xA1		
#define FT_ID_G_MODE 			0xA4   		
#define FT_ID_G_THGROUP			0x80   		
#define FT_ID_G_PERIODACTIVE	0x88   		

#define TOUCH_MAX_NUM 5

typedef struct
{
	uint8_t touch_type;
	uint8_t dir;   //0表示竖屏,1表示横屏
	uint16_t pix_w;
	uint16_t pix_h;
	uint8_t touch_num;
	uint16_t x[TOUCH_MAX_NUM];
	uint16_t y[TOUCH_MAX_NUM];	
}TouchTypedef;

uint8_t FT5206_WR_Reg(uint16_t reg, uint8_t *buf, uint8_t len);
void FT5206_RD_Reg(uint16_t reg, uint8_t *buf, uint8_t len);
void FT5206_Init(void);
uint8_t FT5206_Scan(TouchTypedef *touch);

#endif
  • 在工程中添加FT5206芯片驱动文件ft5206.c
#include "ft5206.h"
#include "stdio.h"

static const uint16_t FT5206_TPX_TBL[5]={FT_TP1_REG, FT_TP2_REG, FT_TP3_REG, FT_TP4_REG, FT_TP5_REG};

uint8_t FT5206_WR_Reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
   uint8_t i;
    uint8_t ret=0;
    IIC_Start();
    IIC_Send_Byte(FT_CMD_WR);	
    IIC_Wait_Ack();
    IIC_Send_Byte(reg&0XFF);   
    IIC_Wait_Ack();
    for(i=0; i<len; i++)
    {
        IIC_Send_Byte(buf[i]);  	
        ret = IIC_Wait_Ack();
        if(ret)break;
    }
    IIC_Stop();					
    return ret;
}


void FT5206_RD_Reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
    uint8_t i;
    IIC_Start();
    IIC_Send_Byte(FT_CMD_WR);   	
    IIC_Wait_Ack();
    IIC_Send_Byte(reg&0XFF);   	
    IIC_Wait_Ack();
    IIC_Start();
    IIC_Send_Byte(FT_CMD_RD);   	
    IIC_Wait_Ack();
    for(i=0; i<len; i++)
    {
        buf[i]=IIC_Read_Byte(i==(len-1)?0:1); 
    }
    IIC_Stop();	
}


void FT5206_Init(void)
{
    uint8_t temp[2];
    GPIO_InitTypeDef GPIO_Initure;
 
    __HAL_RCC_GPIOH_CLK_ENABLE();			
    __HAL_RCC_GPIOI_CLK_ENABLE();			
 
    //PH7
    GPIO_Initure.Pin=GPIO_PIN_7;            
    GPIO_Initure.Mode=GPIO_MODE_INPUT;      
    GPIO_Initure.Pull=GPIO_PULLUP;          
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     
    HAL_GPIO_Init(GPIOH,&GPIO_Initure);    
 
    //PI8
    GPIO_Initure.Pin=GPIO_PIN_8;            
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
    HAL_GPIO_Init(GPIOI,&GPIO_Initure);    
 
    IIC_Init();
 
	HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_RESET);				
    HAL_Delay(20);
    HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_SET);				
    HAL_Delay(50);
    temp[0]=0;
    FT5206_WR_Reg(FT_DEVIDE_MODE,temp,1);	
    FT5206_WR_Reg(FT_ID_G_MODE,temp,1);		
    temp[0]=22;								
    FT5206_WR_Reg(FT_ID_G_THGROUP,temp,1);	
    temp[0]=12;							
    FT5206_WR_Reg(FT_ID_G_PERIODACTIVE,temp,1);
   
    FT5206_RD_Reg(FT_ID_G_LIB_VERSION,&temp[0],2);
    if((temp[0]==0X30&&temp[1]==0X03)||temp[1]==0X01||temp[1]==0X02)
    {
        printf("CTP ID:%x\r\n",((uint16_t)temp[0]<<8)+temp[1]);
        return ;
    }
		printf("CTP ID:%x\r\n",((uint16_t)temp[0]<<8)+temp[1]);
}	


uint8_t FT5206_Scan(TouchTypedef *touch)
{
	uint8_t buf[4];
	uint8_t touch_num;
	uint8_t i = 0;
	//uint8_t touch_state = 0;
	FT5206_RD_Reg(FT_REG_NUM_FINGER,&touch_num,1);
	touch->touch_num = touch_num;
	if((touch_num&0XF)&&((touch_num&0XF)<6))
 {
	 for(i = 0;i<touch_num;i++){
		 FT5206_RD_Reg(FT5206_TPX_TBL[i],buf,4);
		 uint16_t x = 0;
		 uint16_t y = 0;
		 
		 if(touch->dir){
			 y = ((uint16_t)(buf[0]&0X0F)<<8)+buf[1];
			 x = ((uint16_t)(buf[2]&0X0F)<<8)+buf[3];
		 }else{
			x = touch->pix_h - (((uint16_t)(buf[0]&0X0F)<<8)+buf[1]);
		  y = ((uint16_t)(buf[2]&0X0F)<<8)+buf[3];
		 }
		 touch->x[i] = x;
		 touch->y[i] = y;
	 }
 }else{
	 touch->touch_num = 0;
	 return 0;
 }
 return touch_num;
}


2.4 将触摸驱动添加到TouchGFX中

将触摸驱动添加到触摸控制文件STM32TouchController.cpp

#include <STM32TouchController.hpp>

extern "C"{
#include "ft5206.h"
}

TouchTypedef mtouch;

void STM32TouchController::init()
{
	FT5206_Init();
	mtouch.dir = 1;
	mtouch.pix_w = 800;
	mtouch.pix_h = 480;
}

bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
	if(FT5206_Scan(&mtouch)){
		x = mtouch.x[0];
		y = mtouch.y[0];
		return true;
	}	
    return false;
}

三、TouchGFX Designer中添加点击事件

在TouchGFX Designer中,创建一个按钮,实现点击后背景变色的功能

  • 添加一个图标按钮,同时添加一个box作为背景

在这里插入图片描述

  • 添加交互动作:实现点击图标按钮,背景颜色由黑色变为白色

在这里插入图片描述

  • 点击Generate Code生成TouchGFX代码

四、下载测试

回到Keil工程中,编译无误后,下载到开发板中。点击屏幕上的按钮,若屏幕背景色由黑色变为白色,说明点击成功,触摸驱动添加成功

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1050590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pikachu靶场——XXE 漏洞

文章目录 1. XXE1.1 查看系统文件内容1.2 查看PHP源代码1.3 查看开放端口1.4 探测内网主机 1. XXE 漏洞描述 XXE&#xff08;XML External Entity&#xff09;攻击是一种利用XML解析器漏洞的攻击。在这种攻击中&#xff0c;攻击者通过在XML文件中插入恶意实体来触发解析器加载…

自然语言处理(NLP)学习之与HanLP的初相识

目录 前言 一、自然语言处理基本知识 1、NLP类别 2、核心任务 二、Hanlp简要介绍 三、Hanlp云服务能力 1、全新云原生2.x 2、Python api调用 3、Go api调用 4、Java api调用 四、Hanlp native服务 1、本地开发 总结 前言 在ChatGPT的滚滚浪潮下&#xff0c;也伴随着人工智…

深入理解JavaScript中的事件冒泡与事件捕获

在JavaScript中&#xff0c;事件是交互式网页开发中的关键概念之一。了解事件冒泡和事件捕获是成为一名优秀的前端开发者所必需的技能之一。本文将深入探讨这两个概念&#xff0c;解释它们是如何工作的&#xff0c;以及如何在实际应用中使用它们来处理事件。 一.什么是事件冒泡…

No151.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

冲刺十五届蓝桥杯P0002 日期统计

文章目录 题目分析代码 题目 分析 需要明白一些概念&#xff0c;子序列、连续子序列。 1.子序列&#xff08;subsequence&#xff09;是指原始序列中按照相同顺序选择零个或多个元素而形成的序列。连续子序列&#xff08;subarray&#xff09;是指原始序列中相邻位置的元素构…

计算机网络之传输层

计算机网络 - 传输层 计算机网络 - 传输层 UDP 和 TCP 的特点UDP 首部格式TCP 首部格式TCP 的三次握手TCP 的四次挥手TCP 可靠传输TCP 滑动窗口TCP 流量控制TCP 拥塞控制 1. 慢开始与拥塞避免2. 快重传与快恢复 网络层只把分组发送到目的主机&#xff0c;但是真正通信的并不是…

网络-OSI、TCP、浏览器URL、CDN

文章目录 前言一、OSI七层模型二、TCP/IP和UDPTCP三次握手四次挥手 三、 浏览器输入URLURLDNS查询TCP/IP连接浏览器缓存强缓存协商缓存断开连接 浏览器渲染 四、 CDN总结 前言 本文记录OSI七层参考模型&#xff0c;和TCP/IP基本介绍。 一、OSI七层模型 七层参考模型分别是&am…

【C++入门到精通】C++入门 —— set multiset (STL)

阅读导航 前言一、set简介二、std::set1. std::set简介2. std::set的使用- 基本使用- std::set的模板参数列表- std::set的构造函数- std::set的迭代器- std::set容量与元素访问函数 3. set的所有函数&#xff08;表&#xff09; 三、std::multiset1. std::multiset简介 四、st…

农产品经营小程序商城的作用是什么?

农场或拥有稳定货源的商家更适合做线上生鲜蔬果生意&#xff0c;近些年随着线上电商崛起&#xff0c;如何打通并且加深同城、到店、快递货品销售场景成为商家们需要思考的&#xff1b;微信是企业商家重要的营销平台&#xff0c;因此在微信卖货增长很重要&#xff0c;但想要完善…

【中国知名企业高管团队】系列22:滴滴

大家好&#xff01; 今天华研荟的走进中国知名企业高管团队系列带大家认识滴滴。 滴滴公司是出行领域的先行者&#xff0c;也是一个典型样本。通过滴滴公司的名字变迁我们可以感受到滴滴公司的业务发展&#xff0c;这也是整个出行行业公司的发展路径&#xff1a; 第一阶段&a…

神经辐射场(NeRF)2023最新论文及源代码合集

神经辐射场&#xff08;NeRF&#xff09;作为一种先进的计算机图形学技术&#xff0c;能够生成高质量的三维重建模型&#xff0c;在计算机图形学、计算机视觉、增强现实等领域都有着广泛的应用前景&#xff0c;因此&#xff0c;自2020年惊艳亮相后&#xff0c;神经辐射场也成为…

C理解(三):结构体,共用体,枚举

结构体 结构体元素访问本质是指针方式,依据元素在结构体中的偏移量和元素类型进行访问 元素占字节数和类型占字节数不同,导致结构体的元素偏移量要复杂,因此结构体需要对齐访问 结构体对齐规则 结构体本身应在在4字节对齐处&#xff08;占4个字节&#xff09; 每个元素都对其存…

二、MAVEN的安装和配置

二、MAVEN的安装和配置 1.官网下载&#xff1a;http://maven.apache.org/download.cgi 2.解压文件包 1.apache-maven-3.5.2-bin.zip 直接解压到指定安装路径。 2.apache-maven-3.5.2-src.zip maven源码包。 3.配置环境变量&#xff0c;类似jdk环境配置 1.创建M2_HOME环境变…

关于操作系统与内核科普

关于操作系统与内核科普 一.什么是操作系统 操作系统是管理计算机硬件与软件资源的计算机程序。它为计算机硬件和软件提供了一种中间层。 操作系统是一种软件&#xff0c;主要目的有三种&#xff1a; 一.管理计算机资源&#xff0c;这些资源包括CPU&#xff0c;内存&#xff0…

正在等待操作系统重新启动。 请重新启动计算机以安装autocad 2024。

正在等待操作系统重新启动。 请重新启动计算机以安装autocad 2024。 这是刚启动Autodesk 2024产品就弹出的弹窗&#xff0c;重启之后启动还是有这个 一直阻止安装程序运行 出现问题的原因是安装包存在问题 使用正确的安装包即可解决这个问题 需要的朋友查看图片或者评伦取…

【剑指Offer】7.重建二叉树

题目 给定节点数为 n 的二叉树的前序遍历和中序遍历结果&#xff0c;请重建出该二叉树并返回它的头结点。 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}&#xff0c;则重建出如下图所示。 提示: 1.vin.length pre.length 2.pre 和 vin 均无重复…

《Python趣味工具》——ppt的操作(2)

在上次&#xff0c;我们对PPT进行了简单的处理&#xff1b;本次&#xff0c;我们要将PPT中的文本内容写入到 Word 文档中并添加标题&#xff0c;让 Word 文档看上去结构清晰&#xff0c;方便使用。 文章目录 一、安装docx模块&#xff1a;二、从PPT中转移文字&#xff1a;1. 创…

Elasticsearch基础篇(二):Elasticsearch在windows和liunx上的安装部署

Elasticsearch简介 前言1. Windows环境部署Elasticsearch1.1 下载并解压Elasticsearch压缩包1.2 命令行启动elasticsearch1.3 验证是否成功启动elasticsearch1.4 关闭Elasticsearch1.5 在Windows上安装Elasticsearch作为服务 2. Liunx环境部署Elasticsearch安装 Elasticsearch …

Python 爬虫 / web 面试常见问题

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了&#xff0c;直接在文末名片自取就可 爬虫面试常见…

Excel技巧之【锁定工作簿】

Excel工作簿是Excel工作区中一个或多个工作表的集合&#xff0c;我们知道Excel可以设置锁定工作表&#xff0c;防止意外或被他人修改&#xff0c;但可能有小伙伴不知道&#xff0c;Excel工作簿也同样可以设置锁定&#xff0c;防止更改。 那工作簿锁定后会怎么样呢&#xff1f;…