TouchGFX之触摸控制器

news2024/10/2 12:17:06

必须能够从触摸控制器读取触摸坐标,以便用户与应用程序进行交互。 此处开发的代码将被用于以后开发TouchGFX抽象层。

由于开发板触摸芯片没有连接在I2C接口上,因此本节采用普通IO口模拟I2C接口

1.配置IO口

 

2.配置定时器

 

3.编写延时函数

delay.c

#include "delay.h"
#include "tim.h"

void delay_init(void)
{
	__HAL_TIM_ENABLE(&htim16);
}

void delay_us(uint16_t us)
{
	uint16_t cnt = TIM16->CNT;
	
	while(TIM16->CNT - cnt < us)
	{
	
	}
}

void delay_ms(uint32_t ms)
{
	for(uint32_t i = 0; i < ms; i++)
		delay_us(1000);
}
tim.c
  
  /* USER CODE BEGIN TIM16_MspInit 1 */
		delay_init();
  /* USER CODE END TIM16_MspInit 1 */

4.模拟I2C接口

i2c.c

#include "i2c.h"
#include "main.h"
#include "delay.h"

#define SDA_IN()  {GPIOI->MODER &= ~(3 << (3 * 2)); GPIOI->MODER |= 0 << 3 * 2;}
#define SDA_OUT() {GPIOI->MODER &= ~(3 << (3 * 2)); GPIOI->MODER |= 1 << 3 * 2;}
 
#define i2c_scl(n) (n ? HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, GPIO_PIN_RESET))
#define i2c_sda(n) (n ? HAL_GPIO_WritePin(GPIOI, GPIO_PIN_3, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOI, GPIO_PIN_3, GPIO_PIN_RESET))
#define READ_SDA   HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_3)

void i2c_delay(void)
{
	delay_us(2);
}

void i2c_start(void)
{
	i2c_sda(1);
	i2c_scl(1);
	i2c_delay();
	i2c_sda(0);
	i2c_delay();
	i2c_scl(0);
	i2c_delay();
}

void i2c_stop(void)
{
	i2c_sda(0);
	i2c_delay();
	i2c_scl(1);
	i2c_delay();
	i2c_sda(1);
	i2c_delay();
}

uint8_t i2c_wait_ack(void)
{
	uint8_t ucErrTime = 0;
	uint8_t rack = 0;

	i2c_sda(1);
	i2c_delay();
	i2c_scl(1);
	i2c_delay();

	while(READ_SDA)
	{
		ucErrTime++;

		if(ucErrTime > 250)
		{
			i2c_stop();
			rack = 1;
			break;
		}

		i2c_delay();
	}

	i2c_scl(0);
	i2c_delay();
	return rack;
}

void i2c_ack(void)
{
	i2c_sda(0);
	i2c_delay();
	i2c_scl(1);
	i2c_delay();
	i2c_scl(0);
	i2c_delay();
	i2c_sda(1);
	i2c_delay();
}

void i2c_nack(void)
{
	i2c_sda(1);
	i2c_delay();
	i2c_scl(1);
	i2c_delay();
	i2c_scl(0);
	i2c_delay();
}

void i2c_send_byte(uint8_t txd)
{
	uint8_t t;

	for(t = 0; t < 8; t++)
	{
		i2c_sda((txd & 0x80) >> 7);
		i2c_delay();
		i2c_scl(1);
		i2c_delay();
		i2c_scl(0);
		txd <<= 1;
	}

	i2c_sda(1);
}

uint8_t i2c_read_byte(unsigned char ack)
{
	uint8_t i, receive = 0;

	for(i = 0; i < 8; i++)
	{
		receive <<= 1;
		i2c_scl(1);
		i2c_delay();

		if(READ_SDA)
			receive++;

		i2c_scl(0);
		i2c_delay();

	}

	if(!ack)
		i2c_nack();
	else
		i2c_ack();

	return receive;
}

5.GT9147驱动

gt9147.c

#include "gt9147.h"
#include "i2c.h"
#include "delay.h"

#define GT_RST(n) (n ? HAL_GPIO_WritePin(GPIOI, GPIO_PIN_8, GPIO_PIN_SET) : HAL_GPIO_WritePin(GPIOI, GPIO_PIN_8, GPIO_PIN_RESET))

//I2C读写命令	
#define GT_CMD_WR 		0X28		//写命令
#define GT_CMD_RD 		0X29		//读命令

//GT9147 部分寄存器定义 
#define GT_CTRL_REG 	0X8040   	//GT9147控制寄存器
#define GT_CFGS_REG 	0X8047   	//GT9147配置起始地址寄存器
#define GT_CHECK_REG 	0X80FF   	//GT9147校验和寄存器
#define GT_PID_REG 		0X8140   	//GT9147产品ID寄存器

#define GT_GSTID_REG 	0X814E   	//GT9147当前检测到的触摸情况
#define GT_TP1_REG 		0X8150  	//第一个触摸点数据地址
#define GT_TP2_REG 		0X8158		//第二个触摸点数据地址
#define GT_TP3_REG 		0X8160		//第三个触摸点数据地址
#define GT_TP4_REG 		0X8168		//第四个触摸点数据地址
#define GT_TP5_REG 		0X8170		//第五个触摸点数据地址  

uint8_t GT9147_WR_Reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
	uint8_t i;
	uint8_t ret = 0;
	
	i2c_start();	
 	i2c_send_byte(GT_CMD_WR);		//发送写命令 	 
	i2c_wait_ack();
	i2c_send_byte(reg >> 8);		//发送高8位地址
	i2c_wait_ack(); 	 										  		   
	i2c_send_byte(reg & 0XFF);	//发送低8位地址
	i2c_wait_ack();  
	for(i=0; i < len; i++)
	{	   
    i2c_send_byte(buf[i]);  	//发数据
		ret = i2c_wait_ack();
		if(ret)
			break;  
	}
  i2c_stop();									//产生一个停止条件	    
	
	return ret; 
}
		  
void GT9147_RD_Reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
	uint8_t i;
	
 	i2c_start();	
 	i2c_send_byte(GT_CMD_WR);   	//发送写命令 	 
	i2c_wait_ack();
 	i2c_send_byte(reg >> 8);   		//发送高8位地址
	i2c_wait_ack(); 	 										  		   
 	i2c_send_byte(reg & 0XFF);   	//发送低8位地址
	i2c_wait_ack();  
 	i2c_start();  	 	   
	i2c_send_byte(GT_CMD_RD);   	//发送读命令		   
	i2c_wait_ack();	   
	for(i=0; i < len; i++)
	{	   
		buf[i] = i2c_read_byte(i == (len - 1) ? 0 : 1); //发数据	  
	} 
	i2c_stop();//产生一个停止条件    
} 

uint8_t CIP[5];

uint8_t GT9147_Init(void)
{
	uint8_t cmd;
	
	GT_RST(0);				//复位
	delay_ms(20);
 	GT_RST(1);				//释放复位		    
	delay_ms(50);
 	
	GT9147_RD_Reg(GT_PID_REG, CIP, 4); //读取产品ID

	cmd = 0x02;
	GT9147_WR_Reg(GT_CTRL_REG, &cmd, 1);  //软复位GT9XXX 
	GT9147_RD_Reg(GT_CFGS_REG, &cmd, 1);  //读取GT_CFGS_REG寄存器
	delay_ms(10);
	cmd=  0x00;
	GT9147_WR_Reg(GT_CTRL_REG, &cmd, 1); //结束复位, 进入读坐标状态

	return 0;
}

uint8_t GT9147_Scan(uint16_t *x, uint16_t *y)
{
	uint8_t cmd;
	uint8_t mode;
	uint8_t buf[4];
	
	GT9147_RD_Reg(GT_GSTID_REG, &mode, 1);
	if(mode & 0x80)
	{
		GT9147_RD_Reg(GT_TP1_REG, buf, 4);   //读取XY坐标值
		*x = (((uint16_t)buf[1] << 8) + buf[0]);
		*y = (((uint16_t)buf[3] << 8) + buf[2]);
		cmd = 0;
		GT9147_WR_Reg(GT_GSTID_REG, &cmd, 1); //清标志
		return 1;
	}
	
	return 0;
}

6.循环采集触摸坐标

main.c

/* USER CODE BEGIN PV */
//uint16_t framebuffer[1024 * 200];  //16 bpp framebuffer
uint16_t *framebuffer = (uint16_t *)0xC0000000;  //16 bpp framebuffer

uint16_t touch_x, touch_y;
/* USER CODE END PV */
  /* USER CODE BEGIN 2 */
	GT9147_Init();
	
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
	HAL_LTDC_SetAddress(&hltdc, (uint32_t)framebuffer, LTDC_LAYER_1);
	
	hdma2d.Init.Mode = DMA2D_R2M;
	hdma2d.Init.ColorMode = DMA2D_RGB565;

	MODIFY_REG(hdma2d.Instance->CR, DMA2D_CR_MODE, DMA2D_R2M);
	MODIFY_REG(hdma2d.Instance->OPFCCR, DMA2D_OPFCCR_CM, DMA2D_RGB565);
	MODIFY_REG(hdma2d.Instance->OOR, DMA2D_OOR_LO, 0);

	hdma2d.LayerCfg[1].InputColorMode = CM_RGB565;
	hdma2d.LayerCfg[1].InputOffset = 0;

	HAL_DMA2D_ConfigLayer(&hdma2d, 1);

	HAL_DMA2D_Start_IT(&hdma2d, 0xF800, (unsigned int)framebuffer, 1024, 600);
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		GT9147_Scan(&touch_x, &touch_y);
		HAL_Delay(60);
  }
  /* USER CODE END 3 */

7.烧录程序,运行检查触摸坐标

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

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

相关文章

算法练习- 其他算法练习5

文章目录 宜居星球改造计划 宜居星球改造计划 yes no na 每个值为一个格子&#xff1b;每天yes的值可以向上下左右扩展一个格子&#xff0c;将no改为yes&#xff1b;矩形区域no是否可以全部转为yes&#xff0c;可以的话需要几天&#xff1f;不可以的话输出-1输入&#xff1a; …

高性能服务器Nodejs业务实战

目录 1 项目初始化1.1 创建项目1.2 配置 cors 跨域1.3 配置解析表单数据的中间件1.4 初始化路由相关的文件夹1.5 初始化用户路由模块1.6 抽离用户路由模块中的处理函数 2 登录注册2.1 新建 ev_users 表2.2 安装并配置 mysql 模块2.3 注册2.4 优化 res.send() 代码2.5 优化表单数…

cuml机器学习GPU库 sklearn升级版AutoDL使用

CUML库 最近在做机器学习任务的时候发现我自己的数据集太大&#xff0c;直接用sklearn 跑起来时间很长&#xff0c;然后问GPT得知了有CUML库&#xff0c;后来去研究了一下&#xff0c;发现这个库只支持linux系统&#xff0c;从官网直接获取下载命令基本上也实现不了最后&#…

自学设计模式(类图、设计原则、单例模式 - 饿汉/懒汉)

设计模式需要用到面向对象的三大特性——封装、继承、多态&#xff08;同名函数具有不同的状态&#xff09; UML类图 eg.—— 描述类之间的关系&#xff08;设计程序之间画类图&#xff09; : public; #: protected; -: private; 下划线: static 属性名:类型&#xff08;默认值…

如果将PC电脑变成web服务器:利用Nignx反向代理绕过运营商对80端口封锁

如果将PC电脑变成web服务器&#xff1a;利用Nignx反向代理绕过运营商对80端口封锁 在上一篇文章中&#xff0c;我们已经实现了内网主机的多次端口映射&#xff0c;将内网主机的端口映射到了公网&#xff0c;可以通过公网访问该主机了。 因为电信的家庭宽带&#xff0c;默认是…

SpringBoot读取Nacos配置文件

断点到ClientWorker类的getServerConfig方法&#xff0c;反向Debug。

2023-8-23 Trie字符串统计

题目链接&#xff1a;Trie字符串统计 #include <iostream>using namespace std;const int N 100010;int son[N][26], cnt[N],idx;char str[N];void insert(char str[]) {int p 0;for(int i 0; str[i]; i){int u str[i] - a;if(!son[p][u]) son[p][u] idx;p son[p…

Langchain+LLM

LangChain是一个开源框架&#xff0c;允许开发人员在与人工智能&#xff08;AI&#xff09;一起工作时将大型语言模型&#xff08;如GPT4&#xff09;与外部计算和数据源相结合&#xff08;它提供了一套工具、组件和接口&#xff0c;可简化创建由LLM提供支持的应用程序&#xf…

前端进阶Html+css09----BFC模型

1.什么是BFC模型 全称是&#xff1a;Block formatting context&#xff08;块级格式化上下文&#xff09;&#xff0c;是一个独立的布局环境&#xff0c;不受外界的影响。 2.FC,BFC,IFC 元素在标准流里都属于一个FC&#xff08;Formatting Context&#xff09;。 块级元素的布…

【图像分割】理论篇(2)经典图像分割网络基于vgg16的Unet

UNet 是一种用于图像分割任务的深度学习架构&#xff0c;最早由 Olaf Ronneberger、Philipp Fischer 和 Thomas Brox 在2015年的论文 "U-Net: Convolutional Networks for Biomedical Image Segmentation" 中提出。UNet 在医学图像分割等领域取得了显著的成功&#x…

Anaconda安装教程以及深度学习环境搭建

目录 前言 下载Anaconda 虚拟环境的搭建 在pycharm中配置现有的conda环境 CUDA简介 下载安装pytorch包 前言 最近换新笔记本了&#xff0c;要重新安装软件&#xff0c;以前本来是想要写这个教程的&#xff0c;但当时由于截图不全还要懒得再下载重装&#xff0c;就放弃了&…

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合)

一、继承 继承 (inheritance) 机制 &#xff1a;是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特 性 的基础上进行扩展&#xff0c;增加新功能 &#xff0c;这样产生新的类&#xff0c;称 派生类 。 继承呈现了面向对象程序设计的层次结…

TRON归集回调

简介 设计一个通过调用api创建对应的tron地址&#xff0c;当地址收到token的时候&#xff0c;进行归集&回调通知的。包括的功能有: 根据UID创建地址归集&#xff08;TRX归集 TRC10归集 TRC20归集)回调通知&#xff08;转出回调通知&接收回调通知&#xff09;发起转出…

什么是JVM ?

一、JVM 简介 JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java 虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。 常见的虚拟机&#xff1a; JVM 、 VMwave 、 Virtual Box 。 JVM 和其他两个虚拟机的区别…

《JVM修仙之路》初入JVM世界

《JVM修仙之路》初入JVM世界 博主目前正在学习JVM的相关知识&#xff0c;想以一种不同的方式记录下&#xff0c;娱乐一下 清晨&#xff0c;你睁开双眼&#xff0c;看到刺眼的阳光&#xff0c;你第一反应就是完了完了&#xff0c;又要迟到了。刚准备起床穿衣的你突然意识到不对&…

Netty核心源码解析(三)--NioEventLoop

NioEventLoop介绍 NioEventLoop继承SingleThreadEventLoop,核心是一个单例线程池,可以理解为单线程,这也是Netty解决线程并发问题的最根本思路--同一个channel连接上的IO事件只由一个线程来处理,NioEventLoop中的单例线程池轮询事件队列,有新的IO事件或者用户提交的task时便执…

Centos7 安装Docker 详细多图版

配置要求 Docker CE&#xff08;社区免费版&#xff09; 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10&#xff0c; CentOS 7 满足最低内核的要求&#xff0c;所以我们在CentOS 7安装Docker。 一、Centos安装Docker 1.1 卸载&#xff08;可选&#xff0…

项目:点餐系统2

httplib的思想简单总结; 使用线程池来处理请求由用户定义处理函数&#xff0c;告诉httplib哪个请求应该使用哪个函数处理线程接收请求并解析请求后调用处理函数 一、服务器搭建 get主要是用来获取资源的&#xff0c;post主要是客户端提交数据的。 #include"httplib.h"…

小白带你学习linux的shell脚本基础(三十五)

目录 一、概述 1、脚本就是将手动一次性执行的命令进行规范且自动化 2、学习路径 2.1表达式 2.2语句 2.3函数 2.4正则表达式 2.5文件操作四剑客 二、表达式 1、shell 2、表达式 2、1 变量 2、2 运算符 2、3shell脚本编写规范 2、4shell运行规则 2、5shell脚本运…

SpringSecurity原理

最近在研究SpringSecurity&#xff0c;肝了好多天&#xff0c;算是有点收获&#xff0c;在这里分享下 SpringSecurity是什么&#xff1f; SpringSecurity是一个强大的可高度定制的认证和授权框架&#xff0c;对于Spring应用来说它是一套Web安全标准。SpringSecurity注重于为J…