hal编程 gt911 触摸芯片驱动 ( 枚举 结构体 熟用)( 安富莱 f429 4.3寸电容屏 )
使用板子类型以及屏幕类型
本文使用的是安富莱的板子stm32f429,
屏幕是TR433C1的4.3寸TFT显示屏, 480*272 RGB接口, 电容触摸 .
I2C
I2C简介、原理、时序请看这篇文章
使用cubemx工具的stm32用AT24C02实现简单密码(一点点面向对象的思想编程)
gt911
gt911简介
gt911是深圳市汇鼎科技开发
- 专为7英寸到8英寸MID设计的新一代5点电容式触摸,由多达26个发射器电极和14个接收器电极组成,以提供更高的触摸精度。
- gt911可同时识别 5 个触摸点位的实时准确位置,移动轨迹及触摸面积。并可根据主控需要,读取相应点数的触摸信息。
gt911的地址(8位地址情况)
gt911和其他基于i2c的芯片略有不同,它可以通过,外部引脚INT和RST引脚改变他的地址,一般地址默认是0xBA,通过用INT和RESET引脚可以输入特定的时序,改变他的地址,变为0x28,或者变回0xBA,时序如下:
地址变成0x28
- INT和RESET都为输出模式
地址变成0xBA
- INT和RESET都为输出模式
地址配置完成后
配置之后,RST保持拉高输出,INT配置成输入(变成中断线,当有中断来临时,有触摸发生),或者失能(直接通过寄存器来判断是否有触摸)。
gt911配置说明
基本写芯片和读芯片代码
void GT911_WriteReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen)
{HAL_I2C_Mem_Write(&hi2c1, GT911_DIV_W, _usRegAddr, I2C_MEMADD_SIZE_16BIT, _pRegBuf, _ucLen, 0xff);
}void GT911_ReadReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen)
{HAL_I2C_Mem_Read(&hi2c1, GT911_DIV_R, _usRegAddr, I2C_MEMADD_SIZE_16BIT, _pRegBuf, _ucLen, 0xff);
}
对于hal函数说明:
- HAL_I2C_Mem_Write
参数1 : hal生成的i2c句柄
参数2 : gt911的写地址,0xBA(0x28)
参数3 : 寄存器地址
参数4 : 寄存器大小,有8位模式,16位模式,这里选择16位模式
参数5 : 写入寄存器的数据
参数6 : 写入的数据长度
参数7 : 等待超时时间,超出此时间未发出去,则发送失败- HAL_I2C_Mem_Read(未写的参数和上面的一样)
参数2 : gt911的读地址,0xBB(0x29)
参数5 : 要读出的寄存器的数据缓冲区
参数6 : 读出数据缓冲区大小
第一步:软件复位
通过给寄存器0x8040地址的寄存器写入2,复位gt911芯片.,代码如下所示
/*功能:软件复位gt911
*/
void Software_Reset(void)
{uint8_t _temp=2; //中间变量//往gt911中寄存器0x8040中写入2,使之复位GT911_WriteReg(GT_CTRL_REG, &_temp, 1);
}
第二步:往配置寄存器中写入数据(一般可以跳过)
代码如下:
//GT911(原GT9147)配置参数表
//第一个字节为版本号(0X60),必须保证新的版本号大于等于GT911内部
//flash原有版本号,才会更新配置.
const uint8_t GT9147_CFG_TBL[]=
{ 0X60,0XE0,0X01,0X20,0X03,0X05,0X35,0X00,0X02,0X08,0X1E,0X08,0X50,0X3C,0X0F,0X05,0X00,0X00,0XFF,0X67,0X50,0X00,0X00,0X18,0X1A,0X1E,0X14,0X89,0X28,0X0A,0X30,0X2E,0XBB,0X0A,0X03,0X00,0X00,0X02,0X33,0X1D,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X32,0X00,0X00,0X2A,0X1C,0X5A,0X94,0XC5,0X02,0X07,0X00,0X00,0X00,0XB5,0X1F,0X00,0X90,0X28,0X00,0X77,0X32,0X00,0X62,0X3F,0X00,0X52,0X50,0X00,0X52,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,0X0F,0X03,0X06,0X10,0X42,0XF8,0X0F,0X14,0X00,0X00,0X00,0X00,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,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
};/*配置gt911,发送gt911配置参数参数1:mode(0,参数不保存到flash1,参数保存到flash)
*/
void GT911_Send_Config(uint8_t mode)
{uint8_t buf[2];buf[0] = 0;buf[1] = mode; //是否写入到GT9147 FLASH? 即是否掉电保存for(uint8_t i=0; i<sizeof(GT9147_CFG_TBL); i++){buf[0] += GT9147_CFG_TBL[i];//计算校验和}buf[0]=(~buf[0])+1;GT911_WriteReg(GT_CFGS_REG, (uint8_t *)GT9147_CFG_TBL, sizeof(GT9147_CFG_TBL));//发送寄存器配置GT911_WriteReg(GT_CHECK_REG, buf, 2);//写入校验和,和配置更新标记
}
第三步:结束软件复位
通过给寄存器0x8040地址的寄存器写入0,结束复位gt911芯片,代码如下所示
/*功能:软件复位gt911
*/
void Software_Reset(void)
{uint8_t _temp=0; //中间变量//往gt911中寄存器0x8040中写入0,使之结束复位GT911_WriteReg(GT_CTRL_REG, &_temp, 1);
}
gt911使用说明
判断是否被触摸
当我们触摸屏幕时,
寄存器0x814E的最高位(bit7)位会被置位为1, 低4位为触摸的点的数量, 最多支持5个点。我们只要在while中不断轮询判断, 寄存器最高位是否置位,就可以知道, 屏幕是否被触摸(轮询时间长一点要不然会读不出来的, 可以在函数中设置一个计数阀门,当进入一定次数读取一次寄存器,再判断。)
INT引脚会输出一个边沿信号, 我们只要在单片机中, 设置对应的连接引脚为中断引脚, 就可以实时知道屏幕是否被触摸 ,这里我不用这个判断方法。
注意事项:当我们读完寄存器0x814E后, 要清0该寄存器, 表示已读, 要不然他会不断输出中断信号。
触摸后读出数据
这里表示的是所有的5个位置的信息数据, 我们就拿第一个来举例:
每个位置信息都由16+16+16位数据表示, 第一个16位是x的位置数据, 第二个16位是y的位置数据, 第三个是位置上的触摸面积。
每个16位又由两个寄存器的8位数据构成,先是低8位,后是高8位。
我们只要在
寄存器0x8150中读出x的低8位数据,
然后读出寄存器0x8151读出x的高8位数据,
把数据组合成x的16位的数据,y的数据, 触摸面积数据读出方式一样。
触摸轮询代码
代码如下所示:
/*功能:gt911触摸扫描,判断当前是否被触摸参数1:
*/
void gt911_Scanf(void)
{static uint8_t timer_=0;timer_++;if(timer_<10){return;}timer_=0;uint8_t _temp; //中间变量GT911_ReadReg(GT_GSTID_REG, &_temp, 1);User_Touch.Touch_State = (_temp & 0x80); //触摸状态User_Touch.Touch_Number = (_temp & 0x0f); //获取触摸点数switch(User_Touch.Touch_State) //判断是否有触摸数据{case TOUCH__NO: //没有数据break;case TOUCH_ING: //触摸中~后,有数据,并读出数据for(uint8_t i=0; i<User_Touch.Touch_Number; i++)//读出触摸点数的所有数据{GT911_ReadReg((GT_TPD_Sta + i*8 + X_L), &_temp, 1); //读出触摸x坐标的低8位User_Touch.Touch_XY[i].X_Point = _temp;GT911_ReadReg((GT_TPD_Sta + i*8 + X_H), &_temp, 1); //读出触摸x坐标的高8位User_Touch.Touch_XY[i].X_Point |= (_temp<<8);GT911_ReadReg((GT_TPD_Sta + i*8 + Y_L), &_temp, 1); //读出触摸y坐标的低8位User_Touch.Touch_XY[i].Y_Point = _temp;GT911_ReadReg((GT_TPD_Sta + i*8 + Y_H), &_temp, 1); //读出触摸y坐标的高8位User_Touch.Touch_XY[i].Y_Point |= (_temp<<8);GT911_ReadReg((GT_TPD_Sta + i*8 + S_L), &_temp, 1); //读出触摸大小数据的低8位User_Touch.Touch_XY[i].S_Point = _temp;GT911_ReadReg((GT_TPD_Sta + i*8 + S_H), &_temp, 1); //读出触摸大小数据的高8位User_Touch.Touch_XY[i].S_Point |= (_temp<<8);}_temp=0;GT911_WriteReg(GT_GSTID_REG, &_temp, 1); //清除数据标志位break;}
}
代码完整版本
gt911.c
#include "gt911.h"
#include "O_redirect.h"//GT911(原GT9147)配置参数表
//第一个字节为版本号(0X60),必须保证新的版本号大于等于GT911内部
//flash原有版本号,才会更新配置.
const uint8_t GT9147_CFG_TBL[]=
{ 0X60,0XE0,0X01,0X20,0X03,0X05,0X35,0X00,0X02,0X08,0X1E,0X08,0X50,0X3C,0X0F,0X05,0X00,0X00,0XFF,0X67,0X50,0X00,0X00,0X18,0X1A,0X1E,0X14,0X89,0X28,0X0A,0X30,0X2E,0XBB,0X0A,0X03,0X00,0X00,0X02,0X33,0X1D,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X32,0X00,0X00,0X2A,0X1C,0X5A,0X94,0XC5,0X02,0X07,0X00,0X00,0X00,0XB5,0X1F,0X00,0X90,0X28,0X00,0X77,0X32,0X00,0X62,0X3F,0X00,0X52,0X50,0X00,0X52,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,0X0F,0X03,0X06,0X10,0X42,0XF8,0X0F,0X14,0X00,0X00,0X00,0X00,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,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
}; /*创建触摸结构体*/
Touch_Struct User_Touch;void GT911_WriteReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen)
{HAL_I2C_Mem_Write(>911_I2C, GT911_DIV_W, _usRegAddr, I2C_MEMADD_SIZE_16BIT, _pRegBuf, _ucLen, 0xff);
}
void GT911_ReadReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen)
{HAL_I2C_Mem_Read(>911_I2C, GT911_DIV_R, _usRegAddr, I2C_MEMADD_SIZE_16BIT, _pRegBuf, _ucLen, 0xff);
}/*配置gt911,发送gt911配置参数参数1:mode(0,参数不保存到flash1,参数保存到flash)
*/
void GT911_Send_Config(uint8_t mode)
{uint8_t buf[2];buf[0] = 0;buf[1] = mode; //是否写入到GT9147 FLASH? 即是否掉电保存for(uint8_t i=0; i<sizeof(GT9147_CFG_TBL); i++){buf[0] += GT9147_CFG_TBL[i];//计算校验和}buf[0]=(~buf[0])+1;GT911_WriteReg(GT_CFGS_REG, (uint8_t *)GT9147_CFG_TBL, sizeof(GT9147_CFG_TBL));//发送寄存器配置GT911_WriteReg(GT_CHECK_REG, buf, 2);//写入校验和,和配置更新标记
}/*功能:软件复位gt911参数1:gt_SR_type(为1时开始软件复位,为0时结束软件复位)
*/
void Software_Reset(uint8_t gt_SR_type)
{uint8_t _temp=0; //中间变量if(gt_SR_type){_temp=2;GT911_WriteReg(GT_CTRL_REG, &_temp, 1);}else{_temp=0;GT911_WriteReg(GT_CTRL_REG, &_temp, 1);}
}/*功能:gt911触摸扫描,判断当前是否被触摸参数1:
*/
void gt911_Scanf(void)
{static uint8_t timer_=0;timer_++;if(timer_<10) //防止短时间多次进入判断{return;}timer_=0;uint8_t _temp; //中间变量GT911_ReadReg(GT_GSTID_REG, &_temp, 1);//读0x814E寄存器User_Touch.Touch_State = _temp;User_Touch.Touch_Number = (User_Touch.Touch_State & 0x0f); //获取触摸点数User_Touch.Touch_State = (User_Touch.Touch_State & 0x80); //触摸状态switch(User_Touch.Touch_State) //判断是否有触摸数据{case TOUCH__NO: //没有数据break;case TOUCH_ING: //触摸中~后,有数据,并读出数据for(uint8_t i=0; i<User_Touch.Touch_Number; i++){GT911_ReadReg((GT_TPD_Sta + i*8 + X_L), &_temp, 1); //读出触摸x坐标的低8位User_Touch.Touch_XY[i].X_Point = _temp;GT911_ReadReg((GT_TPD_Sta + i*8 + X_H), &_temp, 1); //读出触摸x坐标的高8位User_Touch.Touch_XY[i].X_Point |= (_temp<<8);GT911_ReadReg((GT_TPD_Sta + i*8 + Y_L), &_temp, 1); //读出触摸y坐标的低8位User_Touch.Touch_XY[i].Y_Point = _temp;GT911_ReadReg((GT_TPD_Sta + i*8 + Y_H), &_temp, 1); //读出触摸y坐标的高8位User_Touch.Touch_XY[i].Y_Point |= (_temp<<8);GT911_ReadReg((GT_TPD_Sta + i*8 + S_L), &_temp, 1); //读出触摸大小数据的低8位User_Touch.Touch_XY[i].S_Point = _temp;GT911_ReadReg((GT_TPD_Sta + i*8 + S_H), &_temp, 1); //读出触摸大小数据的高8位User_Touch.Touch_XY[i].S_Point |= (_temp<<8);}_temp=0;GT911_WriteReg(GT_GSTID_REG, &_temp, 1); //清除数据标志位break;}
}
gt911.h
#ifndef __GT911_H_
#define __GT911_H_#include "i2c.h"/*I2C句柄*/
#define GT911_I2C hi2c1#define GT911_DIV_ID 0XBA //设备地址 //0X28 //0XBA#define GT911_DIV_W (GT911_DIV_ID | 0) //写地址
#define GT911_DIV_R (GT911_DIV_ID | 1) //读地址//GT911 部分寄存器定义
#define GT_CTRL_REG 0X8040 //GT911控制寄存器
#define GT_CFGS_REG 0X8047 //GT911配置起始地址寄存器
#define GT_CHECK_REG 0X80FF //GT911校验和寄存器
#define GT_PID_REG 0X8140 //GT911产品ID寄存器#define GT_GSTID_REG 0X814E //GT911当前检测到的触摸情况,第7位是触摸标志位,低4位是触摸点数个数#define GT_TPD_Sta 0X8150 //触摸点起始数据地址
#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 //第五个触摸点数据地址#define GT_TOUCH_MAX 5 //对于gt911,最多同时获取5个触摸点的数据typedef enum
{X_L = 0,X_H = 1,Y_L = 2,Y_H = 3,S_L = 4,S_H = 5
}Data_XYS_P; //数据X、Y、触摸大小数据偏移量typedef enum
{TOUCH__NO = 0x00, //没有触摸TOUCH_ING = 0x80 //被触摸
}TOUCH_STATE_enum; //触摸状态typedef struct
{uint16_t X_Point; //X坐标uint16_t Y_Point; //Y坐标uint16_t S_Point; //触摸点大小
}XY_Coordinate; //触摸点坐标/*触摸结构体*/
typedef struct
{uint8_t Touch_State ; //触摸状态uint8_t Touch_Number ; //触摸数量XY_Coordinate Touch_XY[GT_TOUCH_MAX] ; //触摸的x坐标,对于gt911最多5个点的坐标
}Touch_Struct; //触摸信息结构体/*外部变量区*/
extern Touch_Struct User_Touch;/*外部函数区*/
void GT911_WriteReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen);
void GT911_ReadReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen);void GT911_Send_Config(uint8_t mode); //配置初始化ft911
void Software_Reset(uint8_t gt_SR_type);//复位或者不复位gt911
void gt911_Scanf(void); //扫描触摸模块#endif /*__GT911_H_*/
main.c
头文件引用
#include "gt911.h"
my_gt911函数
gt911_Scanf(); //不断扫描if(User_Touch.Touch_State == 0x80){for(uint8_t i=0; i<User_Touch.Touch_Number; i++){PrintfDebug("X : %d ", User_Touch.Touch_XY[i].X_Point);PrintfDebug("Y : %d ", User_Touch.Touch_XY[i].Y_Point);PrintfDebug("S : %d\r\n\r\n", User_Touch.Touch_XY[i].S_Point);}User_Touch.Touch_State = 0;User_Touch.Touch_Number = 0;}
主函数部分
效果
参考资料
一、数据手册
二、电容触摸屏GT911、GT928、GT9147的使用
hal编程 gt911 触摸芯片驱动 ( 枚举 结构体 熟用)( 安富莱 f429 4.3寸电容屏 )相关推荐
- 野火STM32F103驱动GT911触摸芯片
GT911触摸芯片 芯片介绍 GT911 是专为 7"~8"设计的新一代 5 点电容触控方案,拥有 26 个驱动通道和 14 个感 应通道,以满足更高的 touch 精度要求. G ...
- C#学习笔记_12_枚举结构体
12_枚举&结构体 枚举 是一种数据类型 适用于某些取值范围有限的数据 语法: [访问权限修饰符] enum 枚举名 { 枚举值 } 枚举名遵循大驼峰命名法 枚举一般情况下是和switch c ...
- c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体
枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...
- 《安富莱嵌入式周报》第280期:支持在线仿真编程的网页版电子开发,CAN总线防攻击实现,BigFAT 规范打破了 FAT 每个文件 4GB 的限制
往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...
- 《安富莱嵌入式周报》第292期:树莓派单片机100M双通道示波器开源,MDK5.38发布,万用表单芯片解决方案,8通道±25V模拟前端芯片,开源贴片拾取电机板
往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...
- 《安富莱嵌入式周报》第278期:基于RUST编程语言RTOS,固态继电器芯片,微软发布物联网组件框架,支持多款蜂窝,LoRa和WiFi芯片工业物联网4.0书籍
往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...
- 《安富莱嵌入式周报》第307期:开源智能制冷板,Keil MDK6发布时间,编程助手Github Copilot X,Matlab2023,高品质电容式麦DIY
周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Pow ...
- 《安富莱嵌入式周报》第284期:Matlab2022b发布,支持从 .NET 调用,耳机放大器,牛屎芯片替换,JSON可视化,开源的飞行软件和嵌入式系统框架
往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...
- 《安富莱嵌入式周报》第310期:集成大语言模型的开源调试器ChatDBG, 多功能开源计算器,M7内核航空航天芯片评估板, Zigbee PRO规范
周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Pow ...
最新文章
- iOS 13 如何删除SceneDelegate
- 学会感恩会使你回报的更多!
- 信息奥赛一本通(1413:确定进制)
- VMWARE 构建局域网 + VMWARE SQL Server 服务器搭建
- 创科视觉软件说明书_【纳博特斯克 | GGII】20192023年中国机器视觉行业调研
- Quartz的定时任务实现
- hdu 4421(枚举+2-sat)
- [渝粤教育] 中国地质大学 经济学原理 复习题
- mysql查看autocommit_我所理解的MySQL(四)事务、隔离级别及MVCC
- 离散数学第六版第er章偶数题答案_离散数学答案--第二章习题解答.doc
- 善领dsa2020最新车机ce版_科技测丨需要在车机和手机中“二选一”的凯迪拉克
- QOS端口限速EMAIL流量限速
- 亲自动手写爬虫系列一、实现一个最简单爬虫
- 西门子PLC封装TCP通讯块和调试助手进行TCP仿真测试
- USB Composite 组合设备之多路CDC实现
- caffe常用层:特殊的Math函数
- 这8种恶心虫子 你可能每天都在吃!
- PHPStudy 安装amqp扩展
- C#导出pdf文件《一》
- KeyError: ((1, 1), ‘<i8‘)