野火STM32F103驱动GT911触摸芯片

news/2024/11/23 4:40:45/

GT911触摸芯片

芯片介绍

GT911 是专为 7”~8”设计的新一代 5 点电容触控方案,拥有 26 个驱动通道和 14 个感 应通道,以满足更高的 touch 精度要求。 GT911 可同时识别 5 个触摸点位的实时准确位置移动轨迹触摸面积。并可根据主控需要,读取相应点数的触摸信息。

芯片原理图

管脚定义

管脚号

名称

功能描述

备注

1~11

SEN3~SEN13

触摸模拟信号输入

12

AVDD28

模拟电源正

接 2.2uF 滤波电容

13

AVDD18

接 2.2uF 滤波电容

14

DVDD12

接 2.2uF 滤波电容

15

DGND

数字信号地

16

INT

中断信号

17

Sensor_OPT1

模组识别口

18

Sensor_OPT2

模组识别口(备选)

需外部下拉

19

I2C_SDA

I2C 数据信号

20

I2C_SCL

I2C 时钟信号

21

VDDIO

GPIO 电平控制

接 2.2uF 滤波电容

悬空:1.8V

接 AVDD:AVDD

22

/RSTB

系统复位脚

需外部 10K 上拉,拉低复位

23~48

DRV25~DRV0

驱动信号输出

49

AGND

模拟电源地

50~52

SEN0~SEN2

触摸模拟信号输入

I2C通信

GT911 提供标准的 I 2 C 通讯接口,由 SCL 和 SDA 与主 CPU 进行通讯。 在系统中 GT911 始终作为从设备,所有通讯都是由主 CPU 发起,建议通讯速度为 400Kbps 或 以下。其支持的 I 2 C 硬件电路支持时序如下:

GT911 的 I 2 C 从设备地址有两组,分别为 0xBA/0xBB 和 0x28/0x29。主控在上电初始 化时控制 Reset 和 INT 口状态进行设定,设定方法及时序图如下:

上电时序图:

设定地址为0x28/0x29的时序:

设定地址为 0xBA/0xBB 的时序:

IIC通信实例(以设备地址为 0xBA/0xBB 为例)

数据传输

通讯总是由主 CPU 发起,有效的起始信号为:在 SCL 保持为“1”时,SDA 上发生由“1” 到“0”的跳变。地址信息或数据流均在起始信号之后传输。

所有连接在I 2 C总线上的从设备,都要检测总线上起始信号之后所发送的8位地址信息, 并做出正确反应。在收到与自己相匹配的地址信息时,GT911 在第 9 个时钟周期,将 SDA 改为输出口,并置“0”作为应答信号。若收到不与自己匹配的地址信息,即非 0XBA 或 0XBB,GT911 将保持闲置状态。

SDA 口上的数据按 9 个时钟周期串行发送 9 位数据:8 位有效数据+1 位接收方发送的 应答信号 ACK 或非应答信号 NACK。数据传输在 SCL 为“1”时有效。 当通讯完成时,由主 CPU 发送停止信号。停止信号是当 SCL 为“1”时,SDA 状态由“0” 到“1”的跳变。

对 GT911 写操作

上图为主 CPU 对 GT911 进行的写操作流程图。

首先主 CPU 产生一个起始信号,然后 发送地址信息及读写位信息“0”表示写操作:0XBA。 在收到应答后,主 CPU 发送寄存器的 16 位地址,随后是 8 位要写入到寄存器的数据 内容。 GT911 寄存器的地址指针会在写操作后自动加 1,所以当主 CPU 需要对连续地址的寄 存器进行写操作时,可以在一次写操作中连续写入。写操作完成,主 CPU 发送停止信 号结束当前写操作。

对 GT911 读操作

上图为主 CPU 对 GT911 进行的读操作流程图。

首先主 CPU 产生一个起始信号,然后 发送设备地址信息及读写位信息“0”表示写操作:0XBA。 在收到应答后,主 CPU 发送首寄存器的 16 位地址信息,设置要读取的寄存器地址。 在收到应答后,主 CPU 重新发送一次起始信号,发送读操作:0XBB。收到应答后, 主 CPU 开始读取数据

GT911 同样支持连续的读操作,默认为连续读取数据。主 CPU 在每收到一个 Byte 数 据后需发送一个应答信号表示成功接收。在接收到所需的最后一个Byte数据后,主CPU 发送“非应答信号 NACK”,然后再发送停止信号结束通讯。

详细代码

主函数

/********************************************************************************* @file    main.c* @author  GYLJ* @version V1.0* @date    2022-10-xx* @brief   电容触摸屏-GT911触摸芯片测试******************************************************************************* @attention** 实验平台:野火  STM32 F103 霸道开发板 * 论坛    :http://www.firebbs.cn* 淘宝    :https://fire-stm32.taobao.com********************************************************************************/#include "stm32f10x.h"   // 相当于51单片机中的  #include <reg51.h>
#include "gt9xx.h"
#include "bsp_usart.h"
#include "core_delay.h" 
/*** @brief  主函数* @param  无  * @retval 无*/
int main ( void )
{USART_Config();    /* 初始化内核定时器 */CPU_TS_TmrInit();/* 触摸芯片初始化 */GTP_Init_Panel(); printf("\r\n ********** 触摸面板程序 *********** \r\n");while ( 1 ){}
}

GT9xx.C

/********************************************************************************* @file    gtxx.c* @author  fire* @version V1.0* @date    2015-xx-xx* @brief   i2c电容屏驱动函数gt9157/GT917S/gt5688芯片******************************************************************************* @attention** 实验平台:野火  STM32 F429 开发板 * 论坛    :http://www.firebbs.cn* 淘宝    :https://fire-stm32.taobao.com********************************************************************************/ 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "gt9xx.h"
#include "bsp_i2c_touch.h"// 7寸屏GT917S驱动配置
const uint8_t CTP_CFG_GT917S[] =  {0x84,0x20,0x03,0xE0,0x01,0x05,0x05,0x00,0x00,0x40,0x00,0x0F,0x78,0x64,0x53,0x11,0x00,0x00,0x00,0x00,0x23,0x17,0x19,0x1D,0x0F,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x51,0x14,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x00,0x50,0x38,0x28,0x8A,0x20,0x11,0x37,0x39,0xA2,0x07,0x38,0x6D,0x28,0x11,0x03,0x24,0x00,0x01,0x28,0x50,0xC0,0x94,0x02,0x00,0x00,0x53,0xB8,0x2E,0xA2,0x35,0x8F,0x3B,0x80,0x42,0x75,0x49,0x6B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x4C,0x3C,0xFF,0xFF,0x07,0x14,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x73,0x50,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1D,0x1B,0x1A,0x19,0x18,0x17,0x16,0x15,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1C,0x1B,0x1A,0x19,0x18,0x17,0x15,0x14,0x13,0x12,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x05,0x00,0x00,0x0F,0x00,0x00,0x00,0x80,0x46,0x08,0x96,0x50,0x32,0x0A,0x0A,0x64,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x03,0x0C,0x08,0x23,0x00,0x14,0x23,0x00,0x28,0x46,0x30,0x3C,0xD0,0x07,0x50,0x70,0xB0,0x01
};//uint8_t config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH]
//                = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff};/* 触摸IC类型默认为5寸屏的ic */
TOUCH_IC touchIC = GT917S;        const TOUCH_PARAM_TypeDef touch_param[1] = 
{/* GT917S,4.3寸屏 */{.max_width = 800,.max_height = 480,.config_reg_addr = 0x8050,}
};static int8_t GTP_I2C_Test(void);
//static void GT91xx_Config_Read_Proc(void);static void Delay(__IO uint32_t nCount)     //简单的延时函数
{for(; nCount != 0; nCount--);
}/*** @brief   使用IIC进行数据传输* @param*        @arg i2c_msg:数据传输结构体*        @arg num:数据传输结构体的个数* @retval  正常完成的传输结构个数,若不正常,返回0xff*/
static int I2C_Transfer( struct i2c_msg *msgs,int num)
{int im = 0;int ret = 0;GTP_DEBUG_FUNC();for (im = 0; ret == 0 && im != num; im++){if ((msgs[im].flags&I2C_M_RD))                                                                //根据flag判断是读数据还是写数据{ret = I2C_ReadBytes(msgs[im].addr, msgs[im].buf, msgs[im].len);        //IIC读取数据} else{ret = I2C_WriteBytes(msgs[im].addr,  msgs[im].buf, msgs[im].len);    //IIC写入数据}}if(ret)return ret;return im;                                                       //正常完成的传输结构个数
}/*** @brief   从IIC设备中读取数据* @param*        @arg client_addr:设备地址*        @arg  buf[0~1]: 读取数据寄存器的起始地址*        @arg buf[2~len-1]: 存储读出来数据的缓冲buffer*        @arg len:    GTP_ADDR_LENGTH + read bytes count(寄存器地址长度+读取的数据字节数)* @retval  i2c_msgs传输结构体的个数,2为成功,其它为失败*/
static int32_t GTP_I2C_Read(uint8_t client_addr, uint8_t *buf, int32_t len)
{struct i2c_msg msgs[2];int32_t ret=-1;int32_t retries = 0;GTP_DEBUG_FUNC();/*一个读数据的过程可以分为两个传输过程:* 1. IIC  写入 要读取的寄存器地址* 2. IIC  读取  数据* */msgs[0].flags = !I2C_M_RD;                    //写入msgs[0].addr  = client_addr;                    //IIC设备地址msgs[0].len   = GTP_ADDR_LENGTH;    //寄存器地址为2字节(即写入两字节的数据)msgs[0].buf   = &buf[0];                        //buf[0~1]存储的是要读取的寄存器地址msgs[1].flags = I2C_M_RD;                    //读取msgs[1].addr  = client_addr;                    //IIC设备地址msgs[1].len   = len - GTP_ADDR_LENGTH;    //要读取的数据长度msgs[1].buf   = &buf[GTP_ADDR_LENGTH];    //buf[GTP_ADDR_LENGTH]之后的缓冲区存储读出的数据while(retries < 5){ret = I2C_Transfer( msgs, 2);                    //调用IIC数据传输过程函数,有2个传输过程if(ret == 2)break;retries++;}if((retries >= 5)){GTP_ERROR("I2C Read: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((uint16_t)(buf[0] << 8)) | buf[1]), len-2, ret);}return ret;
}/*** @brief   向IIC设备写入数据* @param*        @arg client_addr:设备地址*        @arg  buf[0~1]: 要写入的数据寄存器的起始地址*        @arg buf[2~len-1]: 要写入的数据*        @arg len:    GTP_ADDR_LENGTH + write bytes count(寄存器地址长度+写入的数据字节数)* @retval  i2c_msgs传输结构体的个数,1为成功,其它为失败*/
static int32_t GTP_I2C_Write(uint8_t client_addr,uint8_t *buf,int32_t len)
{struct i2c_msg msg;int32_t ret = -1;int32_t retries = 0;GTP_DEBUG_FUNC();/*一个写数据的过程只需要一个传输过程:* 1. IIC连续 写入 数据寄存器地址及数据* */msg.flags = !I2C_M_RD;            //写入msg.addr  = client_addr;            //从设备地址msg.len   = len;                            //长度直接等于(寄存器地址长度+写入的数据字节数)msg.buf   = buf;                        //直接连续写入缓冲区中的数据(包括了寄存器地址)while(retries < 5){ret = I2C_Transfer(&msg, 1);    //调用IIC数据传输过程函数,1个传输过程if (ret == 1)break;retries++;}if((retries >= 5)){GTP_ERROR("I2C Write: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((uint16_t)(buf[0] << 8)) | buf[1]), len-2, ret);}return ret;
}/*** @brief   使用IIC读取再次数据,检验是否正常* @param*        @arg client:设备地址*        @arg  addr: 寄存器地址*        @arg rxbuf: 存储读出的数据*        @arg len:    读取的字节数* @retval*     @arg FAIL*     @arg SUCCESS*/int32_t GTP_I2C_Read_dbl_check(uint8_t client_addr, uint16_t addr, uint8_t *rxbuf, int len)
{uint8_t buf[16] = {0};uint8_t confirm_buf[16] = {0};uint8_t retry = 0;GTP_DEBUG_FUNC();while (retry++ < 3){memset(buf, 0xAA, 16);buf[0] = (uint8_t)(addr >> 8);buf[1] = (uint8_t)(addr & 0xFF);GTP_I2C_Read(client_addr, buf, len + 2);memset(confirm_buf, 0xAB, 16);confirm_buf[0] = (uint8_t)(addr >> 8);confirm_buf[1] = (uint8_t)(addr & 0xFF);GTP_I2C_Read(client_addr, confirm_buf, len + 2);if (!memcmp(buf, confirm_buf, len+2)){memcpy(rxbuf, confirm_buf+2, len);return SUCCESS;}}    GTP_ERROR("I2C read 0x%04X, %d bytes, double check failed!", addr, len);return FAIL;
}/*** @brief   关闭GT91xx中断* @param 无* @retval 无*/
void GTP_IRQ_Disable(void)
{GTP_DEBUG_FUNC();}/*** @brief   使能GT91xx中断* @param 无* @retval 无*/
void GTP_IRQ_Enable(void)
{GTP_DEBUG_FUNC();I2C_GTP_IRQEnable();
}/*** @brief   用于处理或报告触屏检测到按下* @param*    @arg     id: 触摸顺序trackID*    @arg     x:  触摸的 x 坐标*    @arg     y:  触摸的 y 坐标*    @arg     w:  触摸的 大小* @retval 无*/
/*用于记录连续触摸时(长按)的上一次触摸位置,负数值表示上一次无触摸按下*/
volatile static int16_t pre_x[GTP_MAX_TOUCH] ={-1,-1,-1,-1,-1};
volatile static int16_t pre_y[GTP_MAX_TOUCH] ={-1,-1,-1,-1,-1};static void GTP_Touch_Down(int32_t id,int32_t x,int32_t y,int32_t w)
{GTP_DEBUG_FUNC();/*取x、y初始值大于屏幕像素值*/GTP_DEBUG("ID:%d, X:%d, Y:%d, W:%d", id, x, y, w);/************************************//*在此处添加自己的触摸点按下时处理过程即可*//* (x,y) 即为最新的触摸点 *************//************************************//*prex,prey数组存储上一次触摸的位置,id为轨迹编号(多点触控时有多轨迹)*/pre_x[id] = x; pre_y[id] =y;}/*** @brief   用于处理或报告触屏释放* @param 释放点的id号* @retval 无*/
static void GTP_Touch_Up( int32_t id)
{/*****************************************//*在此处添加自己的触摸点释放时的处理过程即可*//* pre_x[id],pre_y[id] 即为最新的释放点 ****//*******************************************/    /***id为轨迹编号(多点触控时有多轨迹)********//*触笔释放,把pre xy 重置为负*/pre_x[id] = -1;pre_y[id] = -1;        GTP_DEBUG("Touch id[%2d] release!", id);}/*** @brief   触屏处理函数,轮询或者在触摸中断调用* @param 无* @retval 无*/
static void Goodix_TS_Work_Func(void)
{uint8_t  end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0};uint8_t  point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF};uint8_t  touch_num = 0;uint8_t  finger = 0;static uint16_t pre_touch = 0;static uint8_t pre_id[GTP_MAX_TOUCH] = {0};uint8_t client_addr=GTP_ADDRESS;uint8_t* coor_data = NULL;int32_t input_x = 0;int32_t input_y = 0;int32_t input_w = 0;uint8_t id = 0;int32_t i  = 0;int32_t ret = -1;GTP_DEBUG_FUNC();ret = GTP_I2C_Read(client_addr, point_data, 12);//10字节寄存器加2字节地址if (ret < 0){GTP_ERROR("I2C transfer error. errno:%d\n ", ret);return;}finger = point_data[GTP_ADDR_LENGTH];//状态寄存器数据if (finger == 0x00)        //没有数据,退出{return;}if((finger & 0x80) == 0)//判断buffer status位{goto exit_work_func;//坐标未就绪,数据无效}touch_num = finger & 0x0f;//坐标点数if (touch_num > GTP_MAX_TOUCH){goto exit_work_func;//大于最大支持点数,错误退出}if (touch_num > 1)//不止一个点{uint8_t buf[8 * GTP_MAX_TOUCH] = {(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff};ret = GTP_I2C_Read(client_addr, buf, 2 + 8 * (touch_num - 1));memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1));            //复制其余点数的数据到point_data}if (pre_touch>touch_num)                //pre_touch>touch_num,表示有的点释放了{for (i = 0; i < pre_touch; i++)                        //一个点一个点处理{uint8_t j;for(j=0; j<touch_num; j++){coor_data = &point_data[j * 8 + 3];id = coor_data[0] & 0x0F;                                    //track idif(pre_id[i] == id)break;if(j >= touch_num-1)                                            //遍历当前所有id都找不到pre_id[i],表示已释放{GTP_Touch_Up( pre_id[i]);}}}}if (touch_num){for (i = 0; i < touch_num; i++)                        //一个点一个点处理{coor_data = &point_data[i * 8 + 3];id = coor_data[0] & 0x0F;                                    //track idpre_id[i] = id;input_x  = coor_data[1] | (coor_data[2] << 8);    //x坐标input_y  = coor_data[3] | (coor_data[4] << 8);    //y坐标input_w  = coor_data[5] | (coor_data[6] << 8);    //size{GTP_Touch_Down( id, input_x, input_y, input_w);//数据处理其中 480-input_y 是为了换一下y的方向}}}else if (pre_touch)        //touch_ num=0 且pre_touch!=0{for(i=0;i<pre_touch;i++){GTP_Touch_Up(pre_id[i]);}}pre_touch = touch_num;exit_work_func:{ret = GTP_I2C_Write(client_addr, end_cmd, 3);if (ret < 0){GTP_INFO("I2C write end_cmd error!");}}}/*** @brief   给触屏芯片重新复位* @param 无* @retval 无*/int8_t GTP_Reset_Guitar(void)
{GTP_DEBUG_FUNC();
#if 1I2C_ResetChip();return 0;
#else         //软件复位int8_t ret = -1;int8_t retry = 0;uint8_t reset_command[3]={(uint8_t)GTP_REG_COMMAND>>8,(uint8_t)GTP_REG_COMMAND&0xFF,2};//写入复位命令while(retry++ < 5){ret = GTP_I2C_Write(GTP_ADDRESS, reset_command, 3);if (ret > 0){GTP_INFO("GTP enter sleep!");return ret;}}GTP_ERROR("GTP send sleep cmd failed.");return ret;
#endif}/*** @brief   进入睡眠模式* @param 无* @retval 1为成功,其它为失败*/
//int8_t GTP_Enter_Sleep(void)
//{
//    int8_t ret = -1;
//    int8_t retry = 0;
//    uint8_t reset_comment[3] = {(uint8_t)(GTP_REG_COMMENT >> 8), (uint8_t)GTP_REG_COMMENT&0xFF, 5};//5
//
//    GTP_DEBUG_FUNC();
//
//    while(retry++ < 5)
//    {
//        ret = GTP_I2C_Write(GTP_ADDRESS, reset_comment, 3);
//        if (ret > 0)
//        {
//            GTP_INFO("GTP enter sleep!");
//
//            return ret;
//        }
//
//    }
//    GTP_ERROR("GTP send sleep cmd failed.");
//    return ret;
//}int8_t GTP_Send_Command(uint8_t command)
{int8_t ret = -1;int8_t retry = 0;uint8_t command_buf[3] = {(uint8_t)(GTP_REG_COMMAND >> 8), (uint8_t)GTP_REG_COMMAND&0xFF, GTP_COMMAND_READSTATUS};GTP_DEBUG_FUNC();while(retry++ < 5){ret = GTP_I2C_Write(GTP_ADDRESS, command_buf, 3);if (ret > 0){GTP_INFO("send command success!");return ret;}}GTP_ERROR("send command fail!");return ret;
}/*** @brief   唤醒触摸屏* @param 无* @retval 0为成功,其它为失败*/
int8_t GTP_WakeUp_Sleep(void)
{uint8_t retry = 0;int8_t ret = -1;GTP_DEBUG_FUNC();while(retry++ < 10){ret = GTP_I2C_Test();if (ret > 0){GTP_INFO("GTP wakeup sleep.");return ret;}GTP_Reset_Guitar();}GTP_ERROR("GTP wakeup sleep failed.");return ret;
}static int32_t GTP_Get_Info(void)
{uint8_t opr_buf[10] = {0};int32_t ret = 0;uint16_t abs_x_max = GTP_MAX_WIDTH;uint16_t abs_y_max = GTP_MAX_HEIGHT;uint8_t int_trigger_type = GTP_INT_TRIGGER;opr_buf[0] = (uint8_t)((GTP_REG_CONFIG_DATA+1) >> 8);opr_buf[1] = (uint8_t)((GTP_REG_CONFIG_DATA+1) & 0xFF);ret = GTP_I2C_Read(GTP_ADDRESS, opr_buf, 10);if (ret < 0){return FAIL;}abs_x_max = (opr_buf[3] << 8) + opr_buf[2];abs_y_max = (opr_buf[5] << 8) + opr_buf[4];GTP_DEBUG("RES"); 
//        GTP_DEBUG("opr_buf:");
//        for (int i = 0; i < 10; i++)    {printf(" %d\n", opr_buf[i]);}    GTP_DEBUG_ARRAY(&opr_buf[0],10);opr_buf[0] = (uint8_t)((GTP_REG_CONFIG_DATA+6) >> 8);opr_buf[1] = (uint8_t)((GTP_REG_CONFIG_DATA+6) & 0xFF);ret = GTP_I2C_Read(GTP_ADDRESS, opr_buf, 3);if (ret < 0){return FAIL;}int_trigger_type = opr_buf[7] & 0x03;GTP_INFO("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x",abs_x_max,abs_y_max,int_trigger_type);return SUCCESS;    
}/*******************************************************
Function:Initialize gtp.
Input:ts: goodix private data
Output:Executive outcomes.0: succeed, otherwise: failed
*******************************************************/int32_t GTP_Init_Panel(void)
{int32_t ret = -1;int32_t i = 0;uint16_t check_sum = 0;int32_t retry = 0;const uint8_t* cfg_info;uint8_t cfg_info_len  ;uint8_t* config;uint8_t cfg_num =0 ;        //需要配置的寄存器个数GTP_DEBUG_FUNC();I2C_Touch_Init();ret = GTP_I2C_Test();if (ret < 0){GTP_ERROR("I2C communication ERROR!");return ret;}//获取触摸IC的型号GTP_Read_Version(); #if UPDATE_CONFIGconfig = (uint8_t *)malloc (GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH);if (config == NULL){GTP_ERROR("malloc fail ! ");return -1;}config[0] = GTP_REG_CONFIG_DATA >> 8;config[1] =  GTP_REG_CONFIG_DATA & 0xff;//根据IC的型号指向不同的配置if(touchIC == GT917S){cfg_info =  CTP_CFG_GT917S;//指向寄存器配置cfg_info_len = CFG_GROUP_LEN(CTP_CFG_GT917S) ;//计算配置表的大小}memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH);memcpy(&config[GTP_ADDR_LENGTH], cfg_info, cfg_info_len);cfg_num = cfg_info_len;GTP_DEBUG("cfg_info_len = %d ",cfg_info_len);GTP_DEBUG("cfg_num = %d ",cfg_num);GTP_DEBUG_ARRAY(config,6);/*根据LCD的扫描方向设置分辨率*/config[GTP_ADDR_LENGTH+1] = LCD_PIXEL_WIDTH & 0xFF;config[GTP_ADDR_LENGTH+2] = LCD_PIXEL_WIDTH >> 8;config[GTP_ADDR_LENGTH+3] = LCD_PIXEL_HEIGHT & 0xFF;config[GTP_ADDR_LENGTH+4] = LCD_PIXEL_HEIGHT >> 8;/*根据模式设置X2Y交换*///不交换config[GTP_ADDR_LENGTH+6] &= ~(X2Y_LOC);//交换// config[GTP_ADDR_LENGTH+6] |= (X2Y_LOC);//计算要写入checksum寄存器的值check_sum = 0;/* 计算check sum校验值 */if(touchIC == GT917S) {for (i = GTP_ADDR_LENGTH; i < (cfg_num+GTP_ADDR_LENGTH-3); i += 2) {check_sum += (config[i] << 8) + config[i + 1];}check_sum = 0 - check_sum;GTP_DEBUG("Config checksum: 0x%04X", check_sum);//更新checksumconfig[(cfg_num+GTP_ADDR_LENGTH -3)] = (check_sum >> 8) & 0xFF;config[(cfg_num+GTP_ADDR_LENGTH -2)] = check_sum & 0xFF;config[(cfg_num+GTP_ADDR_LENGTH -1)] = 0x01;}// 写入配置信息for (retry = 0; retry < 5; retry++){ret = GTP_I2C_Write(GTP_ADDRESS, config , cfg_num + GTP_ADDR_LENGTH+2);if (ret > 0){break;}}Delay(0xfffff);                //延迟等待芯片更新#if 1    //读出写入的数据,检查是否正常写入//检验读出的数据与写入的是否相同{uint16_t i;uint8_t buf[300];buf[0] = config[0];buf[1] =config[1];    //寄存器地址GTP_DEBUG_FUNC();ret = GTP_I2C_Read(GTP_ADDRESS, buf, sizeof(buf));GTP_DEBUG("read ");GTP_DEBUG_ARRAY(buf,cfg_num);GTP_DEBUG("write ");GTP_DEBUG_ARRAY(config,cfg_num);//不对比版本号for(i=3;i<cfg_num+GTP_ADDR_LENGTH-3;i++){if(config[i] != buf[i]){GTP_ERROR("Config fail ! i = %d ",i);
//                            free(config);
//                    return -1;}}if(i==cfg_num+GTP_ADDR_LENGTH-3)GTP_DEBUG("Config success ! i = %d ",i);}
#endiffree(config);#endif/* emXGUI示例中不使能中断 */GTP_IRQ_Enable();GTP_Get_Info();return 0;
}/*******************************************************
Function:Read chip version.
Input:client:  i2c deviceversion: buffer to keep ic firmware version
Output:read operation return.2: succeed, otherwise: failed
*******************************************************/
int32_t GTP_Read_Version(void)
{int32_t ret = -1;uint8_t buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff};    //寄存器地址GTP_DEBUG_FUNC();ret = GTP_I2C_Read(GTP_ADDRESS, buf, sizeof(buf));if (ret < 0){GTP_ERROR("GTP read version failed");return ret;}if(buf[4] == '7'){//GT917S芯片GTP_INFO("IC2 Version: %c%c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]);if(buf[2] == '9' && buf[3] == '1' && buf[4] == '7' && buf[5] == 'S'){    touchIC = GT917S; /* 设置当前的液晶屏类型 *///cur_lcd = INCH_5;    }                    }else GTP_INFO("Unknown IC Version: %c%c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]);return ret;
}/*******************************************************
Function:I2c test Function.
Input:client:i2c client.
Output:Executive outcomes.2: succeed, otherwise failed.
*******************************************************/
static int8_t GTP_I2C_Test( void)
{uint8_t test[3] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff};uint8_t retry = 0;int8_t ret = -1;GTP_DEBUG_FUNC();while(retry++ < 5){ret = GTP_I2C_Read(GTP_ADDRESS, test, 3);if (ret > 0){return ret;}GTP_ERROR("GTP i2c test failed time %d.",retry);}return ret;
}//检测到触摸中断时调用,
void GTP_TouchProcess(void)
{GTP_DEBUG_FUNC();Goodix_TS_Work_Func();}#if 0//没有到的测试函数
/*******************************************************
Function:Request gpio(INT & RST) ports.
Input:ts: private data.
Output:Executive outcomes.>= 0: succeed, < 0: failed
*******************************************************/
static int8_t GTP_Request_IO_Port(struct goodix_ts_data *ts)
{
}/*******************************************************
Function:Request interrupt.
Input:ts: private data.
Output:Executive outcomes.0: succeed, -1: failed.
*******************************************************/
static int8_t GTP_Request_IRQ(struct goodix_ts_data *ts)
{
}//输出要初始化的数据及芯片中的真实数据
static void GT91xx_Config_Read_Proc(void)
{char temp_data[GTP_CONFIG_MAX_LENGTH + 2] = {0x80, 0x47};int i;GTP_INFO("==== GT9XX config init value====\n");for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++){printf("reg0x%x = 0x%02X ", i+0x8047, config[i + 2]);if (i % 10 == 9)printf("\n");}GTP_INFO("==== GT9XX config real value====\n");GTP_I2C_Read(GTP_ADDRESS, (uint8_t *)temp_data, GTP_CONFIG_MAX_LENGTH + 2);for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++){printf("reg0x%x = 0x%02X ", i+0x8047,temp_data[i+2]);if (i % 10 == 9)printf("\n");}}//向芯片写入配置数据
static int32_t GT91xx_Config_Write_Proc(void)
{int32_t ret = -1;int32_t i = 0;uint8_t check_sum = 0;int32_t retry = 0;uint8_t cfg_num =0x80FE-0x8047+1 ;        //需要配置的寄存器个数uint8_t cfg_info[] = CTP_CFG_GROUP1;uint8_t cfg_info_len =CFG_GROUP_LEN(cfg_info) ;GTP_INFO("==== GT9XX send config====\n");memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH);memcpy(&config[GTP_ADDR_LENGTH], cfg_info,cfg_info_len);//计算要写入checksum寄存器的值check_sum = 0;for (i = GTP_ADDR_LENGTH; i < cfg_num+GTP_ADDR_LENGTH; i++){check_sum += config[i];}config[ cfg_num+GTP_ADDR_LENGTH] = (~check_sum) + 1;     //checksumconfig[ cfg_num+GTP_ADDR_LENGTH+1] =  1;                         //refresh 配置更新标志//写入配置信息for (retry = 0; retry < 5; retry++){ret = GTP_I2C_Write(GTP_ADDRESS, config , cfg_num + GTP_ADDR_LENGTH+2);if (ret > 0){break;}}return ret;
}#endif/*** @brief  触屏中断服务函数,emXGUI示例中没有使用中断* @param 无* @retval 无*/
void GTP_IRQHandler(void)
{if(EXTI_GetITStatus(GTP_INT_EXTI_LINE) != RESET) //确保是否产生了EXTI Line中断{GTP_TouchProcess();    EXTI_ClearITPendingBit(GTP_INT_EXTI_LINE);     //清除中断标志位}  
}/*** @brief  触屏检测函数,本函数作为emXGUI的定制检测函数,*        参考Goodix_TS_Work_Func修改而来, 只读取单个触摸点坐标* @param x[out] y[out] 读取到的坐标* @retval 坐标有效返回1,否则返回0*/
int    GTP_Execu( int *x,int *y)
{uint8_t  end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0};//2-寄存器地址 1-状态寄存器 8*1-每个触摸点使用8个寄存器 uint8_t  point_data[2 + 1 + 8 * 1 + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF};uint8_t  touch_num = 0;uint8_t  finger = 0;uint8_t client_addr=GTP_ADDRESS;int32_t input_x = 0;int32_t input_y = 0;int32_t ret = -1;GTP_DEBUG_FUNC();ret = GTP_I2C_Read(client_addr, point_data, 12);//10字节寄存器加2字节地址if (ret < 0){GTP_ERROR("I2C transfer error. errno:%d\n ", ret);return 0;}finger = point_data[GTP_ADDR_LENGTH];//状态寄存器数据if (finger == 0x00)        //没有数据,退出{return 0;}if((finger & 0x80) == 0)//判断buffer status位{goto exit_work_func;//坐标未就绪,数据无效}touch_num = finger & 0x0f;//坐标点数if (touch_num > GTP_MAX_TOUCH){goto exit_work_func;//大于最大支持点数,错误退出}    if (touch_num){
//      id = point_data[0] & 0x0F;                                    //track idinput_x  = point_data[3+1] | (point_data[3+2] << 8);    //x坐标input_y  = point_data[3+3] | (point_data[3+4] << 8);    //y坐标
//      input_w  = coor_data[5] | (coor_data[6] << 8);    //sizeif(input_x < GTP_MAX_WIDTH && input_y < GTP_MAX_HEIGHT)  {*x = input_x;*y = 480 - input_y;   // 交换一下y}else{//超出范围,错误退出goto exit_work_func;}}exit_work_func:{//清空标志ret = GTP_I2C_Write(client_addr, end_cmd, 3);if (ret < 0){GTP_INFO("I2C write end_cmd error!");return 0;}}return touch_num;
}
//MODULE_DESCRIPTION("GTP Series Driver");
//MODULE_LICENSE("GPL");

GT9XX.h

/* drivers/input/touchscreen/gt9xx.h* * 2010 - 2013 Goodix Technology.* * This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.* * This program is distributed in the hope that it will be a reference * to you, when you are integrating the GOODiX's CTP IC into your system, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details.* */#ifndef _GOODIX_GTXX_H
#define _GOODIX_GTXX_H#include "stm32f10x.h"#ifndef NULL#define NULL        0
#endif#define LCD_PIXEL_HEIGHT    480
#define LCD_PIXEL_WIDTH     800#define UPDATE_CONFIG    1    // 1 :更新配置    0 :不更新配置/*flags的可取值,注释掉的在本工程没有用到*/
//#define I2C_M_TEN        0x0010    /* 表示这是个10位地址 */
//#define I2C_M_NOSTART        0x4000    /* if I2C_FUNC_PROTOCOL_MANGLING */
//#define I2C_M_REV_DIR_ADDR    0x2000    /* if I2C_FUNC_PROTOCOL_MANGLING */
//#define I2C_M_IGNORE_NAK    0x1000    /* if I2C_FUNC_PROTOCOL_MANGLING */
//#define I2C_M_NO_RD_ACK        0x0800    /* if I2C_FUNC_PROTOCOL_MANGLING */
//#define I2C_M_RECV_LEN        0x0400    /* length will be first received byte *//* 表示读数据 */ 
#define I2C_M_RD        0x0001    /** 存储I2C通讯的信息* @addr:  从设备的I2C设备地址    * @flags: 控制标志* @len:  读写数据的长度* @buf:  存储读写数据的指针**/
struct i2c_msg {uint8_t addr;        /*从设备的I2C设备地址 */uint16_t flags;    /*控制标志*/uint16_t len;        /*读写数据的长度            */uint8_t *buf;        /*存储读写数据的指针    */
};/** * @brief 触摸屏参数*/
typedef struct
{/*根据触摸屏类型配置*/uint16_t max_width;  //触点最大值,高uint16_t max_height;  //触点最大值,宽uint16_t config_reg_addr;      //不同类型的触摸ic配置寄存器地址不同}TOUCH_PARAM_TypeDef;/** * @brief  触摸屏类型*/ 
typedef enum 
{GT917S=0,
}TOUCH_IC;extern TOUCH_IC touchIC;
extern const TOUCH_PARAM_TypeDef touch_param[];// STEP_3(optional): Specify your special config info if needed
#define GTP_MAX_HEIGHT   touch_param[touchIC].max_height
#define GTP_MAX_WIDTH    touch_param[touchIC].max_width
#define GTP_INT_TRIGGER  0
#define GTP_MAX_TOUCH         5//***************************PART3:OTHER define*********************************
#define GTP_DRIVER_VERSION          "V2.2<2014/01/14>"
#define GTP_I2C_NAME                "Goodix-TS"
#define GT91XX_CONFIG_PROC_FILE     "gt9xx_config"
#define GTP_POLL_TIME         10    
#define GTP_ADDR_LENGTH       2
#define GTP_CONFIG_MIN_LENGTH 186
#define GTP_CONFIG_MAX_LENGTH 256
#define FAIL                  0
#define SUCCESS               1
#define SWITCH_OFF            0
#define SWITCH_ON             1//******************** For GT9XXF Start **********************//
#define GTP_REG_BAK_REF                 0x99D0
#define GTP_REG_MAIN_CLK                0x8020
#define GTP_REG_CHIP_TYPE               0x8000
#define GTP_REG_HAVE_KEY                0x804E
#define GTP_REG_MATRIX_DRVNUM           0x8069     
#define GTP_REG_MATRIX_SENNUM           0x806A
#define GTP_REG_COMMAND                0x8040#define GTP_COMMAND_READSTATUS        0
#define GTP_COMMAND_DIFFERENCE        1
#define GTP_COMMAND_SOFTRESET            2
#define GTP_COMMAND_UPDATE                3
#define GTP_COMMAND_CALCULATE        4
#define GTP_COMMAND_TURNOFF            5#define GTP_FL_FW_BURN              0x00
#define GTP_FL_ESD_RECOVERY         0x01
#define GTP_FL_READ_REPAIR          0x02#define GTP_BAK_REF_SEND                0
#define GTP_BAK_REF_STORE               1
#define CFG_LOC_DRVA_NUM                29
#define CFG_LOC_DRVB_NUM                30
#define CFG_LOC_SENS_NUM                31#define GTP_CHK_FW_MAX                  40
#define GTP_CHK_FS_MNT_MAX              300
#define GTP_BAK_REF_PATH                "/data/gtp_ref.bin"
#define GTP_MAIN_CLK_PATH               "/data/gtp_clk.bin"
#define GTP_RQST_CONFIG                 0x01
#define GTP_RQST_BAK_REF                0x02
#define GTP_RQST_RESET                  0x03
#define GTP_RQST_MAIN_CLOCK             0x04
#define GTP_RQST_RESPONDED              0x00
#define GTP_RQST_IDLE                   0xFF//******************** For GT9XXF End **********************//
// Registers define
#define GTP_READ_COOR_ADDR    0x814E
#define GTP_REG_SLEEP         0x8040
#define GTP_REG_SENSOR_ID     0x814A
#define GTP_REG_CONFIG_DATA   touch_param[touchIC].config_reg_addr
#define GTP_REG_VERSION       0x8140#define RESOLUTION_LOC        3
#define TRIGGER_LOC           8
#define X2Y_LOC                        (1<<3)#define CFG_GROUP_LEN(p_cfg_grp)  (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0]))//***************************PART1:ON/OFF define*******************************#define GTP_DEBUG_ON             1
#define GTP_DEBUG_ARRAY_ON    1
#define GTP_DEBUG_FUNC_ON       0
// Log define
#define GTP_INFO(fmt,arg...)           printf("<<-GTP-INFO->> "fmt"\n",##arg)
#define GTP_ERROR(fmt,arg...)          printf("<<-GTP-ERROR->> "fmt"\n",##arg)
#define GTP_DEBUG(fmt,arg...)          do{\if(GTP_DEBUG_ON)\printf("<<-GTP-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);\}while(0)#define GTP_DEBUG_ARRAY(array, num)    do{\int32_t i;\uint8_t* a = array;\if(GTP_DEBUG_ARRAY_ON)\{\printf("<<-GTP-DEBUG-ARRAY->>\n");\for (i = 0; i < (num); i++)\{\printf("%02x   ", (a)[i]);\if ((i + 1 ) %10 == 0)\{\printf("\n");\}\}\printf("\n");\}\}while(0)#define GTP_DEBUG_FUNC()               do{\if(GTP_DEBUG_FUNC_ON)\printf("<<-GTP-FUNC->> Func:%s@Line:%d\n",__func__,__LINE__);\}while(0)#define GTP_SWAP(x, y)                 do{\typeof(x) z = x;\x = y;\y = z;\}while (0)//*****************************End of Part III********************************
int8_t GTP_Reset_Guitar(void);
int32_t GTP_Read_Version(void);
void GTP_IRQ_Disable(void);
void GTP_IRQ_Enable(void);
int32_t GTP_Init_Panel(void);
int8_t GTP_Send_Command(uint8_t command);
int    GTP_Execu( int *x,int *y);                                       #endif /* _GOODIX_GT9XX_H_ */

bsp_i2c_touch.c

/********************************************************************************* @file    bsp_i2c_ee.c* @author  STMicroelectronics* @version V1.0* @date    2015-xx-xx* @brief   电容触摸屏的专用iic驱动******************************************************************************* @attention** 实验平台:野火  STM32 F407 开发板 * 论坛    :http://www.firebbs.cn* 淘宝    :https://fire-stm32.taobao.com********************************************************************************/ #include "bsp_i2c_touch.h"
#include "core_delay.h"   
#include "bsp_usart.h"/* STM32 I2C 快速模式 */
#define I2C_Speed              400000/* 这个地址只要与STM32外挂的I2C器件地址不一样即可 */
#define I2C_OWN_ADDRESS7      0x0A//static void Delay(__IO uint32_t nCount)     //简单的延时函数
//{
//    for(; nCount != 0; nCount--);
//}/*** @brief  使能触摸屏中断* @param  无* @retval 无*/
void I2C_GTP_IRQEnable(void)
{EXTI_InitTypeDef EXTI_InitStructure;  NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;  /*配置 INT 为浮空输入 */   GPIO_InitStructure.GPIO_Pin = GTP_INT_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GTP_INT_GPIO_PORT, &GPIO_InitStructure);  /* 连接 EXTI 中断源 到INT 引脚 */GPIO_EXTILineConfig(GTP_INT_EXTI_PORTSOURCE, GTP_INT_EXTI_PINSOURCE);/* 选择 EXTI 中断源 */EXTI_InitStructure.EXTI_Line = GTP_INT_EXTI_LINE;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);  /* 配置中断优先级 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/*使能中断*/NVIC_InitStructure.NVIC_IRQChannel = GTP_INT_EXTI_IRQ;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}/*** @brief  关闭触摸屏中断* @param  无* @retval 无*/
void I2C_GTP_IRQDisable(void)
{EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;/*配置 INT 为浮空输入 */   GPIO_InitStructure.GPIO_Pin = GTP_INT_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GTP_INT_GPIO_PORT, &GPIO_InitStructure);/* 连接 EXTI 中断源 到INT 引脚 */GPIO_EXTILineConfig(GTP_INT_EXTI_PORTSOURCE, GTP_INT_EXTI_PINSOURCE);/* 选择 EXTI 中断源 */EXTI_InitStructure.EXTI_Line = GTP_INT_EXTI_LINE;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStructure.EXTI_LineCmd = DISABLE;EXTI_Init(&EXTI_InitStructure);/* 配置中断优先级 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 关闭中断 */NVIC_InitStructure.NVIC_IRQChannel = GTP_INT_EXTI_IRQ;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;NVIC_Init(&NVIC_InitStructure);}/*** @brief  触摸屏 I/O配置* @param  无* @retval 无*/
static void I2C_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;  /*使能触摸屏使用的引脚的时钟*/RCC_APB2PeriphClockCmd(GTP_I2C_SCL_GPIO_CLK|GTP_I2C_SDA_GPIO_CLK|GTP_RST_GPIO_CLK|GTP_INT_GPIO_CLK, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);/*配置SCL引脚 */   GPIO_InitStructure.GPIO_Pin = GTP_I2C_SCL_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GTP_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);/*配置SDA引脚 */GPIO_InitStructure.GPIO_Pin = GTP_I2C_SDA_PIN;GPIO_Init(GTP_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);/*配置RST引脚,推挽输出 */   GPIO_InitStructure.GPIO_Pin = GTP_RST_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GTP_RST_GPIO_PORT, &GPIO_InitStructure);/*配置 INT引脚,推挽输出,方便初始化 */   GPIO_InitStructure.GPIO_Pin = GTP_INT_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置为下拉,方便初始化GPIO_Init(GTP_INT_GPIO_PORT, &GPIO_InitStructure);
}/*** @brief  对GT91xx芯片进行复位* @param  无* @retval 无*/
void I2C_ResetChip(void)
{GPIO_InitTypeDef GPIO_InitStructure;/*配置 INT引脚,下拉推挽输出,方便初始化 */   GPIO_InitStructure.GPIO_Pin = GTP_INT_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置为下拉,方便初始化GPIO_Init(GTP_INT_GPIO_PORT, &GPIO_InitStructure);/*初始化GT5688,rst为高电平,int为低电平,则gt5688的设备地址被配置为0xBA*/GPIO_ResetBits (GTP_INT_GPIO_PORT,GTP_INT_GPIO_PIN);/*复位为低电平,为初始化做准备*/GPIO_ResetBits (GTP_RST_GPIO_PORT,GTP_RST_GPIO_PIN);
//      Delay_us(200);
//    Delay(1);Delay_ms(1);/*拉高一段时间,进行初始化*/GPIO_SetBits (GTP_RST_GPIO_PORT,GTP_RST_GPIO_PIN);Delay_ms(55);/*把INT引脚设置为浮空输入模式,以便接收触摸中断信号*/GPIO_InitStructure.GPIO_Pin = GTP_INT_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GTP_INT_GPIO_PORT, &GPIO_InitStructure);
}/*** @brief  I2C 外设(GT5xx)初始化* @param  无* @retval 无*/
void I2C_Touch_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);I2C_GPIO_Config(); I2C_ResetChip();I2C_GTP_IRQDisable();
}
/*
*********************************************************************************************************
*    函 数 名: i2c_Delay
*    功能说明: I2C总线位延迟,最快400KHz
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
static void i2c_Delay(void)
{uint8_t i;/* 下面的时间是通过逻辑分析仪测试得到的。工作条件:CPU主频180MHz ,MDK编译环境,1级优化循环次数为50时,SCL频率 = 333KHz 循环次数为30时,SCL频率 = 533KHz,  循环次数为20时,SCL频率 = 727KHz, */for (i = 0; i < 50; i++);
//  Delay_us(40);
}/*
*********************************************************************************************************
*    函 数 名: i2c_Start
*    功能说明: CPU发起I2C总线启动信号
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_Start(void)
{/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */I2C_SDA_1();I2C_SCL_1();i2c_Delay();I2C_SDA_0();i2c_Delay();I2C_SCL_0();i2c_Delay();
}/*
*********************************************************************************************************
*    函 数 名: i2c_Start
*    功能说明: CPU发起I2C总线停止信号
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_Stop(void)
{/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */I2C_SDA_0();I2C_SCL_1();i2c_Delay();I2C_SDA_1();
}/*
*********************************************************************************************************
*    函 数 名: i2c_SendByte
*    功能说明: CPU向I2C总线设备发送8bit数据
*    形    参:_ucByte : 等待发送的字节
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_SendByte(uint8_t _ucByte)
{uint8_t i;/* 先发送字节的高位bit7 */for (i = 0; i < 8; i++){        if (_ucByte & 0x80){I2C_SDA_1();}else{I2C_SDA_0();}i2c_Delay();I2C_SCL_1();i2c_Delay();    I2C_SCL_0();if (i == 7){I2C_SDA_1(); // 释放总线}_ucByte <<= 1;    /* 左移一个bit */i2c_Delay();}
}/*
*********************************************************************************************************
*    函 数 名: i2c_ReadByte
*    功能说明: CPU从I2C总线设备读取8bit数据
*    形    参:无
*    返 回 值: 读到的数据
*********************************************************************************************************
*/
uint8_t i2c_ReadByte(void)
{uint8_t i;uint8_t value;/* 读到第1个bit为数据的bit7 */value = 0;for (i = 0; i < 8; i++){value <<= 1;I2C_SCL_1();i2c_Delay();if (I2C_SDA_READ()){value++;}I2C_SCL_0();i2c_Delay();}return value;
}/*
*********************************************************************************************************
*    函 数 名: i2c_WaitAck
*    功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
*    形    参:无
*    返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
uint8_t i2c_WaitAck(void)
{uint8_t re;I2C_SDA_1();    /* CPU释放SDA总线 */i2c_Delay();I2C_SCL_1();    /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */i2c_Delay();if (I2C_SDA_READ())    /* CPU读取SDA口线状态 */{re = 1;}else{re = 0;}I2C_SCL_0();i2c_Delay();return re;
}/*
*********************************************************************************************************
*    函 数 名: i2c_Ack
*    功能说明: CPU产生一个ACK信号
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{I2C_SDA_0();    /* CPU驱动SDA = 0 */i2c_Delay();I2C_SCL_1();    /* CPU产生1个时钟 */i2c_Delay();I2C_SCL_0();i2c_Delay();I2C_SDA_1();    /* CPU释放SDA总线 */
}/*
*********************************************************************************************************
*    函 数 名: i2c_NAck
*    功能说明: CPU产生1个NACK信号
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{I2C_SDA_1();    /* CPU驱动SDA = 1 */i2c_Delay();I2C_SCL_1();    /* CPU产生1个时钟 */i2c_Delay();I2C_SCL_0();i2c_Delay();    
}#define I2C_DIR_WR    0        /* 写控制bit */
#define I2C_DIR_RD    1        /* 读控制bit *//*** @brief   使用IIC读取数据* @param   *     @arg ClientAddr:从设备地址*        @arg pBuffer:存放由从机读取的数据的缓冲区指针*        @arg NumByteToRead:读取的数据长度* @retval  无*/
uint32_t I2C_ReadBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint16_t NumByteToRead)
{/* 第1步:发起I2C总线启动信号 */i2c_Start();/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(ClientAddr | I2C_DIR_RD);    /* 此处是读指令 *//* 第3步:等待ACK */if (i2c_WaitAck() != 0){goto cmd_fail;    /* 器件无应答 */}while(NumByteToRead) {*pBuffer = i2c_ReadByte();if(NumByteToRead == 1){i2c_NAck();    /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) *//* 发送I2C总线停止信号 */i2c_Stop();}/* 读指针自增 */pBuffer++; /*计数器自减 */NumByteToRead--;i2c_Ack();    /* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */  }/* 发送I2C总线停止信号 */i2c_Stop();return 0;    /* 执行成功 */cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 *//* 发送I2C总线停止信号 */i2c_Stop();return 1;
}/*** @brief   使用IIC写入数据* @param   *     @arg ClientAddr:从设备地址*        @arg pBuffer:缓冲区指针*     @arg NumByteToWrite:写的字节数* @retval  无*/
uint32_t I2C_WriteBytes(uint8_t ClientAddr,uint8_t* pBuffer,  uint8_t NumByteToWrite)
{uint16_t m;    /* 第0步:发停止信号,启动内部写操作 */i2c_Stop();/* 通过检查器件应答的方式,判断内部写操作是否完成, 一般小于 10ms             CLK频率为200KHz时,查询次数为30次左右*/for (m = 0; m < 1000; m++){                /* 第1步:发起I2C总线启动信号 */i2c_Start();/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(ClientAddr | I2C_DIR_WR);    /* 此处是写指令 *//* 第3步:发送一个时钟,判断器件是否正确应答 */if (i2c_WaitAck() == 0){break;}}if (m  == 1000){goto cmd_fail;    /* EEPROM器件写超时 */}    while(NumByteToWrite--){/* 第4步:开始写入数据 */i2c_SendByte(*pBuffer);//printf(" 0x%x\r\n", *pBuffer);/* 第5步:检查ACK */if (i2c_WaitAck() != 0){goto cmd_fail;    /* 器件无应答 */}pBuffer++;    /* 地址增1 */        }/* 命令执行成功,发送I2C总线停止信号 */i2c_Stop();return 0;cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 *//* 发送I2C总线停止信号 */i2c_Stop();return 1;
}/*********************************************END OF FILE**********************/

bsp_i2c_touch.h

#ifndef __I2C_TOUCH_H
#define    __I2C_TOUCH_H#include "stm32f10x.h"/*设定使用的电容屏IIC设备地址*/
#define GTP_ADDRESS            0xBA#define I2CT_FLAG_TIMEOUT         ((uint32_t)0x1000)
#define I2CT_LONG_TIMEOUT         ((uint32_t)(10 * I2CT_FLAG_TIMEOUT))/*I2C引脚*/
#define GTP_I2C_SCL_PIN                  GPIO_Pin_10                 
#define GTP_I2C_SCL_GPIO_PORT            GPIOF                     
#define GTP_I2C_SCL_GPIO_CLK             RCC_APB2Periph_GPIOF
#define GTP_I2C_SCL_SOURCE               GPIO_PinSource10#define GTP_I2C_SDA_PIN                  GPIO_Pin_6                 
#define GTP_I2C_SDA_GPIO_PORT            GPIOF                    
#define GTP_I2C_SDA_GPIO_CLK             RCC_APB2Periph_GPIOF
#define GTP_I2C_SDA_SOURCE               GPIO_PinSource6/*复位引脚*/
#define GTP_RST_GPIO_PORT                GPIOF
#define GTP_RST_GPIO_CLK                 RCC_APB2Periph_GPIOF
#define GTP_RST_GPIO_PIN                 GPIO_Pin_11
/*中断引脚*/
#define GTP_INT_GPIO_PORT                GPIOF
#define GTP_INT_GPIO_CLK                 RCC_APB2Periph_GPIOF
#define GTP_INT_GPIO_PIN                 GPIO_Pin_9
#define GTP_INT_EXTI_PORTSOURCE          GPIO_PortSourceGPIOF
#define GTP_INT_EXTI_PINSOURCE           GPIO_PinSource9
#define GTP_INT_EXTI_LINE                EXTI_Line9
#define GTP_INT_EXTI_IRQ                 EXTI9_5_IRQn
/*中断服务函数*/
#define GTP_IRQHandler                   EXTI9_5_IRQHandler//软件IIC使用的宏
#define I2C_SCL_1()  GPIO_SetBits(GTP_I2C_SCL_GPIO_PORT, GTP_I2C_SCL_PIN)        /* SCL = 1 */
#define I2C_SCL_0()  GPIO_ResetBits(GTP_I2C_SCL_GPIO_PORT, GTP_I2C_SCL_PIN)        /* SCL = 0 */#define I2C_SDA_1()  GPIO_SetBits(GTP_I2C_SDA_GPIO_PORT, GTP_I2C_SDA_PIN)        /* SDA = 1 */
#define I2C_SDA_0()  GPIO_ResetBits(GTP_I2C_SDA_GPIO_PORT, GTP_I2C_SDA_PIN)        /* SDA = 0 */#define I2C_SDA_READ()  GPIO_ReadInputDataBit(GTP_I2C_SDA_GPIO_PORT, GTP_I2C_SDA_PIN)    /* 读SDA口线状态 *///函数接口
void I2C_Touch_Init(void);
uint32_t I2C_WriteBytes(uint8_t ClientAddr,uint8_t* pBuffer,  uint8_t NumByteToWrite);
uint32_t I2C_ReadBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint16_t NumByteToRead);
void I2C_ResetChip(void);
void I2C_GTP_IRQDisable(void);
void I2C_GTP_IRQEnable(void);#endif /* __I2C_TOUCH_H */

主要部分就这些,实测能用(野火霸道开发板测试)。

测试结果:


http://www.ppmy.cn/news/562698.html

相关文章

你不得不知道的箭头函数和普通函数使用区别!

前言 箭头函数是 ES6 新增的一种函数类型&#xff0c;它采用箭头 > 定义函数&#xff0c;也称为 lambda 函数。箭头函数语法更为简洁&#xff0c;用起来很是方便顺手。 但它存在一些需要注意的问题和局限性。在实际使用时&#xff0c;我们需要根据具体情况来选择合适的函数…

16个小的UI设计规则却能产生巨大的影响

微信搜索 【大迁世界】, 我会第一时间和你分享前端行业趋势&#xff0c;学习途径等等。 本文 GitHub https://github.com/qq449245884/xiaozhi 已收录&#xff0c;有一线大厂面试完整考点、资料以及我的系列文章。 快来免费体验ChatGpt plus版本的&#xff0c;我们出的钱 体验地…

王道操作系统学习笔记(2)——进程管理

前言 本文介绍了操作系统中的进程管理&#xff0c;文章中的内容来自B站王道考研操作系统课程&#xff0c;想要完整学习的可以到B站官方看完整版。 二&#xff1a;进程管理 2.1.1&#xff1a;进程的概念、组成、特征 程序&#xff1a;是静态的&#xff0c;就是存放在磁盘里的…

超全机械设备 机器3dm犀牛资源素材网站整理

想必大家都在为找机械设备 机器3dm犀牛资源而头疼吧&#xff0c;今天小编都为大家整理好咯&#xff0c;上资源的机械设备 机器3dm犀牛资源&#xff0c;大家喜欢的可以先行收藏哈&#xff0c;之后会持续更新哒~ 接下来就给大家介绍一下我珍藏已久的网站&#xff1a;爱给网&…

Skyline 3dm格式l数据困惑

自从Skyline 发布6.5版本以后&#xff0c;推出了新的数据格式3dml&#xff0c;可以通过Pro的Make 3DML 工具&#xff0c;或者单独的CityBuilder工具把一般的模型图层生成3dml图层。 所谓3dml图层实际是把模型打包生成一整块的三角网&#xff0c;生成以后不能编辑。3dml图层的优…

最齐全的鼠标3dm犀牛模型素材,速来收藏

看到大家都在问鼠标3dm犀牛模型素材&#xff0c;既要免费又要质量好&#xff0c;数量还要多&#xff0c;小编好不容易挖到了宝藏素材网站哦&#xff0c;不知道爱给网这个网站大家认识不&#xff0c;资源优质数量庞大&#xff0c;使用体验也很好&#xff0c;要是需要的话&#x…

MicroStrain 3DM-GX3-25 ROS 开发

ROS 版本&#xff1a;18.04 1 从github下载源码 git clone https://github.com/LORD-MicroStrain/microstrain_inertial --recursivegit submodule init && git submodule update --recursive 2 创建ros 环境 mkdir -p/imu/src3 将源码放到你创建的src文件下&#…

3DM:phase wrapping

1.spu-phase unwrap 1.up unwrap(unwrap(wp)’)’&#xff0c;转置两次 2.unwrap()&#xff1a;某人展开起始点为0。&#xff08;展开相位幅度为2Π*周期数&#xff0c;下图为64周期&#xff09; 2.先展开&#xff0c;再相减 3.cfuwp 1.某认展开起始点为图片中心点