使用板类型和屏幕类型
本文使用安富莱的板子stm32f429, 屏幕是TR433C1的4.3寸TFT显示屏, 480*272 RGB接口, 电容触摸 .
I2C
I2C请参阅本文的介绍、原理和顺序
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 : 读取数据缓冲区的大小
第一步:软件复位
通过给寄存器0x写入8040地址的寄存器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引脚会输出一个边沿信号, 我们只要在单片机中, 设置对应的连接引脚为中断引脚, 就可以实时知道屏幕是否被触摸 ,这里我不用这个判断方法。
触摸后读出数据
这里表示的是所有的5个位置的信息数据, 我们就拿第一个来举例:
我们只要在 寄存器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,