Chuyển đến nội dung
Display Engineer
Xử lý sự cố

Cảm ứng GT911 không hoạt động? Sửa lỗi địa chỉ I2C, thời điểm reset, cấu hình và tọa độ

Danh sách kiểm tra từng bước cho bộ điều khiển cảm ứng điện dung GT911 không bị phát hiện, không nhận được điểm chạm hoặc báo sai tọa độ: nguồn và quét I2C, trình tự chọn địa chỉ qua INT/RST, thanh ghi trạng thái 0x814E, cạnh ngắt, độ phân giải và các cách sửa trục cho Linux, ESP-IDF và ESPHome.

DEDisplay Engineer Applications Team · Kỹ sư ứng dụng màn hìnhCập nhật 19 thg 10, 2026

Bắt đầu từ đây: đối chiếu hiện tượng

Hiện tượng

Nguyên nhân nhiều khả năng nhất

Xem mục

Không thấy gì tại 0x5D hay 0x14 khi quét I2C

Bộ điều khiển không được cấp nguồn, thiếu điện trở kéo lên, hoặc chip đang bị giữ ở trạng thái reset

Bước 1

Phát hiện tại 0x14 trong khi driver kỳ vọng 0x5D (hoặc ngược lại), hoặc địa chỉ thay đổi giữa các lần khởi động

Mức chân INT trong lúc reset

Bước 2

Được phát hiện, đọc product ID chính xác, nhưng không có điểm chạm nào

Thanh ghi trạng thái chưa được xóa, cạnh ngắt sai, hoặc INT chưa được nối dây

Bước 3

Có điểm chạm nhưng bị sai vị trí, bị đảo chiều hoặc xoay

Độ phân giải trong cấu hình GT911 không khớp với tấm panel, hoặc cần hoán đổi các trục

Bước 4

Đang định viết lại khối cấu hình mới

Hãy đọc phần này trước

Bước 5

Thực hiện lần lượt theo các bước. Các địa chỉ thanh ghi và thông số thời điểm dưới đây lấy từ driver goodix của Linux, component esp_lcd_touch_gt911 của Espressif và tài liệu ESPHome; các liên kết nằm trong phần Sources.

1. Xác nhận GT911 đã có nguồn và phản hồi trên I2C

Nguồn và điện trở kéo lên

Device-tree binding của Linux cho các bộ điều khiển Goodix nêu tên hai nguồn cấp: AVDD28 (analog) và VDDIO (đường nguồn I/O logic). Trên module hoặc FPC, cả hai thường được cấp từ connector của máy chủ, vì vậy hãy đo ngay tại connector trước khi nghi ngờ firmware. SDA và SCL cũng cần có điện trở kéo lên ở đâu đó trên bus; nhiều module hiển thị không tích hợp sẵn chúng.

Quét bus

Chạy một sketch quét I2C hoặc i2cdetect. GT911 phản hồi tại một trong hai địa chỉ 7-bit:

Địa chỉ 7-bit

Byte ghi / đọc 8-bit (như một số datasheet liệt kê)

0x5D

0xBA / 0xBB

0x14

0x28 / 0x29

Các cặp 8-bit xuất phát từ một chú thích trong mã reset của driver Linux. Nếu tài liệu của nhà cung cấp ghi "địa chỉ 0xBA", đó chính là thiết bị với địa chỉ 7-bit 0x5D; hãy nhập 0x5D trong Arduino, ESP-IDF và Linux.

Đọc product ID

Các thanh ghi trên GT911 dùng địa chỉ 16-bit. Driver Linux đọc 6 byte từ 0x8140: 4 byte đầu là product ID ở dạng văn bản ASCII và 2 byte sau là phiên bản firmware (little-endian). GT911 báo chuỗi 911. Nếu bạn nhận được 911, thì bus, nguồn và địa chỉ đều ổn và vấn đề nằm ở phần sau của danh sách này.

Nếu không có gì phản hồi tại cả hai địa chỉ, hãy kiểm tra xem đường reset có đang bị giữ mức thấp hay không. Trên nhiều module, RST là chân input của GT911 và phải được máy chủ đưa lên mức cao (hoặc kéo lên trên bo mạch) trước khi bộ điều khiển hoạt động.

2. Thực hiện đúng trình tự reset và chọn địa chỉ

GT911 chọn địa chỉ I2C dựa trên mức tín hiệu trên chân INT tại thời điểm reset được nhả. Theo nguyên văn của binding Linux, đường INT "được thiết bị lấy mẫu khi reset được nhả để chọn địa chỉ I2C client".

Mức INT khi RST lên mức cao

Địa chỉ I2C

Thấp

0x5D

Cao

0x14

Trình tự mà driver Linux sử dụng

  1. Kéo RST xuống mức thấp và chờ hơn 10 ms (driver chờ 20 ms).
  2. Đưa INT về mức tương ứng với địa chỉ mong muốn: cao để chọn 0x14, thấp để chọn 0x5D.
  3. Chờ hơn 100 µs.
  4. Đưa RST lên mức cao và chờ hơn 5 ms (driver chờ 6–10 ms).
  5. Kéo INT xuống mức thấp trong 50 ms, sau đó chuyển INT sang chế độ đầu vào.

Nếu INT ở trạng thái thả nổi (float) trong bước 4, địa chỉ có thể khác nhau giữa các lần cấp nguồn. Đây chính là hiện tượng quen thuộc theo dạng "nạp xong thì chạy, khởi động nguội lại thì lỗi".

ESP-IDF: esp_lcd_touch_gt911

Component của Espressif định nghĩa ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS là 0x5D và ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUP là 0x14. Nó chỉ chạy trình tự chọn địa chỉ khi cả ba điều kiện sau được thỏa mãn:

  • rst_gpio_num là một GPIO thực (không phải GPIO_NUM_NC),
  • int_gpio_num là một GPIO thực,
  • driver_data trỏ tới một cấu trúc esp_lcd_touch_io_gt911_config_t whose dev_addr là địa chỉ bạn muốn.

Ngược lại, nó ghi log I2C address initialization procedure skipped - using default GT9xx setup và chỉ thực hiện reset thông thường. Khi đó, địa chỉ phụ thuộc vào cách đi dây của bo mạch, và địa chỉ I2C của panel-IO bạn truyền vào phải khớp với kết quả quét I2C. Xung clock I2C mặc định của component trong ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG() là 100 kHz.

Các bo mạch mà host không điều khiển chân INT

Nếu INT không được nối với host, host không thể chọn địa chỉ, vì vậy hãy quét cả hai địa chỉ và dùng địa chỉ có phản hồi. Ví dụ, trên bo Sunton ESP32-8048S043C, ngắt của GT911 mặc định không được nối tới GPIO nào (xem trang bo mạch của chúng tôi). Trang GT911 của ESPHome lưu ý rằng khi INT đi qua một IO expander, chân này vẫn được dùng để thiết lập địa chỉ khi khởi động, nhưng cảm ứng sẽ được polled thay vì dùng ngắt.

3. Được phát hiện nhưng không có sự kiện chạm

Đọc và xóa thanh ghi trạng thái

Dữ liệu cảm ứng bắt đầu tại 0x814E. Byte đầu tiên là byte trạng thái:

  • Bit 7 (0x80): buffer sẵn sàng. Dữ liệu mới chỉ có hiệu lực khi bit này được set.
  • Bit 0–3: số điểm chạm. Driver Linux loại bỏ các giá trị vượt quá số điểm tối đa đã cấu hình.
  • Bit 4: có một phím (button) đang được nhấn.

Mỗi điểm chạm tiếp theo gồm 8 byte: một track ID, sau đó là X, Y và size dưới dạng giá trị 16-bit little-endian.

Sau khi đọc, cả driver Linux lẫn esp_lcd_touch_gt911 đều ghi 0 vào 0x814E. Nếu bạn tự viết driver, hãy làm tương tự; bỏ qua bước ghi này là lý do phổ biến khiến driver tự viết chỉ nhận được lần chạm đầu tiên.

Khớp cạnh ngắt

Kiểu trigger nằm trong cấu hình của chính GT911: bit 0–1 của byte cấu hình tại 0x804D (offset 6 tính từ vị trí bắt đầu cấu hình tại 0x8047). Driver Linux ánh xạ như sau:

Giá trị

Kiểu ngắt

0

Cạnh lên

1

Cạnh xuống

2

Mức thấp

3

Mức cao

Hãy đặt ngắt GPIO tương ứng. Trong esp_lcd_touch_gt911, levels.interrupt = 1 chọn ngắt cạnh lên và 0 là cạnh xuống.

Không có đường INT? Dùng polling

Polling hoạt động tốt cho ứng dụng HMI. ESPHome poll mặc định mỗi 50 ms (update_interval) khi không đặt interrupt_pin. Driver Linux, khi có ngắt, sẽ chờ tối đa 20 ms cho bit ready trước khi bỏ qua một khung cảm ứng.

4. Tọa độ cảm ứng bị sai vị trí

Kiểm tra độ phân giải lưu trong GT911

GT911 báo tọa độ theo độ phân giải ghi trong cấu hình của nó, chứ không theo độ phân giải của màn hình bạn. Theo driver Linux, giá trị X maximum là số 16-bit little-endian tại 0x8048 và Y maximum tại 0x804A. Hãy đọc hai giá trị này. Nếu controller được cấu hình cho 1024×600 trong khi panel của bạn là 800×480, điểm chạm sẽ nằm lệch sang phải và xuống dưới so với ngón tay, và các cạnh xa bị rơi ra ngoài màn hình. Cách khắc phục là scale (hoặc đặt giới hạn của driver theo giá trị của controller).

Nguồn giới hạn độ phân giải của từng stack:

Stack

Nguồn độ phân giải

Hoán vị và lật gương

Linux goodix

Đọc từ cấu hình GT911; fallback về 4095 × 4095 khi cấu hình không có

Device-tree touchscreen-swapped-x-y, touchscreen-inverted-x, touchscreen-inverted-y, touchscreen-size-x/y

ESP-IDF esp_lcd_touch_gt911

x_max / y_max do bạn khai báo trong esp_lcd_touch_config_t (driver không đọc độ phân giải của chip)

flags.swap_xy, flags.mirror_x, flags.mirror_y

ESPHome gt911

Touchscreen calibration (x_min, x_max, y_min, y_max)

transform: swap_xy / mirror_x / mirror_y

Hiệu chuẩn từ giá trị raw

Trang touchscreen của ESPHome gợi ý log touch.x_raw và touch.y_raw trong một lambda on_touch, chạm vào các góc ở sát pixel biên vài lần, rồi nhập giá trị raw nhỏ nhất và lớn nhất làm calibration. Cách này dùng được trên mọi platform: in ra X và Y raw, chạm bốn góc, và ánh xạ khoảng giá trị đó lên màn hình.

Sửa hướng theo thứ tự này: trước hết đưa X và Y về đúng trục (swap_xy), sau đó lật trục nào chạy ngược (mirror_x / mirror_y). Điểm logic (0, 0) của màn hình phải là góc trên bên trái.

5. Ghi lại cấu hình GT911: giải pháp cuối cùng

Khối cấu hình bắt đầu tại 0x8047. Với GT911, driver Linux coi nó dài 186 byte:

  • Byte 0 (0x8047): phiên bản cấu hình.
  • Byte 1–4: độ phân giải X và Y (xem bước 4).
  • Byte 5 (0x804C): số điểm cảm ứng tối đa, 4 bit thấp.
  • Byte 6 (0x804D): kiểu kích hoạt ngắt, 2 bit thấp.
  • Byte 184 (0x80FF): checksum, phần bù hai của 8 bit của tổng các byte 0–183.
  • Byte 185 (0x8100): config_fresh, phải bằng 1.

Bản thân driver Linux chỉ ghi cấu hình khi nó có cả GPIO INT và RST và tìm thấy file firmware (tên mặc định goodix_911_cfg.bin, hoặc tên trong thuộc tính goodix,config-name). Không có file đó, nó dùng cấu hình đã lưu sẵn trong chip.

Trước khi ghi bất cứ thứ gì, hãy đọc đủ 186 byte và lưu lại. Hãy sửa độ phân giải và hướng trong phần mềm khi có thể. Một khối cấu hình làm cho panel cảm ứng khác có thể làm mất cảm ứng trên panel của bạn, nên nếu thực sự cần thay đổi, hãy lấy file từ nhà cung cấp panel.

Chọn module cảm ứng điện dung

Nếu bạn đang chọn màn hình CTP cho một thiết kế mới, hãy hỏi nhà cung cấp ba điều trước khi đặt mẫu: bộ điều khiển cảm ứng sử dụng chip nào, địa chỉ I2C xuất xưởng là bao nhiêu, và chân INT và RST có được dẫn tới đầu nối hay không. Gửi thông tin về kích thước, giao diện và vi xử lý chủ của bạn qua Ask an Engineer, chúng tôi sẽ cung cấp cả ba câu trả lời đó cùng với các module mà chúng tôi đề xuất.

Câu hỏi thường gặp

Địa chỉ I2C của GT911 là gì?

Một trong hai địa chỉ 0x5D hoặc 0x14 (7-bit). Bộ điều khiển lấy mẫu chân INT khi reset được nhả: INT mức thấp chọn 0x5D, INT mức cao chọn 0x14. Các datasheet liệt kê 0xBA/0xBB hoặc 0x28/0x29 thực chất là cùng địa chỉ đó ở dạng byte ghi/đọc 8-bit.

Tại sao GT911 của tôi đổi địa chỉ sau khi khởi động lại?

Chân INT đang thả nổi hoặc do thành phần khác điều khiển khi reset được nhả, nên bộ điều khiển lấy mẫu mức khác nhau mỗi lần. Kéo INT xuống mức thấp (cho 0x5D) hoặc mức cao (cho 0x14) trước khi nhả RST, đợi hơn 5 ms, giữ INT ở mức thấp trong 50 ms, sau đó chuyển chân này thành đầu vào. Nếu host không điều khiển được INT, hãy quét cả hai địa chỉ.

Tại sao GT911 của tôi chỉ nhận được một điểm chạm?

Sau khi đọc dữ liệu cảm ứng tại 0x814E, ghi 0 vào 0x814E. Driver goodix của Linux và esp_lcd_touch_gt911 của Espressif đều làm điều này sau mỗi lần đọc; driver bỏ qua bước này thường sẽ không còn nhận được các lần chạm mới.

Tại sao tọa độ cảm ứng GT911 bị scale hoặc lệch offset?

GT911 báo tọa độ theo độ phân giải được lưu trong cấu hình của chính nó (X tại 0x8048, Y tại 0x804A). Nếu giá trị này khác với panel của bạn, hãy scale các giá trị hoặc đặt x_max/y_max của driver theo độ phân giải của bộ điều khiển, sau đó dùng swap_xy và mirror_x/mirror_y để chỉnh hướng.

GT911 có hoạt động khi không có chân INT không?

Có. Hãy polling thanh ghi trạng thái 0x814E thay vì dùng ngắt. ESPHome mặc định polling mỗi 50 ms khi không đặt interrupt_pin. Không có INT, host cũng không thể chọn địa chỉ, nên hãy dùng địa chỉ trong hai địa chỉ 0x5D hoặc 0x14 nào phản hồi.

Tôi có nên ghi lại cấu hình GT911 không?

Chỉ dùng như giải pháp cuối cùng. Trước tiên hãy đọc và lưu khối 186 byte hiện có từ 0x8047, ưu tiên sửa độ phân giải và hướng trong phần mềm, và nếu bắt buộc phải ghi cấu hình thì dùng file config từ nhà cung cấp touch panel. Khối này kết thúc bằng checksum 8-bit tại 0x80FF và byte config_fresh tại 0x8100 phải bằng 1.

Nguồn

  1. Linux kernel: drivers/input/touchscreen/goodix.c
  2. Linux kernel: drivers/input/touchscreen/goodix.h (địa chỉ thanh ghi)
  3. Linux kernel: Goodix touchscreen device-tree binding (goodix.yaml)
  4. Espressif ESP-BSP: mã nguồn driver esp_lcd_touch_gt911
  5. Espressif ESP-BSP: header esp_lcd_touch_gt911 (địa chỉ I2C)
  6. ESPHome: GT911 touchscreen
  7. ESPHome: Touchscreen components (transform, calibration)

Chưa chắc màn hình nào phù hợp thiết kế của bạn?

Gửi kích thước, giao tiếp và bộ xử lý host. Kỹ sư màn hình sẽ phản hồi trong 12 giờ với 2–3 phương án, datasheet và mã khởi tạo. Mẫu từ 1 chiếc.