跳到正文
Display Engineer
排障

GT911 触摸无响应?I2C 地址、复位时序、配置与坐标问题排查

针对无法被检测到、无触摸报点或坐标错误的 GT911 电容触摸控制器,提供一份逐步排查清单:供电与 I2C 扫描、INT/RST 地址选择时序、0x814E 状态寄存器、中断边沿,以及针对 Linux、ESP-IDF 和 ESPHome 的分辨率与坐标轴修正方法。

DEDisplay Engineer Applications Team · 显示应用工程师更新于 2026年10月19日

从这里开始:对照故障现象

故障现象

最可能的原因

转到

I2C 扫描在 0x5D 和 0x14 上均无响应

控制器未供电、缺少上拉电阻,或芯片被保持在复位状态

第 1 步

驱动期望 0x5D 却在 0x14 上发现设备(或相反),或地址在多次启动之间发生变化

复位期间 INT 引脚的电平

第 2 步

设备已被检测到,产品 ID 读取正确,但没有触摸报点

状态寄存器未清除、中断边沿配置错误,或 INT 未接线

第 3 步

有触摸报点,但位置错误、镜像或旋转

GT911 配置中的分辨率与面板不匹配,或需要交换坐标轴

第 4 步

打算写入新的配置块

请先阅读本节

第 5 步

按顺序逐步排查。下文的寄存器地址和时序来自 Linux goodix 驱动、Espressif 的 esp_lcd_touch_gt911 组件以及 ESPHome 文档;链接见“参考资料”部分。

1. 确认 GT911 已供电且在 I2C 上应答

供电与上拉电阻

Linux 设备树绑定中为 Goodix 控制器定义了两个电源:AVDD28(模拟电源)和 VDDIO(逻辑 I/O 电源)。在模组或 FPC 上,两者通常都由主机连接器供电,因此应先在连接器处测量电压,再怀疑固件问题。SDA 和 SCL 还需要在总线上某处接上拉电阻;许多显示模组并不自带。

扫描总线

运行 I2C 扫描程序或 i2cdetect。GT911 会在以下两个 7 位地址之一上应答:

7 位地址

8 位写/读字节(部分数据手册如此标注)

0x5D

0xBA / 0xBB

0x14

0x28 / 0x29

8 位地址对来自 Linux 驱动复位代码中的一条注释。如果供应商资料写的是“地址 0xBA”,它与 7 位 0x5D 是同一个设备;在 Arduino、ESP-IDF 和 Linux 中请填写 0x5D。

读取产品 ID

GT911 的寄存器地址为 16 位。Linux 驱动从 0x8140 读取 6 个字节:前 4 个字节是以 ASCII 文本表示的产品 ID,后 2 个字节是固件版本(小端序)。GT911 报告的字符串为 911。如果读到了 911,说明总线、供电和地址都没有问题,问题在排查清单的更后面。

如果两个地址上都无应答,请检查复位线是否被拉低。在许多模组上,RST 是 GT911 的输入引脚,必须由主机驱动为高电平(或在板上加上拉)后控制器才会运行。

2. 正确执行复位与地址选择时序

GT911 在复位释放的瞬间根据 INT 引脚的电平选择其 I2C 地址。用 Linux 绑定的原话说,INT 线“在复位释放时被器件采样,用于选择 I2C 客户端地址”。

RST 变高时 INT 的电平

I2C 地址

低电平

0x5D

高电平

0x14

Linux 驱动所使用的初始化时序

  1. 将 RST 拉低并等待 10 ms 以上(该驱动等待 20 ms)。
  2. 将 INT 拉到所选地址对应的电平:0x14 为高电平,0x5D 为低电平。
  3. 等待 100 µs 以上。
  4. 将 RST 拉高并等待 5 ms 以上(该驱动等待 6–10 ms)。
  5. 将 INT 拉低保持 50 ms,然后将 INT 切换为输入。

如果在第 4 步期间 INT 处于浮空状态,地址可能在上电之间有所不同。这正是经典的“烧录后正常,冷启动后失效”问题的来源。

ESP-IDF:esp_lcd_touch_gt911

Espressif 的组件将 ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS 定义为 0x5D,将 ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUP 定义为 0x14。只有同时满足以下三个条件时,它才会执行地址选择时序:

  • rst_gpio_num 是有效的 GPIO(不是 GPIO_NUM_NC),
  • int_gpio_num 是有效的 GPIO,
  • driver_data 指向一个 esp_lcd_touch_io_gt911_config_t,其 dev_addr 为所需地址。

否则它会打印 I2C address initialization procedure skipped - using default GT9xx setup 并执行普通复位。这种情况下,地址取决于板子的接线,你传入的 I2C panel-IO 地址必须与扫描结果一致。该组件在 ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG() 中默认的 I2C 时钟为 100 kHz。

主机无法控制 INT 的板卡

如果 INT 未连接到主机,主机就无法选择地址,因此应扫描两个地址并使用有应答的那个。例如在 Sunton ESP32-8048S043C 上,GT911 的中断默认未连接到任何 GPIO(参见我们的板卡页面)。ESPHome 的 GT911 页面指出:当 INT 经过 IO 扩展器时,该引脚在启动时仍用于设定地址,但触摸改为轮询方式而非中断驱动。

3. 能检测到设备,但没有触摸事件

读取并清除状态寄存器

触摸数据从 0x814E 开始。第一个字节是状态字节:

  • Bit 7(0x80):缓冲区就绪。只有该位被置位时,新数据才有效。
  • Bit 0–3:触摸点数量。Linux 驱动会拒绝超过所配置上限的数量。
  • Bit 4:有按键(button)被按下。

每个触摸点占 8 字节:一个 track ID,随后是小端 16 位的 X、Y 和 size。

读取后,Linux 驱动和 esp_lcd_touch_gt911 都会向 0x814E 写入 0。如果自行编写驱动,也应这样做;漏掉该写入是手写驱动只能收到第一次触摸的常见原因。

匹配中断边沿

触发类型存放在 GT911 自身的配置中:0x804D 处配置字节的 bit 0–1(相对配置起始地址 0x8047 的偏移 6)。Linux 驱动按如下方式映射:

数值

中断类型

0

上升沿

1

下降沿

2

低电平

3

高电平

GPIO 中断设置需要与之匹配。在 esp_lcd_touch_gt911 中,levels.interrupt = 1 表示上升沿中断,0 表示下降沿。

没有 INT 线?轮询

对 HMI 应用来说,轮询完全够用。未设置 interrupt_pin 时,ESPHome 默认每 50 ms 轮询一次(update_interval)。Linux 驱动在使用中断时,最多会等待 20 ms 的就绪位,超时则放弃该帧。

4. 触点位置不对

检查 GT911 中保存的分辨率

GT911 上报的坐标是其配置中写入的分辨率,而不是你显示屏的分辨率。根据 Linux 驱动,X 最大值是 0x8048 处的小端 16 位值,Y 最大值在 0x804A。读出这两个值。如果控制器配置为 1024×600 而你的面板是 800×480,触点会落在手指的右下方,且远离手指的边缘区域会超出屏幕。解决办法是做缩放(或把驱动的限值设置为控制器的值)。

各软件栈的限值来源:

软件栈

分辨率来源

交换与镜像

Linux goodix

从 GT911 配置中读取;配置中没有时回退为 4095 × 4095

设备树属性 touchscreen-swapped-x-y、touchscreen-inverted-x、touchscreen-inverted-y、touchscreen-size-x/y

ESP-IDF esp_lcd_touch_gt911

esp_lcd_touch_config_t 中你设置的 x_max / y_max(驱动不会读取芯片的分辨率)

flags.swap_xy、flags.mirror_x、flags.mirror_y

ESPHome gt911

触摸屏 calibration(x_min、x_max、y_min、y_max)

transform: swap_xy / mirror_x / mirror_y

从原始值开始校准

ESPHome 的触摸屏页面建议在 on_touch lambda 中记录 touch.x_raw 和 touch.y_raw,多次触碰屏幕边缘像素处的四个角,然后把原始值的最小值和最大值填入校准参数。同样的方法适用于任何平台:打印原始 X 和 Y,触碰四个角,再把量程映射到屏幕上。

按以下顺序修正方向:先把 X 和 Y 调到正确的轴上(swap_xy),再翻转方向反了的轴(mirror_x / mirror_y)。显示屏的逻辑 (0, 0) 必须位于左上角。

5. 重写 GT911 配置:最后手段

配置块从 0x8047 开始。对 GT911,Linux 驱动将其视为 186 字节:

  • 字节 0(0x8047):配置版本。
  • 字节 1–4:X 和 Y 分辨率(见第 4 步)。
  • 字节 5(0x804C):最大触点数,低 4 位。
  • 字节 6(0x804D):中断触发类型,低 2 位。
  • 字节 184(0x80FF):校验和,即字节 0–183 之和的 8 位二进制补码。
  • 字节 185(0x8100):config_fresh,必须为 1。

Linux 驱动本身只有在同时拥有 INT 和 RST GPIO 并找到固件文件(默认文件名 goodix_911_cfg.bin,或 goodix,config-name 属性指定的名称)时才会写入配置。没有该文件时,它使用芯片中已存储的配置。

在写入任何内容之前,先读出全部 186 字节并保存。能在软件层面解决的分辨率和方向问题,尽量在软件中解决。为其他触摸面板制作的配置块可能导致你的面板触摸失效,所以如果确实需要修改,请向面板供应商索取配置文件。

如何选择电容触摸模块

如果你要为新设计选购 CTP 显示屏,下单样品前请向供应商确认三件事:采用的触摸控制器型号、出厂默认的 I2C 地址,以及 INT 和 RST 是否引出到连接器。把你的尺寸、接口和主控处理器通过 Ask an Engineer 发给我们,我们会连同这三项答案一起推荐合适的模块。

常见问题

GT911 的 I2C 地址是多少?

0x5D 或 0x14(7 位地址)。控制器在复位释放时采样 INT 引脚电平:INT 为低电平选择 0x5D,INT 为高电平选择 0x14。有些数据手册列出 0xBA/0xBB 或 0x28/0x29,那是同一地址的 8 位写/读字节形式。

为什么我的 GT911 重启后地址会变?

复位释放时 INT 引脚悬空或被其他器件驱动,导致控制器每次采样到不同的电平。在释放 RST 之前将 INT 拉低(对应 0x5D)或拉高(对应 0x14),等待 5 ms 以上,将 INT 保持低电平 50 ms,然后将其设为输入。如果主机无法控制 INT,则同时扫描两个地址。

为什么 GT911 只响应一次触摸?

读取 0x814E 处的触摸数据后,向 0x814E 写入 0。Linux 的 goodix 驱动和乐鑫的 esp_lcd_touch_gt911 都会在每次读取后执行此操作;跳过这一步的驱动通常会再也检测不到新的触摸。

为什么 GT911 的触摸坐标被缩放或偏移?

GT911 按其自身配置中存储的分辨率上报坐标(X 在 0x8048,Y 在 0x804A)。如果与您的面板分辨率不一致,请对数值进行缩放,或将驱动的 x_max/y_max 设为控制器的分辨率,再通过 swap_xy 和 mirror_x/mirror_y 调整方向。

GT911 不接 INT 引脚能工作吗?

可以。改为轮询 0x814E 状态寄存器,而不使用中断。ESPHome 在未设置 interrupt_pin 时默认每 50 ms 轮询一次。没有 INT 时主机也无法选择地址,因此使用 0x5D 或 0x14 中有应答的那个即可。

我应该重写 GT911 的配置吗?

仅作为最后手段。先从 0x8047 读出并保存现有的 186 字节配置块;优先在软件中修正分辨率和方向;如确需写入配置,请使用触摸屏供应商提供的配置文件。该配置块末尾是位于 0x80FF 的 8 位校验和,以及位于 0x8100、必须为 1 的 config_fresh 字节。

资料来源

  1. Linux 内核:drivers/input/touchscreen/goodix.c
  2. Linux 内核:drivers/input/touchscreen/goodix.h(寄存器地址)
  3. Linux 内核:Goodix 触摸屏设备树绑定(goodix.yaml)
  4. 乐鑫 ESP-BSP:esp_lcd_touch_gt911 驱动源码
  5. 乐鑫 ESP-BSP:esp_lcd_touch_gt911 头文件(I2C 地址)
  6. ESPHome:GT911 触摸屏
  7. ESPHome:触摸屏组件(变换、校准)

不确定哪款显示屏适合你的设计?

告诉我们尺寸、接口和主控。显示工程师会在 12 小时内回复 2–3 个方案,附规格书和初始化代码。样品 1 片起。