Files
player/Project/Src/Drive/Source/touch_043.c
2025-07-05 19:47:28 +08:00

412 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***
***************************************************************************************
* @file touch_043.c
* @version V1.0
* @date 2018-1-1
* @author 反客科技
* @brief GT9147触摸驱动
***************************************************************************************
* @description
*
* 实验平台反客STM32F429核心板 + 4.3寸RGB液晶屏(屏幕型号RGB043M1)
* 淘宝地址https://shop212360197.taobao.com
* QQ交流群536665479
*
>>>>> 文件说明:
*
* 1.触摸屏相关的操作函数
* 2.使用模拟IIC
* 3.通信速度默认为100KHz
*
>>>>> 重要说明:
*
* 1.GT9147可以掉电保存配置参数且出厂时已配置好用户一般情况下无需再进行配置
* 2.在修改触摸配置参数之前,需要将原厂的参数读取并做好备份,以免改动关键的参数
* 3.用户修改参数之后,需要将 GT9XX_SendCfg() 函数屏蔽掉不然频繁的写入会将触摸芯片的Flash写坏
*
***************************************************************************************
***/
#include "touch_043.h"
// 触摸信息结构体,在函数 Touch_Scan() 里被调用,存储触摸数据
TouchStructure touchInfo;
// 触摸参数配置数组,在函数 GT9XX_SendCfg() 里调用用于配置触摸IC的相关参数
// 由于GT9147可以固化保存这些参数所以用户一般情况下无需再进行配置
// 详细的寄存器功能请参考《GT9147编程指南》
//
const u8 GT9XX_CFG_DATA[] =
{
0XAA, // 寄存器地址0x8047功能配置版本号
0XE0,0X01, // 寄存器地址0x8048~0x8049功能X坐标最大值低位在前
0X10,0X01, // 寄存器地址0x804A~0x804B功能Y坐标最大值低位在前
0X05, // 寄存器地址0x804C功能设置最大触摸点数1~5点
0X0E, // 寄存器地址0x804D功能设置INT触发方式、XY坐标交换
0X00, // 该寄存器无需配置
0X88, // 寄存器地址0x804F功能按下或松开去抖次数
0X0B, // 寄存器地址0x8050功能原始坐标窗口滤波值
0X80,0X08,0X50,0X3C,0X0F,0X00,0X00,0X00,0XFF,0X67, // 0X8051 ~ 0X805A
0X50,0X00,0X00,0X18,0X1A,0X1E,0X14,0X89,0X28,0X0A, // 0X805B ~ 0X8064
0X30,0X2E,0XBB,0X0A,0X03,0X00,0X00,0X02,0X33,0X1D, // 0X8065 ~ 0X806E
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X32,0X00,0X00, // 0X806F ~ 0X8078
0X2A,0X1C,0X5A,0X94,0XC5,0X02,0X07,0X00,0X00,0X00, // 0X8079 ~ 0X8082
0XB5,0X1F,0X00,0X90,0X28,0X00,0X77,0X32,0X00,0X62, // 0X8083 ~ 0X808C
0X3F,0X00,0X52,0X50,0X00,0X52,0X00,0X00,0X00,0X00, // 0X808D ~ 0X8096
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00, // 0X8097 ~ 0X80A0
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F, // 0X80A1 ~ 0X80AA
0X0F,0X03,0X06,0X10,0X42,0XF8,0X0F,0X14,0X00,0X00, // 0X80AB ~ 0X80B4
0X00,0X00,
/******************************************************************************************
* 寄存器地址: 0x80B7~0X80C4
* 功能说明 : 修改感应通道对应的芯片通道号,可以改变触摸面板的垂直扫描方向
*******************************************************************************************/
// 0X08,0X0A,0X0C,0X0E,0X10,0X12,0X14,0X16,0X18,0X1A, // 扫描方向从 上 到 下
0X1A,0X18,0X16,0X14,0X12,0X10,0X0E,0X0C,0X0A,0X08, // 扫描方向从 下 到 上
0X00,0X00,0X00,0X00, // 未使用的感应通道,无需更改设置
/******************************************************************************************/
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00, // 无作用寄存器,无需配置
0X00,0X00,0X00,0X00,0x00,0x00, // 无作用寄存器,无需配置
/*******************************************************************************************
* 寄存器地址: 0x80D5~0X80EE
* 功能说明 : 修改驱动通道对应的芯片通道号,可以改变触摸面板的水平扫描方向
********************************************************************************************/
// 0x00,0x02,0x04,0x05,0x06,0x08,0x0a,0x0c, // 扫描方向从 左 到 右
// 0x0e,0x1d,0x1e,0x1f,0x20,0x22,0x24,0x28,0x29,
0X29,0X28,0X24,0X22,0X20,0X1F,0X1E,0X1D, // 扫描方向从 右 到 左
0X0E,0X0C,0X0A,0X08,0X06,0X05,0X04,0X02,0X00,
0xff, // 未使用的驱动通道,无需更改设置
/*******************************************************************************************/
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00, // 通道调整系数寄存器,无需修改
0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, // 通道调整系数寄存器,无需修改
0XFF,0XFF,0XFF,0XFF, // 通道调整系数寄存器,无需修改
};
/*****************************************************************************************
* 函 数 名: GT9XX_Reset
* 入口参数: 无
* 返 回 值: 无
* 函数功能: 复位GT9147
* 说 明:复位GT9147并将芯片的IIC地址配置为0xBA/0xBB
******************************************************************************************/
void GT9XX_Reset(void)
{
Touch_INT_Out(); // 将INT引脚配置为输出
// 初始化引脚状态
GPIO_ResetBits(Touch_INT_PORT,Touch_INT_PIN); // 将INT拉低
GPIO_SetBits (Touch_RST_PORT,Touch_RST_PIN); // 将RST拉高
Touch_IIC_Delay(10000);
// 开始执行复位
// INT引脚保持低电平不变将器件地址设置为0XBA/0XBB
GPIO_ResetBits(Touch_RST_PORT,Touch_RST_PIN); // 拉低复位引脚,此时芯片执行复位
Touch_IIC_Delay(350000); // 延时
GPIO_SetBits (Touch_RST_PORT,Touch_RST_PIN); // 拉高复位引脚,复位结束
Touch_IIC_Delay(350000); // 延时
Touch_INT_In(); // INT引脚转为浮空输入
Touch_IIC_Delay(350000); // 延时
}
/*****************************************************************************************
* 函 数 名: GT9XX_WriteHandle
* 入口参数: addr - 要操作的寄存器
* 返 回 值: SUCCESS - 操作成功
* ERROR - 操作失败
* 函数功能: GT9XX 写操作
* 说 明:对指定的寄存器执行写操作
******************************************************************************************/
u8 GT9XX_WriteHandle (u16 addr)
{
u8 status; // 状态标志位
Touch_IIC_Start(); // 启动IIC通信
if( Touch_IIC_WriteByte(GT9XX_IIC_WADDR) == ACK_OK ) //写数据指令
{
if( Touch_IIC_WriteByte((u8)(addr >> 8)) == ACK_OK ) //写入16位地址
{
if( Touch_IIC_WriteByte((u8)(addr)) != ACK_OK )
{
status = ERROR; // 操作失败
}
}
}
status = SUCCESS; // 操作成功
return status;
}
/*****************************************************************************************
* 函 数 名: GT9XX_WriteData
* 入口参数: addr - 要写入的寄存器
* value - 要写入的数据
* 返 回 值: SUCCESS - 操作成功
* ERROR - 操作失败
* 函数功能: GT9XX 写一字节数据
* 说 明:对指定的寄存器写入一字节数据
******************************************************************************************/
u8 GT9XX_WriteData (u16 addr,u8 value)
{
u8 status;
Touch_IIC_Start(); //启动IIC通讯
if( GT9XX_WriteHandle(addr) == SUCCESS) //写入要操作的寄存器
{
if (Touch_IIC_WriteByte(value) != ACK_OK) //写数据
{
status = ERROR; // 写入失败
}
}
Touch_IIC_Stop(); // 停止通讯
status = SUCCESS; // 写入成功
return status;
}
/*****************************************************************************************
* 函 数 名: GT9XX_WriteReg
* 入口参数: addr - 要写入的寄存器区域首地址
* cnt - 数据长度
* value - 要写入的数据区
* 返 回 值: SUCCESS - 操作成功
* ERROR - 操作失败
* 函数功能: GT9XX 写寄存器
* 说 明:往芯片的寄存器区写入指定长度的数据
******************************************************************************************/
u8 GT9XX_WriteReg (u16 addr, u8 cnt, u8 *value)
{
u8 status = 0;
u8 i = 0;
Touch_IIC_Start(); // 启动IIC通信
if( GT9XX_WriteHandle(addr) == SUCCESS) //写入要操作的寄存器
{
for(i = 0 ; i < cnt; i++) // 计数
{
Touch_IIC_WriteByte(value[i]); // 写入数据
}
Touch_IIC_Stop(); // 停止IIC通信
status = SUCCESS; // 写入成功
}
else
{
Touch_IIC_Stop(); // 停止IIC通信
status = ERROR; // 写入失败
}
return status;
}
/*****************************************************************************************
* 函 数 名: GT9XX_ReadReg
* 入口参数: addr - 要读取的寄存器区域首地址
* cnt - 数据长度
* value - 要读取的数据区
* 返 回 值: SUCCESS - 操作成功
* ERROR - 操作失败
* 函数功能: GT9XX 读寄存器
* 说 明:从芯片的寄存器区读取指定长度的数据
******************************************************************************************/
u8 GT9XX_ReadReg (u16 addr, u8 cnt, u8 *value)
{
u8 status = 0;
u8 i = 0;
status = ERROR;
Touch_IIC_Start(); // 启动IIC通信
if( GT9XX_WriteHandle(addr) == SUCCESS) // 写入要操作的寄存器
{
Touch_IIC_Start(); // 重新启动IIC通讯
if (Touch_IIC_WriteByte(GT9XX_IIC_RADDR) == ACK_OK) // 发送读命令
{
for(i = 0 ; i < cnt; i++) // 计数
{
if (i == (cnt - 1))
{
value[i] = Touch_IIC_ReadByte(0); // 读到最后一个数据时发送 非应答信号
}
else
{
value[i] = Touch_IIC_ReadByte(1); // 发送应答信号
}
}
Touch_IIC_Stop(); // 停止IIC通信
status = SUCCESS;
}
}
Touch_IIC_Stop();
return (status);
}
/*****************************************************************************************
* 函 数 名: GT9XX_SendCfg
* 入口参数: 无
* 返 回 值:无
* 函数功能: 发送GT9147配置参数
* 说 明:由于GT9147可以掉电保存配置参数并且出厂时已配置好一般情况下用户无需更改
* 用户修改参数之后需要将该函数屏蔽掉不然频繁的写入会将触摸芯片的Flash写坏
******************************************************************************************/
void GT9XX_SendCfg(void)
{
u8 GT9XX_Check[2];
u8 i=0;
GT9XX_Check[1] = 1; // 配置更新标志
for(i=0;i<sizeof(GT9XX_CFG_DATA);i++)
{
GT9XX_Check[0] += GT9XX_CFG_DATA[i]; //计算校验和
}
GT9XX_Check [0] = (~GT9XX_Check[0])+1;
GT9XX_WriteReg(0X8047,sizeof(GT9XX_CFG_DATA),(u8*)GT9XX_CFG_DATA); // 发送寄存器配置
GT9XX_WriteReg(0X80FF,2,GT9XX_Check); // 写入校验和,并更新配置
}
/*****************************************************************************************
* 函 数 名: GT9XX_ReadCfg
* 入口参数: 无
* 返 回 值:无
* 函数功能: 读取GT9147配置参数
* 说 明:通过串口打印数据,在修改数据之前,需要将原厂的参数读取并做好备份,以免改动关键的参数
******************************************************************************************/
void GT9XX_ReadCfg(void)
{
u8 GT9XX_Cfg[184]; // 数组长度取决于实际的芯片的寄存器个数
u16 i = 0;
printf("-----------------------------------------\r\n");
printf("读取芯片配置信息,串口打印输出\r\n");
GT9XX_ReadReg (GT9XX_CFG_ADDR,184,GT9XX_Cfg); // 读配置信息
for(i=0;i<184;i++)
{
if( (i%10 == 0) && (i>0) )
{
printf("\r\n");
}
printf("0X%.2x,",GT9XX_Cfg[i]);
}
printf("\r\n-----------------------------------------\r\n");
}
/*****************************************************************************************
* 函 数 名: Touch_Init
* 入口参数: 无
* 返 回 值: SUCCESS - 初始化成功
* ERROR - 错误,未检测到触摸屏
* 函数功能: 触摸IC初始化并读取相应信息发送到串口
* 说 明: 在程序里周期性的调用该函数,用以检测触摸操作,触摸信息存储在 touchInfo 结构体
******************************************************************************************/
u8 Touch_Init(void)
{
u8 GT9XX_Info[11]; // 触摸屏IC信息
u8 cfgVersion = 0; // 触摸配置版本
Touch_IIC_GPIO_Config(); // 初始化IIC引脚
GT9XX_Reset(); // GT9147 复位
// //读取GT9147配置参数通过串口打印输出
// // 通过串口打印数据,在修改数据之前,需要将原厂的参数读取并做好备份,以免改动关键的参数
// GT9XX_ReadCfg();
// // 发送配置参数由于GT9147可以掉电保存配置参数一般情况下用户无需更改
// //用户修改参数之后需要将该函数屏蔽掉不然频繁的写入会将触摸芯片的Flash写坏
// GT9XX_SendCfg();
GT9XX_ReadReg (GT9XX_ID_ADDR,11,GT9XX_Info); // 读触摸屏IC信息
GT9XX_ReadReg (GT9XX_CFG_ADDR,1,&cfgVersion); // 读触摸配置版本
if( GT9XX_Info[0] == '9' ) // 判断第一个字符是否为 9
{
// printf("Touch ID GT%.4s \r\n",GT9XX_Info); // 打印触摸芯片的ID
// printf("固件版本: 0X%.4x\r\n",(GT9XX_Info[5]<<8) + GT9XX_Info[4]); // 芯片固件版本
// printf("触摸分辨率:%d * %d\r\n",(GT9XX_Info[7]<<8) + GT9XX_Info[6],(GT9XX_Info[9]<<8) +GT9XX_Info[8]); // 当前触摸分辨率
// printf("触摸参数配置版本: 0X%.2x \r\n",cfgVersion); // 触摸配置版本
return SUCCESS;
}
else
{
// printf("未检测到触摸IC\r\n"); //错误,未检测到触摸屏
return ERROR;
}
}
/*****************************************************************************************
* 函 数 名: Touch_Scan
* 入口参数: 无
* 返 回 值: 无
* 函数功能: 触摸扫描
* 说 明: 在程序里周期性的调用该函数,用以检测触摸操作,触摸信息存储在 touchInfo 结构体
******************************************************************************************/
void Touch_Scan(void)
{
u8 touchData[2 + 8 * TOUCH_MAX ]; //用于存储触摸数据
u8 i = 0;
GT9XX_ReadReg (GT9XX_READ_ADDR,2 + 8 * TOUCH_MAX ,touchData); //读数据
GT9XX_WriteData (GT9XX_READ_ADDR,0); // 清除触摸芯片的寄存器标志位
touchInfo.num = touchData[0] & 0x0f; // 取当前的触摸点数若为0则代表无触摸数据发生
if ( (touchInfo.num >= 1) && (touchInfo.num <=5) ) // 当触摸数在 1-5 之间时
{
for(i=0;i<touchInfo.num;i++) // 取相应的触摸坐标
{
// touchInfo.y[i] = 272-((touchData[5+8*i]<<8) | touchData[4+8*i]); // 获取Y坐标
// touchInfo.x[i] = 480-((touchData[3+8*i]<<8) | touchData[2+8*i]); // 获取X坐标
touchInfo.y[i] = ((touchData[5+8*i]<<8) | touchData[4+8*i]); // 获取Y坐标
touchInfo.x[i] = ((touchData[3+8*i]<<8) | touchData[2+8*i]); // 获取X坐标
}
touchInfo.flag = 1; // 触摸标志位置1代表有触摸动作发生
}
else
{
for(i=0;i<TOUCH_MAX;i++) // 取相应的触摸坐标
{
touchInfo.y[i] =0; // 获取Y坐标
touchInfo.x[i] =0; // 获取X坐标
}
touchInfo.flag = 0; // 触摸标志位置0无触摸动作
}
}
TouchStructure *Touch_GetState(void)
{
return &touchInfo;
}
/******************************************************************************************/