본문으로 건너뛰기
Display Engineer
문제 해결

GT911 터치가 동작하지 않나요? I2C 주소, 리셋 타이밍, 설정 및 좌표 문제 해결

GT911 정전식 터치 컨트롤러가 감지되지 않거나, 터치가 전혀 입력되지 않거나, 잘못된 좌표를 보고할 때를 위한 단계별 체크리스트: 전원 및 I2C 스캔, INT/RST 주소 선택 시퀀스, 0x814E 상태 레지스터, 인터럽트 엣지, 해상도 및 축 문제 해결 (Linux, ESP-IDF, ESPHome 대응).

DEDisplay Engineer Applications Team · 디스플레이 애플리케이션 엔지니어업데이트: 2026년 10월 19일

여기서 시작하세요: 증상별 매칭

증상

가장 가능성 높은 원인

이동

I2C 스캔에서 0x5D 또는 0x14 어디에서도 응답이 없음

컨트롤러에 전원이 공급되지 않음, 풀업 저항 누락, 또는 칩이 리셋 상태로 고정됨

Step 1

드라이버가 0x5D를 기대하는데 0x14에서 발견되거나(또는 그 반대), 부팅할 때마다 주소가 바뀜

리셋 중 INT 핀 레벨

Step 2

감지는 되고 제품 ID도 올바르게 읽히지만 터치가 입력되지 않음

상태 레지스터가 클리어되지 않음, 인터럽트 엣지 설정 오류, 또는 INT 핀이 배선되지 않음

Step 3

터치는 입력되지만 위치가 틀리거나, 좌우 반전 또는 회전됨

GT911 설정의 해상도가 패널과 일치하지 않거나, 축을 서로 바꿔야 함

Step 4

새로운 설정 블록을 작성하려는 경우

먼저 이 내용을 읽으세요

Step 5

단계를 순서대로 진행하세요. 아래의 레지스터 주소와 타이밍은 Linux goodix 드라이버, Espressif의 esp_lcd_touch_gt911 컴포넌트 및 ESPHome 문서에서 가져온 것이며, 관련 링크는 Sources 섹션에 있습니다.

1. GT911의 전원 공급 및 I2C 응답 확인

전원 및 풀업

Goodix 컨트롤러의 Linux 디바이스 트리 바인딩은 두 개의 전원을 명시합니다: 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이 읽힌다면 버스, 전원, 주소 모두 정상이며 문제는 이 목록의 더 아래에 있는 것입니다.

두 주소 어디에서도 응답이 없다면, 리셋 라인이 Low로 고정되어 있지 않은지 확인하세요. 많은 모듈에서 RST는 GT911의 입력 핀이며, 컨트롤러가 동작하기 전에 호스트가 이를 High로 구동(또는 보드에서 풀업)해야 합니다.

2. 리셋 및 주소 선택 시퀀스를 올바르게 수행하기

GT911은 리셋이 해제되는 순간 INT 핀의 레벨을 기준으로 I2C 주소를 결정합니다. Linux 바인딩의 표현을 빌리면, INT 라인은 "I2C 클라이언트 주소를 선택하기 위해 리셋 해제 시점에 디바이스가 샘플링하는" 신호입니다.

RST가 High가 될 때의 INT 레벨

I2C 주소

Low

0x5D

High

0x14

리눅스 드라이버가 사용하는 시퀀스

  1. RST를 Low로 출력하고 10 ms 이상 대기합니다(드라이버는 20 ms 대기).
  2. INT를 원하는 주소에 해당하는 레벨로 출력합니다: 0x14는 High, 0x5D는 Low입니다.
  3. 100 µs 이상 대기합니다.
  4. RST를 High로 출력하고 5 ms 이상 대기합니다(드라이버는 6–10 ms 대기).
  5. INT를 50 ms 동안 Low로 출력한 뒤, 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부터 시작합니다. 첫 바이트는 상태 바이트입니다:

  • 비트 7 (0x80): 버퍼 준비 완료. 이 비트가 설정되어 있을 때만 새 데이터가 유효합니다.
  • 비트 0–3: 터치 포인트 수. 리눅스 드라이버는 설정된 최대값을 초과하는 개수는 거부합니다.
  • 비트 4: 키(버튼)가 눌려 있음.

이어지는 각 터치 포인트는 8바이트입니다: 트랙 ID 하나와, 리틀 엔디안 16비트 값으로 된 X, Y, size입니다.

읽은 후에는 리눅스 드라이버와 esp_lcd_touch_gt911 모두 0x814E에 0을 씁니다. 직접 드라이버를 작성하는 경우에도 동일하게 해야 합니다. 이 쓰기를 생략하면 직접 작성한 드라이버가 첫 터치만 받게 되는 흔한 원인이 됩니다.

인터럽트 엣지 일치시키기

트리거 타입은 GT911 자체 설정에 있습니다: 0x804D의 설정 바이트(0x8047의 설정 시작 위치로부터 오프셋 6)의 비트 0–1입니다. 리눅스 드라이버는 이를 다음과 같이 매핑합니다:

값

인터럽트 타입

0

라이징 엣지

1

폴링 엣지

2

Low 레벨

3

High 레벨

GPIO 인터럽트 설정을 이에 맞추십시오. esp_lcd_touch_gt911에서 levels.interrupt = 1은 상승 엣지 인터럽트를, 0은 하강 엣지를 선택합니다.

INT 라인이 없다면? 폴링을 사용하십시오

HMI 용도라면 폴링으로도 충분합니다. ESPHome은 interrupt_pin이 설정되지 않은 경우 기본적으로 50 ms 간격(update_interval)으로 폴링합니다. Linux 드라이버는 인터럽트가 있을 때 프레임을 포기하기 전까지 준비 비트를 최대 20 ms까지 기다립니다.

4. 터치 위치가 어긋나는 경우

GT911에 저장된 해상도를 확인하십시오

GT911은 디스플레이 해상도가 아니라 자체 설정에 기록된 해상도 기준으로 좌표를 보고합니다. Linux 드라이버에 따르면 X 최댓값은 0x8048에, Y 최댓값은 0x804A에 있는 리틀 엔디안 16비트 값입니다. 이 값을 읽어 보십시오. 컨트롤러가 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 람다에서 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비트 2의 보수.
  • 바이트 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가 Low이면 0x5D, High이면 0x14가 선택됩니다. 0xBA/0xBB 또는 0x28/0x29로 표기된 데이터시트는 동일한 주소를 8비트 쓰기/읽기 바이트로 표현한 것입니다.

GT911이 리부팅 후 주소가 바뀌는 이유는 무엇입니까?

리셋 해제 시점에 INT 핀이 플로팅 상태이거나 다른 회로에 의해 구동되어, 매번 다른 레벨이 샘플링되기 때문입니다. RST를 해제하기 전에 INT를 Low(0x5D) 또는 High(0x14)로 구동하고, 5 ms 이상 대기한 뒤, INT를 50 ms 동안 Low로 유지한 후 입력 모드로 전환하십시오. 호스트가 INT를 제어할 수 없다면 두 주소를 모두 스캔해야 합니다.

GT911에서 터치가 한 번만 인식되는 이유는 무엇입니까?

0x814E에서 터치 데이터를 읽은 후, 0x814E에 0을 다시 써야 합니다. Linux goodix 드라이버와 Espressif의 esp_lcd_touch_gt911 모두 매 읽기 후 이를 수행하며, 이를 생략하는 드라이버는 새로운 터치를 감지하지 못하게 되는 경우가 일반적입니다.

GT911 터치 좌표가 스케일되거나 오프셋되는 이유는 무엇입니까?

GT911은 자체 설정에 저장된 해상도(X는 0x8048, Y는 0x804A)로 좌표를 보고합니다. 이 값이 패널 해상도와 다르면 값을 스케일링하거나 드라이버의 x_max/y_max를 컨트롤러의 해상도로 설정한 후, 방향에 따라 swap_xy 및 mirror_x/mirror_y를 사용하십시오.

INT 핀 없이도 GT911을 사용할 수 있습니까?

네, 가능합니다. 인터럽트 대신 0x814E 상태 레지스터를 폴링하십시오. ESPHome은 interrupt_pin이 설정되지 않은 경우 기본적으로 50 ms 간격으로 폴링합니다. INT가 없으면 호스트가 주소를 선택할 수도 없으므로, 0x5D와 0x14 중 응답하는 쪽을 사용하십시오.

GT911 설정을 다시 작성해야 합니까?

최후의 수단으로만 사용해야 합니다. 먼저 0x8047부터 기존 186바이트 설정 블록을 읽어 저장해 두고, 해상도와 방향은 소프트웨어에서 수정하는 것을 우선하며, 불가피하게 써야 한다면 터치 패널 공급업체의 설정 파일을 사용하십시오. 이 블록은 0x80FF의 8비트 체크섬과 0x8100의 config_fresh 바이트(반드시 1이어야 함)로 끝납니다.

출처

  1. Linux 커널: drivers/input/touchscreen/goodix.c
  2. Linux 커널: drivers/input/touchscreen/goodix.h (레지스터 주소)
  3. Linux 커널: Goodix 터치스크린 디바이스 트리 바인딩 (goodix.yaml)
  4. Espressif ESP-BSP: esp_lcd_touch_gt911 드라이버 소스
  5. Espressif ESP-BSP: esp_lcd_touch_gt911 헤더 (I2C 주소)
  6. ESPHome: GT911 터치스크린
  7. ESPHome: 터치스크린 컴포넌트 (transform, 캘리브레이션)

어떤 디스플레이가 설계에 맞는지 고민되시나요?

크기, 인터페이스, 호스트 프로세서를 알려 주세요. 디스플레이 엔지니어가 12시간 이내에 데이터시트와 초기화 코드를 포함한 2–3가지 옵션을 회신합니다. 샘플 1개부터.