2301_78563331 2025-12-10 14:44 采纳率: 89.5%
浏览 5

GT911无法获取状态寄存器的值和坐标寄存器的值

驱动使用GT911,能够正常读取ID的值,触摸屏幕时INT电压也下降了。初始化的时候给GT911配置寄存器写入新的配置参数,读取该寄存器的值也与写入的值相同,但是读取状态寄存器的数据始终为0,直接读取坐标的数据也为0,这是为什么?

#ifndef __GT911_H
#define __GT911_H

#include "stm32f4xx.h" // Device header


#include "MyI2C.h"
#include "Delay.h"
#include "usart1.h"

// GT911 寄存器地址定义

#define GT911_ADDR1_WR                 0xBA        // 0x5D << 1
#define GT911_ADDR1_RD                 0xBB

#define GT911_ADDR2                                         0x28
#define GT911_ADDR2_WR                 0x28        // 0x14 << 1
#define GT911_ADDR2_RD                 0x29       // 0x14 << 1

#define GT911_STATUS_REG            0x814E      //状态寄存器
#define GT911_CONFIG_VERSION        0x8047            //配置寄存器
#define GT911_PRODUCT_ID            0x8140            //坐标寄存器     ID

#define GT911_TOUCH_DATA_START      0x8150            //坐标寄存器1     

#define GT911_CONTROL_REGISTER             0x8040            //控制寄存器

#define GT911_MAX_TOUCH             5

// 触摸点数据结构
typedef struct {
    uint8_t trackId;
    uint16_t x;
    uint16_t y;
    uint8_t size;
    uint8_t flag;
} GT911_TouchPoint;

// 触摸状态结构
typedef struct {
    uint8_t touchNum;
    uint8_t touchStatus;
    GT911_TouchPoint points[GT911_MAX_TOUCH];
} GT911_TouchData;

// 函数声明
uint8_t GT911_Init(uint16_t devAddr);
uint8_t GT911_CheckTouchStatus(void);
uint8_t GT911_ReadTouchData(GT911_TouchData *touchData);
uint8_t GT911_ClearStatus(void);
void GT911_Reset(void);
uint8_t GT911_ReadProductID(uint8_t *productID);

// I2C 读写函数
uint8_t GT911_I2C_Write(uint16_t regAddr, uint8_t *data, uint16_t len);
uint8_t GT911_I2C_Read(uint16_t regAddr, uint8_t *data, uint16_t len);

// 外部变量
extern uint16_t gt911_devAddr;

uint8_t GT911_ReadAndPrintConfig(uint8_t *store_config);
void GT911_Send_Cfg(uint8_t mode);
    

#endif




#include "GT911.h"
#include <string.h>

uint16_t gt911_devAddr = 0;


const uint8_t GT911_CFG_TBL[]=
{ 
        0x5A,0x20,0x03,0xE0,0x01,0x05,0x0C,0x00,0x01,0x08,0x28,0x0F,0x5A,0x46,0x03,0x0F,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87,0x28,0x0A,0x96,0x98,
        0xB2,0x04,0x00,0x00,0x00,0x00,0x02,0x1D,0x19,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x78,0xA0,0x94,0xD5,0x02,0x08,0x00,0x00,0x04,0x93,0x7B,0x00,0x8D,
        0x82,0x00,0x87,0x8A,0x00,0x82,0x92,0x00,0x7D,0x9B,0x00,0x7D,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x14,0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0xFF,0xFF,0xFF,0xFF,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0x24,
        0x22,0x21,0x20,0x1F,0x1E,0x1D,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0xFF,0xFF,0xFF,
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};  




/**
  * @brief  I2C写数据
  */
uint8_t GT911_I2C_Write(uint16_t regAddr, uint8_t *data, uint16_t len)
{
    uint16_t i;
    
    MyI2C_Start();
    
    // 发送设备地址 + 写标志
    MyI2C_SendByte(0x28);
    if(MyI2C_ReceiveAck())
    {
        MyI2C_Stop();
        return 1;
    }
    
    // 发送寄存器地址高字节
    MyI2C_SendByte((regAddr >> 8) & 0xFF);
    if(MyI2C_ReceiveAck())
    {
        MyI2C_Stop();
        return 2;
    }
    
    // 发送寄存器地址低字节
    MyI2C_SendByte(regAddr & 0xFF);
    if(MyI2C_ReceiveAck())
    {
        MyI2C_Stop();
        return 3;
    }
    
    // 发送数据
    for(i = 0; i < len; i++)
    {
        MyI2C_SendByte(data[i]);
        if(MyI2C_ReceiveAck())
        {
            MyI2C_Stop();
            return 4;
        }
    }
    
    MyI2C_Stop();
    return 0;
}

/**
  * @brief  I2C读数据
  */
uint8_t GT911_I2C_Read(uint16_t regAddr, uint8_t *data, uint16_t len)
{
    uint16_t i;
    
    MyI2C_Start();
    
    // 发送设备地址 + 写标志
    MyI2C_SendByte(0x28);
    if(MyI2C_ReceiveAck())
    {
        MyI2C_Stop();
        return 1;
    }
        
    
    // 发送寄存器地址高字节
    MyI2C_SendByte((regAddr >> 8)& 0xFF);
    if(MyI2C_ReceiveAck())
    {
        MyI2C_Stop();
        return 2;
    }
    
    // 发送寄存器地址低字节
    MyI2C_SendByte(regAddr & 0xFF);
    if(MyI2C_ReceiveAck())
    {
        MyI2C_Stop();
        return 3;
    }
    
    // 重新发送起始条件
    MyI2C_Start();
    
    // 发送设备地址 + 读标志
    MyI2C_SendByte(0x29);
    if(MyI2C_ReceiveAck())
    {
        MyI2C_Stop();
        return 4;
    }
    
    // 读取数据
    for(i = 0; i < len; i++)
    {
        if(i == len - 1)
        {
            data[i] = MyI2C_ReceiveByte();
            MyI2C_SendAck(1); // 最后一个字节发送NACK
        }
        else
        {
            data[i] = MyI2C_ReceiveByte();
            MyI2C_SendAck(0); // 发送ACK
        }
    }
    
    MyI2C_Stop();
    return 0;
}

/**
  * @brief  初始化GT911
  */
 uint8_t GT911_Init(uint16_t devAddr)
{
    
    uint8_t temp[2] = {0};
        uint8_t productID[4] = {0};
    uint8_t ret = 0;
    
    gt911_devAddr = devAddr;
        

    
    // 初始化I2C(包含GPIO初始化)
    MyI2C_Init();
        
        A:
    // 执行复位序列
////        //0xBA
//    GPIO_ResetBits(GT911_RST_PORT, GT911_RST_PIN);
//    GPIO_ResetBits(GT911_INT_PORT, GT911_INT_PIN);
//        Delay_ms(10);  // 10ms
//        GPIO_SetBits(GT911_RST_PORT, GT911_RST_PIN);
    
////        //0x28 八位写地址
        GPIO_ResetBits(GT911_RST_PORT, GT911_RST_PIN);  // 拉低RST
    GPIO_ResetBits(GT911_INT_PORT, GT911_INT_PIN);  // INT保持低
    Delay_ms(10);                                    // 保持10ms
    GPIO_SetBits(GT911_RST_PORT, GT911_RST_PIN);    // 释放RST
    Delay_ms(10);                                     // 等待芯片稳定

    
    // 重新配置INT为浮空输入
    GPIO_InitTypeDef GPIO_InitStructure;
        //GPIO_InitStructure.GPIO_OType = GPIO_OTYPE_PP;
    GPIO_InitStructure.GPIO_Pin = GT911_INT_PIN;
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_OType    =    GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd    =GPIO_PuPd_NOPULL;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GT911_INT_PORT, &GPIO_InitStructure);
    
    Delay_ms(100); // 等待芯片完全初始化
    
    ret = GT911_I2C_Read(0x8140, productID, 4);
        if(ret != 0)
        {    
            printf(" id read error   ");
                printf("ret = %d\r\n",ret);
            Delay_ms(500);
            goto A;
        }
    

        printf("productID = %d %d %d %d \r\n",productID[0],productID[1],productID[2],productID[3]);
        //printf("productID = %s \r\n",productID);
        if(strcmp((char*)productID,"911")==0)//ID==9147
        {
                temp[0]=0X02;            
                GT911_I2C_Write(GT911_CONTROL_REGISTER,temp,1);//软复位GT911
                GT911_I2C_Read(GT911_STATUS_REG,temp,1);//读取GT_CFGS_REG寄存器
                //printf("Default Ver:%x\r\n",temp[0]);
//                if(temp[0]!=0x60)
//                {
                    GT911_Send_Cfg(1);
//                }
                Delay_ms(10);
                temp[0]=0X00;     
                GT911_I2C_Write(GT911_CONTROL_REGISTER,temp,1);//结束复位   
        
        }
        
        
        
        
        
    return 0;
}

/**
  * @brief  检查触摸状态(轮询状态寄存器最高位)
  */
uint8_t GT911_CheckTouchStatus(void)
{
    uint8_t status = 0;
    uint8_t ret = 0;
    
    ret = GT911_I2C_Read(GT911_STATUS_REG, &status, 1);
    if(ret != 0)
    {
        return ret; // 通信错误
    }
    
    // 检查最高位(bit7)是否为1,表示有触摸数据
    if(status & 0x80)
    {
        return status; // 有触摸
    }
    
    return 0; // 无触摸
}



/**
  * @brief  读取触摸数据(修正坐标解析)
  * @param  touchData: 存储触摸数据的结构体指针
  * @retval 0-成功, 1-通信错误, 2-无触摸数据, 3-参数错误
  */
uint8_t GT911_ReadTouchData(GT911_TouchData *touchData)
{
    uint8_t buf[40] = {0};    // 足够存放5个触摸点(5*8=40字节)
    uint8_t status = 0;
    uint8_t ret = 0;
    uint8_t i;
    
    if(touchData == NULL) {
        return 3; // 参数错误
    }
    
    memset(touchData, 0, sizeof(GT911_TouchData));
    
    // 1. 读取状态寄存器(0x814E)
    ret = GT911_I2C_Read(GT911_STATUS_REG, &status, 1);
    if(ret != 0) {
        printf("读取状态寄存器失败,错误码: %d\r\n", ret);
        return 1; // 通信错误
    }
    
    // 调试信息:打印原始状态字节
    //printf("[DEBUG] 状态寄存器原始值: 0x%02X\r\n", status);
    
    // 2. 检查最高位(bit7)是否为1,表示有新的触摸数据
    if((status & 0x80) == 0) {
        // 注意:无触摸时返回2,这是正常情况,不是错误
        return 2; // 无新触摸数据
    }
    
    // 3. 获取触摸点数量(低4位,最多5点)
    touchData->touchNum = status & 0x0F;
    if(touchData->touchNum > GT911_MAX_TOUCH) {
        printf("警告:报告的触摸点数(%d)超过最大值,已截断\r\n", touchData->touchNum);
        touchData->touchNum = GT911_MAX_TOUCH;
    }
    
    printf("检测到触摸点数: %d\r\n", touchData->touchNum);
    
    // 4. 如果有点,则读取触摸点数据(每个点8字节)
    if(touchData->touchNum > 0) {
        // 计算需要读取的字节数
        uint8_t bytesToRead = touchData->touchNum * 8;
        
        // 从0x8150开始读取触摸数据
        ret = GT911_I2C_Read(GT911_TOUCH_DATA_START, buf, bytesToRead);
        if(ret != 0) {
            printf("读取触摸数据失败,错误码: %d\r\n", ret);
            return 1; // 通信错误
        }
        
        // 5. 解析每个触摸点数据(关键修正部分)
        for(i = 0; i < touchData->touchNum; i++) {
            uint8_t *p = &buf[i * 8]; // 每个点8字节
            
            // 解析触摸点数据(根据GT911数据手册)
            touchData->points[i].trackId = p[7] & 0x0F;      // 跟踪ID(低4位)
            touchData->points[i].x = ((uint16_t)(p[1] & 0x0F) << 8) | p[0]; // X坐标
            touchData->points[i].y = ((uint16_t)(p[3] & 0x0F) << 8) | p[2]; // Y坐标
            touchData->points[i].size = p[4];                // 触摸面积
            touchData->points[i].flag = 1;                   // 标记有效
            
            // 调试输出
            printf("点%d: ID=%d, X=%d, Y=%d, 面积=%d\r\n", 
                   i, 
                   touchData->points[i].trackId,
                   touchData->points[i].x,
                   touchData->points[i].y,
                   touchData->points[i].size);
        }
    }
    
    // 6. 读取完成后,必须清除状态寄存器(写入0x00)
    GT911_ClearStatus();
    
    return 0; // 成功
}

/**
  * @brief  清除状态寄存器(必须每次读取触摸数据后调用)
  * @retval 0-成功, 非0-失败
  */
uint8_t GT911_ClearStatus(void)
{
    uint8_t clear_data = 0x00;
    uint8_t ret = GT911_I2C_Write(GT911_STATUS_REG, &clear_data, 1);
    
    if(ret != 0) {
        printf("清除状态寄存器失败,错误码: %d\r\n", ret);
    } else {
         printf("状态寄存器已清除\r\n");
                printf("\r\n");
                    printf("\r\n");
    }
    
    return ret;
}

/**
  * @brief  硬件复位
  */
void GT911_Reset(void)
{
    GPIO_ResetBits(GT911_RST_PORT, GT911_RST_PIN);
    MyI2C_Delay(10000); // 10ms
    GPIO_SetBits(GT911_RST_PORT, GT911_RST_PIN);
    MyI2C_Delay(100000); // 100ms
}

/**
  * @brief  读取并打印GT911配置寄存器组 (0x8047 ~ 0x8100)
  * @param  store_config: (可选)用于存储读取到的186字节配置的缓冲区。
  *                     如果为NULL,则只打印不存储。
  * @retval 0-成功, 非0-失败 (I2C读取错误码)
  */
uint8_t GT911_ReadAndPrintConfig(uint8_t *store_config)
{
    uint8_t config_buf[186] = {0}; // 0x8100 - 0x8047 + 1 = 186 字节
    uint8_t ret = 0;
    uint16_t i, j;
    
    printf("\r\n========== GT911 配置寄存器组 (0x8047~0x8100) ==========\r\n");
    
    // 1. 读取全部186字节配置
    ret = GT911_I2C_Read(0x8047, config_buf, sizeof(config_buf));
    if(ret != 0) {
        printf("[错误] 读取配置寄存器失败,错误码: %d\r\n", ret);
        return ret;
    }
    
    // 2. 打印关键配置信息(头部)
    printf("配置版本: %d.%d.%d.%d\r\n", 
           config_buf[0], config_buf[1], config_buf[2], config_buf[3]);
    printf("X分辨率: %d\r\n", (config_buf[0x4A] << 8) | config_buf[0x49]);
    printf("Y分辨率: %d\r\n", (config_buf[0x4C] << 8) | config_buf[0x4B]);
    printf("触摸点数: %d\r\n", config_buf[0x4D]);
    
    // 3. 计算并验证校验和
    // GT911配置的校验和通常是前184字节的和,存储在第185(0x80FF)、186(0x8100)字节
    uint16_t calc_checksum = 0;
    for(i = 0; i < 184; i++) {
        calc_checksum += config_buf[i];
    }
    uint16_t stored_checksum = (config_buf[184] << 8) | config_buf[185];
    
    printf("存储的校验和: 0x%04X\r\n", stored_checksum);
    printf("计算的校验和: 0x%04X\r\n", calc_checksum);
    if(calc_checksum == stored_checksum) {
        printf("校验和: ? 正确\r\n");
    } else {
        printf("校验和: ? 错误 (配置可能已损坏)\r\n");
    }
    
    // 4. 以十六进制格式打印全部配置数据(每行16字节)
    printf("\r\n--- 完整配置数据 (HEX) ---\r\n");
    for(i = 0; i < sizeof(config_buf); i += 16) {
        printf("0x%04X: ", 0x8047 + i); // 打印当前行起始地址
        
        // 打印16个字节的HEX值
        for(j = 0; j < 16; j++) {
            if(i + j < sizeof(config_buf)) {
                printf("%02X ", config_buf[i + j]);
            } else {
                printf("   "); // 对齐最后一行
            }
        }
        
        printf("  "); // 分隔符
        
        // 打印ASCII字符(可打印字符)
        for(j = 0; j < 16 && i + j < sizeof(config_buf); j++) {
            uint8_t c = config_buf[i + j];
            if(c >= 32 && c <= 126) { // 可打印字符范围
                printf("%c", c);
            } else {
                printf(".");
            }
        }
        printf("\r\n");
    }
    printf("============================================================\r\n\r\n");
    
    // 5. 如果调用者提供了存储缓冲区,则将数据拷贝过去
    if(store_config != NULL) {
        memcpy(store_config, config_buf, sizeof(config_buf));
    }
    
    return 0;
}

/*
* 函数名称: GT911_Send_Cfg
* 功能描述: 更新GT911配置参数
* 传入参数: mode:0,参数不保存到flash
*                1:参数保存到flash
*   返回值: 0,成功;1,失败.
*/
void GT911_Send_Cfg(uint8_t mode)
{
    uint8_t buf[2];
    uint8_t i=0;
    buf[0]=0;
    buf[1]=mode;    //是否写入到GT911 FLASH?  即是否掉电保存
    for(i=0;i<sizeof(GT911_CFG_TBL);i++)buf[0]+=GT911_CFG_TBL[i];//计算校验和
    buf[0]=(~buf[0])+1;
    GT911_I2C_Write(GT911_CONFIG_VERSION,(uint8_t*)GT911_CFG_TBL,sizeof(GT911_CFG_TBL));//发送寄存器配置
    GT911_I2C_Write(0x80FF,buf,2);//写入校验和,和配置更新标记  0x80FF校验和寄存器
    
} 




  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2025-12-10 15:14
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你提到的问题是:GT911 无法获取状态寄存器的值和坐标寄存器的值,驱动能正常读取 ID 的值,触摸屏幕时 INT 电压也下降了。初始化时配置寄存器写入新参数后读取值与写入相同,但读取状态寄存器和坐标寄存器始终为 0。


    问题分析

    从你的描述来看,GT911 能够完成以下操作:

    • 正常读取 Product ID(说明 I2C 通信正常);
    • 触摸时 INT 引脚电压下降(说明触摸事件被检测到);
    • 写入配置寄存器后,读取值与写入值一致(说明配置寄存器通信正常)。

    但是读取 状态寄存器坐标寄存器 始终为 0,这可能意味着以下几个原因:


    🔍 可能的原因

    1. I2C 地址错误

    你使用的 I2C 地址是否正确?
    GT911 的 I2C 地址是 0x14,因此写地址应为 0x28(0x14 << 1),读地址为 0x29(0x14 << 1 | 1)。
    你在代码中使用的是:

    #define GT911_ADDR1_WR                 0xBA        // 0x5D << 1
    

    这是错误的,GT911 的地址应该是 0x14,所以正确的写地址应为 0x28,读地址为 0x29

    重点:I2C 地址错误会导致读写寄存器失败!


    2. 未正确使能中断或唤醒设备

    GT911 在默认情况下可能处于 低功耗模式,需要通过写控制寄存器来 唤醒设备使能中断

    你是否有在初始化时设置控制寄存器?

    例如:

    uint8_t controlReg = 0x00;
    GT911_I2C_Write(GT911_CONTROL_REGISTER, &controlReg, 1);
    

    如果未设置该寄存器,设备可能不会进入正常工作模式,导致无法读取状态和坐标数据。


    3. 未正确读取多字节寄存器

    状态寄存器和坐标寄存器是 多字节寄存器,需要读取多个字节。
    例如:

    • 状态寄存器是 1 字节(0x814E);
    • 坐标寄存器是 6 字节(每个点占 6 字节,最多 5 个点)。

    如果你只读取了一个字节,或者没有正确处理多字节读取,也会导致结果为 0。


    4. 未等待中断触发后再读取数据

    GT911 是一个异步设备,需要在 INT 引脚触发中断 后才能读取触摸数据。
    如果你在未触发中断前就尝试读取数据,会得到 0。


    解决方案

    第一步:修正 I2C 地址定义

    修改头文件中的 I2C 地址定义:

    // GT911 寄存器地址定义
    
    #define GT911_ADDR_WR     0x28      // 0x14 << 1
    #define GT911_ADDR_RD     0x29      // 0x14 << 1 | 1
    
    #define GT911_STATUS_REG       0x814E   // 状态寄存器
    #define GT911_TOUCH_DATA_START 0x8150   // 坐标寄存器起始地址
    

    第二步:初始化时设置控制寄存器

    GT911_Init() 中添加控制寄存器初始化代码:

    uint8_t GT911_Init(uint16_t devAddr)
    {
        // 设置控制寄存器,使能中断等
        uint8_t controlReg = 0x00; // 根据文档设置
        GT911_I2C_Write(GT911_CONTROL_REGISTER, &controlReg, 1);
    
        // 其他初始化代码...
    }
    

    第三步:确保读取多字节寄存器

    修改读取函数,确保读取完整的数据:

    读取状态寄存器:

    uint8_t GT911_ReadStatus(uint8_t *status)
    {
        return GT911_I2C_Read(GT911_STATUS_REG, status, 1);
    }
    

    读取坐标寄存器(最多 5 个点):

    uint8_t GT911_ReadTouchData(GT911_TouchData *touchData)
    {
        uint8_t data[5 * 6]; // 每个点 6 字节,最多 5 个点
        uint8_t result = GT911_I2C_Read(GT911_TOUCH_DATA_START, data, sizeof(data));
    
        if (result != 0) {
            return result;
        }
    
        touchData->touchNum = data[0]; // 第一个字节是触摸点数量
        for (int i = 0; i < touchData->touchNum; i++) {
            int offset = i * 6 + 1;
            touchData->points[i].trackId = data[offset];
            touchData->points[i].x = (data[offset + 1] << 8) | data[offset + 2];
            touchData->points[i].y = (data[offset + 3] << 8) | data[offset + 4];
            touchData->points[i].size = data[offset + 5];
            touchData->points[i].flag = data[offset + 6];
        }
    
        return 0;
    }
    

    第四步:确保在 INT 中断后读取数据

    你需要在 INT 引脚触发中断 后再调用读取函数。
    你可以使用外部中断或者轮询方式检测 INT 是否为低电平。

    示例(轮询方式):

    void CheckTouch()
    {
        if (INT_PIN == 0) { // INT 为低电平,表示有触摸
            GT911_TouchData touchData;
            if (GT911_ReadTouchData(&touchData) == 0) {
                // 处理触摸数据
            }
        }
    }
    

    总结:关键点如下

    | 问题 | 解决方案 | |------|----------| | I2C 地址错误 | 修改为 0x28(写)和 0x29(读) | | 控制寄存器未设置 | 初始化时写入控制寄存器 | | 未读取多字节寄存器 | 使用 GT911_I2C_Read 读取完整数据 | | 未等待中断触发 | 在 INT 为低电平时读取数据 |


    修改后的代码示例(部分)

    修改 I2C 地址定义(头文件)

    #define GT911_ADDR_WR     0x28
    #define GT911_ADDR_RD     0x29
    
    #define GT911_STATUS_REG       0x814E
    #define GT911_TOUCH_DATA_START 0x8150
    

    初始化控制寄存器(初始化函数)

    uint8_t GT911_Init(uint16_t devAddr)
    {
        // 设置控制寄存器
        uint8_t controlReg = 0x00;
        GT911_I2C_Write(GT911_CONTROL_REGISTER, &controlReg, 1);
    
        // ...其他初始化代码
    }
    

    读取触摸数据函数(改进版)

    uint8_t GT911_ReadTouchData(GT911_TouchData *touchData)
    {
        uint8_t data[5 * 6]; // 每个点 6 字节,最多 5 个点
        uint8_t result = GT911_I2C_Read(GT911_TOUCH_DATA_START, data, sizeof(data));
    
        if (result != 0) {
            return result;
        }
    
        touchData->touchNum = data[0]; // 第一个字节是触摸点数量
        for (int i = 0; i < touchData->touchNum; i++) {
            int offset = i * 6 + 1;
            touchData->points[i].trackId = data[offset];
            touchData->points[i].x = (data[offset + 1] << 8) | data[offset + 2];
            touchData->points[i].y = (data[offset + 3] << 8) | data[offset + 4];
            touchData->points[i].size = data[offset + 5];
            touchData->points[i].flag = data[offset + 6];
        }
    
        return 0;
    }
    

    最后建议

    • 如果仍然无法读取数据,建议使用 I2C 调试工具(如逻辑分析仪或 I2C 检测器)查看实际 I2C 通信是否正常。
    • 参考 GT911 数据手册 中关于寄存器的详细说明。

    如有更多细节(如硬件连接、调试日志等),可以继续提供,我会进一步帮你定位问题。

    评论

报告相同问题?

问题事件

  • 创建了问题 12月10日