✅ 一、GT9271 的核心接口说明
- 硬件连接(I²C 接口 + 控制引脚)
| GT9271 引脚 | 功能 | MCU 连接建议 |
|---|---|---|
I2C_SCL | I²C 时钟 | 接 MCU 的 I2C SCL |
I2C_SDA | I²C 数据 | 接 MCU 的 I2C SDA |
INT | 中断输出 | 接 MCU GPIO 中断引脚 |
/RST | 复位 | 接 MCU GPIO 输出引脚 |
AVDD、VDDIO | 电源 | 一般 2.8~3.3V,VDDIO 需接上拉 |
GND | 地线 | 接地 |
- SDA/SCL 需要接 2kΩ 上拉电阻。
- INT 接口可配置为上升沿/下降沿中断。
- RST 上电初始化需由主控控制(决定 I2C 地址)。
✅ 二、GT9271 的 I2C 初始化时序(关键)
GT9271 有两个 I2C 地址选项:
- 0xBA/0xBB(写/读)
- 0x28/0x29(写/读)
通过 INT 与 RST 引脚上电时的状态设定:
-设定为 0x28/0x29: - RST 拉低(>100us)
- INT 拉高
- RST 拉高(>5ms)
- INT 改为输入(悬浮)
设定为 0xBA/0xBB: - RST 拉低(>100us)
- INT 拉低
- RST 拉高(>5ms)
- INT 改为输入(悬浮)
所以如果你选择使用 0x28 写地址,初始化要正确控制这两个引脚时序。
✅ 三、MCU HC32 对接 GT9271 步骤
-
初始化 I2C
• 配置 I2C 速率建议不超过 400Kbps;
• 设置 I2C 地址;
• 配置 GPIO INT 和 RST;
• INT 配为中断输入引脚。 -
初始化 GT9271(建议流程)
// 设置 I2C 地址为 0x28 的流程
void GT9271_Reset_Init(void) {
GPIO_Reset(RST_PIN); // RST = 0
GPIO_Set(INT_PIN); // INT = 1
delay_us(120); // >100us
GPIO_Set(RST_PIN); // RST = 1
delay_ms(10); // >5ms
GPIO_Input(INT_PIN); // INT 设为输入
}
- 检测设备是否在线
读取寄存器地址 0x8140 ~ 0x8143,返回的是 “9271” 的 ASCII 字符,即 0x39 0x32 0x37 0x31。
✅ 四、读取触摸坐标流程
触摸数据起始地址:0x814E
结构如下:

✅ 五、HC32 示例任务划分
I²C通信驱动部分:
• 使用 HC32 的 I2C HAL 库或裸写寄存器方式
• 支持读写 16 位寄存器地址的 I2C 协议
中断处理部分:
• INT 引脚中断响应时,读取 0x814E 判断是否有触点
• 根据触点数量读取相应的坐标点
应用层:
• 将坐标信息传入 GUI、手势识别或你自定义的界面控制逻辑中。
✅ 六、你可以从哪些地方开始?
如果你刚开始用 HC32 + GT9271,建议按以下步骤来:
1. 硬件连接确认;
2. 写一个 GT9271 初始化函数(控制 RST/INT、检测 I2C 地址);
3. 读 Product ID 和坐标数据(检测触摸);
4. 实现 INT 中断处理逻辑;
5. 将坐标数据打印出来验证。
🧭 一、整体开发流程
步骤
说明
- 硬件连接与原理图确认
GT9271 接 I2C、INT、RST、供电等 - MCU 初始化
GPIO、I2C 初始化 - GT9271 初始化流程
控制 RST/INT、选择 I2C 地址、检查设备在线 - 获取触摸数据
轮询或中断读取坐标数据 - 坐标后处理
滤波 / 去抖动 / 坐标转换 - 应用接口对接
显示或手势识别等
🔌 二、硬件连接简要说明

🎯 四、触摸点优化建议(滤波处理)
坐标会有轻微抖动,建议处理如下:
✅ 1. 简单平均滤波(Moving Average)
#define FILTER_N 3
static int16_t x_hist[FILTER_N];
static int16_t y_hist[FILTER_N];
static uint8_t filter_index = 0;
void GT9271_Filter(TouchPoint* raw, TouchPoint* smooth) {
x_hist[filter_index] = raw->x;
y_hist[filter_index] = raw->y;
filter_index = (filter_index + 1) % FILTER_N;
int32_t sum_x = 0, sum_y = 0;
for (int i = 0; i < FILTER_N; ++i) {
sum_x += x_hist[i];
sum_y += y_hist[i];
}
smooth->x = sum_x / FILTER_N;
smooth->y = sum_y / FILTER_N;
}
✅ 2. 条件滤波(去抖动)
if (abs(current.x - last.x) > THRESHOLD || abs(current.y - last.y) > THRESHOLD) {
// 接受新坐标
}
✅ INT 引脚的作用详解
📌 INT 是谁拉的?
INT 是 GT9271 输出的,用于通知主控有事件,比如:
• 有触摸点按下或移动;
• 有按键(如果你用了触摸按键);
• 某些内部状态更新(较少使用)。
📌 INT 是什么信号?
你可以根据配置寄存器选择 INT 是:
• 下降沿触发(默认):触摸发生时,GT9271 将 INT 拉低一个短脉冲;
• 上升沿触发;
• 低电平触发查询(轮询模式);
在实际中,大多数使用方式是:INT 为下降沿中断触发。
📌 MCU 如何响应?
你需要:
• 把 MCU 的某个 GPIO 配成“下降沿触发的中断输入”;
• 在中断服务函数中读取触摸状态寄存器 0x814E,然后读取触摸点坐标。
🧩 文件结构规划(gt9271.c / gt9271.h)
我将帮你构建一个可移植性较强的驱动文件,方便你添加到任何 HC32 工程中。包含:
// gt9271.h
#ifndef __GT9271_H__
#define __GT9271_H__
#include <stdint.h>
#include <stdbool.h>
typedef struct {
uint16_t x;
uint16_t y;
} TouchPoint;
void GT9271_GPIO_Init(void);
void GT9271_I2C_Init(void);
void GT9271_Reset(void);
bool GT9271_CheckOnline(void);
uint8_t GT9271_ReadTouchPoints(TouchPoint *points);
void GT9271_Filter(TouchPoint *raw, TouchPoint *filtered);
#endif
// gt9271.c
#include "gt9271.h"
#include "your_i2c_driver.h" // 你自己的 I2C 实现
#include "your_gpio_driver.h" // 你自己的 GPIO 实现
#include "delay.h"
#define GT9271_I2C_ADDR_WRITE 0x28
#define GT9271_I2C_ADDR_READ 0x29
#define GT9271_STATUS_REG 0x814E
#define GT9271_POINT1_XL 0x8150
#define GT9271_MAX_TOUCH 5
#define FILTER_N 3
static int16_t x_hist[FILTER_N], y_hist[FILTER_N];
static uint8_t filter_index = 0;
void GT9271_GPIO_Init(void) {
GPIO_Config(INT_PIN, INPUT_PULLUP);
GPIO_Config(RST_PIN, OUTPUT);
}
void GT9271_I2C_Init(void) {
I2C_Config_Typedef cfg = {
.clockSpeed = 100000,
.addressingMode = I2C_ADDRESSINGMODE_7BIT,
};
I2C_Init(I2C1, &cfg);
}
void GT9271_Reset(void) {
GPIO_Write(RST_PIN, 0);
GPIO_Write(INT_PIN, 1); // 设定 I2C 地址为 0x28
Delay_us(120);
GPIO_Write(RST_PIN, 1);
Delay_ms(10);
GPIO_Config(INT_PIN, INPUT); // INT 悬空,等待 GT9271 驱动
}
bool GT9271_CheckOnline(void) {
uint8_t buf[4];
I2C_ReadRegister(GT9271_I2C_ADDR_WRITE, 0x8140, buf, 4);
return buf[0] == '9' && buf[1] == '2' && buf[2] == '7' && buf[3] == '1';
}
uint8_t GT9271_ReadTouchPoints(TouchPoint* points) {
uint8_t status;
I2C_ReadRegister(GT9271_I2C_ADDR_WRITE, GT9271_STATUS_REG, &status, 1);
uint8_t num = status & 0x0F;
if (num == 0 || num > GT9271_MAX_TOUCH) return 0;
uint8_t buf[8 * GT9271_MAX_TOUCH];
I2C_ReadRegister(GT9271_I2C_ADDR_WRITE, GT9271_POINT1_XL, buf, num * 8);
for (uint8_t i = 0; i < num; i++) {
points[i].x = (buf[i * 8 + 1] << 8) | buf[i * 8];
points[i].y = (buf[i * 8 + 3] << 8) | buf[i * 8 + 2];
}
uint8_t clear = 0;
I2C_WriteRegister(GT9271_I2C_ADDR_WRITE, GT9271_STATUS_REG, &clear, 1);
return num;
}
void GT9271_Filter(TouchPoint* raw, TouchPoint* filtered) {
x_hist[filter_index] = raw->x;
y_hist[filter_index] = raw->y;
filter_index = (filter_index + 1) % FILTER_N;
int32_t sum_x = 0, sum_y = 0;
for (int i = 0; i < FILTER_N; ++i) {
sum_x += x_hist[i];
sum_y += y_hist[i];
}
filtered->x = sum_x / FILTER_N;
filtered->y = sum_y / FILTER_N;
}
⚡ INT 中断使用方法(简化说明)
你需要:
1. 在 GPIO 初始化时启用下降沿中断;
2. 在中断回调函数里调用 GT9271_ReadTouchPoints();
3. 中断结束后,坐标就读取好了,送给你界面/UI 层处理。
✅ 一、GT9271 + HC32 DDL 开发时你会遇到的典型问题




352

被折叠的 条评论
为什么被折叠?



