3. 触摸采样率优化:采样率对响应速度的影响、如何配置触摸控制器采样率、避免采样抖动
触摸采样率,说白了就是触摸控制器每秒钟“看”一次触摸屏的次数。单位是 Hz。比如 100Hz 的采样率,就是每 10ms 报告一次触摸坐标。这个参数直接决定了你的 UI 响应有多跟手。
我刚开始做 TouchGFX 项目时,总觉得采样率越高越好。后来在一个工业平板项目上吃了亏——采样率设到 250Hz,结果 SPI 总线被触摸中断占满了,屏幕刷新反而卡顿。嗯,从那以后我才明白,采样率不是越高越好,得跟系统整体节奏匹配。
3.1 采样率对响应速度的影响
触摸响应延迟,说白了就是从手指碰到屏幕,到 UI 元素做出反应的时间。这个延迟由三部分组成:
- 触摸硬件采样延迟:触摸控制器采集坐标并上报的时间
- 传输延迟:通过 I2C/SPI 把数据传给 MCU 的时间
- 软件处理延迟:TouchGFX 处理触摸事件并更新画面的时间
采样率主要影响第一部分。你想想看,如果采样率是 60Hz,那么两次采样间隔约 16.7ms。手指从按下到被检测到,平均要等半个周期,也就是 8.3ms。如果采样率提高到 120Hz,这个等待时间就降到 4.2ms。
我在一个医疗设备项目中做过对比测试:
| 采样率 (Hz) | 采样间隔 (ms) | 平均触摸延迟 (ms) | 主观体验 |
|---|---|---|---|
| 60 | 16.7 | 8.3 | 轻微迟滞感 |
| 100 | 10.0 | 5.0 | 基本流畅 |
| 120 | 8.3 | 4.2 | 跟手 |
| 200 | 5.0 | 2.5 | 非常跟手 |
但要注意,采样率超过 120Hz 后,人眼能感知的差异其实很小。反而会带来额外的 CPU 开销。我个人习惯把采样率控制在 100~120Hz,这个区间性价比最高。
核心结论:采样率每翻一倍,触摸延迟减半。但超过 120Hz 后边际收益递减,且可能引入其他问题。
3.2 如何配置触摸控制器采样率
不同触摸控制器的配置方式不一样。我接触最多的是 FT5x06 系列和 GT911 系列。下面分别说。
3.2.1 FT5x06 系列配置
FT5x06 的采样率由寄存器 0x88 控制。默认值是 0x0A(10),对应 100Hz。配置公式是:
采样率 (Hz) = 1000 / (寄存器值 × 1ms)
举个例子:
- 寄存器值 = 10 → 1000 / 10 = 100Hz
- 寄存器值 = 8 → 1000 / 8 = 125Hz
- 寄存器值 = 5 → 1000 / 5 = 200Hz
配置代码片段:
// FT5x06 设置采样率为 125Hz
uint8_t rate = 8;
I2C_WriteRegister(FT5x06_ADDR, 0x88, rate);
3.2.2 GT911 系列配置
GT911 的采样率配置稍微复杂一点。它通过寄存器 0x8040 的 bit[3:0] 控制。配置值跟采样率的对应关系是:
| 寄存器值 | 采样率 (Hz) |
|---|---|
| 0x03 | 100 |
| 0x02 | 125 |
| 0x01 | 166 |
| 0x00 | 200 |
配置代码:
// GT911 设置采样率为 125Hz
uint8_t config[2];
config[0] = 0x02; // 采样率配置值
config[1] = 0x00; // 其他配置保持默认
I2C_WriteRegister(GT911_ADDR, 0x8040, config, 2);
个人经验:配置采样率后,一定要读回确认。我遇到过 I2C 写入失败但没报错的情况,结果采样率还是默认值,排查了半天。
3.3 避免采样抖动
采样抖动,说白了就是触摸坐标在短时间内来回跳变。比如手指明明没动,但上报的 x 坐标在 ±5 像素范围内跳动。这会导致 UI 元素抖动,用户体验很差。
为什么会这样?三个原因:
- 触摸控制器自身噪声:电容触摸屏的物理特性决定的,尤其是低端控制器
- 电源噪声:触摸控制器的供电纹波太大,影响 ADC 采样精度
- 采样率过高:采样率太高时,相邻两次采样的时间间隔太短,噪声被放大
我曾经在一个消费电子项目上被采样抖动坑惨了。用户反馈说“滑动时图标在抖”,我一开始以为是 UI 渲染问题,查了两天才发现是触摸采样抖动。后来用了三个手段解决:
3.3.1 硬件滤波
在触摸控制器的供电引脚上加 100nF + 10μF 去耦电容。这个看似简单,但效果很明显。我测过,不加电容时抖动幅度 ±8 像素,加上后降到 ±2 像素。
3.3.2 软件去抖算法
TouchGFX 本身没有内置去抖算法,需要自己在触摸驱动里实现。我常用的方法是滑动平均滤波:
#define FILTER_WINDOW 4
typedef struct {
int16_t x_buf[FILTER_WINDOW];
int16_t y_buf[FILTER_WINDOW];
uint8_t index;
} TouchFilter;
int16_t TouchFilter_Process(TouchFilter *filter, int16_t raw_value) {
// 存入最新值
filter->buf[filter->index] = raw_value;
filter->index = (filter->index + 1) % FILTER_WINDOW;
// 计算平均值
int32_t sum = 0;
for (int i = 0; i < FILTER_WINDOW; i++) {
sum += filter->buf[i];
}
return (int16_t)(sum / FILTER_WINDOW);
}
这个算法简单有效。窗口大小我建议用 4,太小去抖效果差,太大会引入明显延迟。
3.3.3 合理设置采样率
采样率不是越高越好。我做过对比测试:
| 采样率 (Hz) | 抖动幅度 (像素) | 去抖后延迟 (ms) | 推荐场景 |
|---|---|---|---|
| 60 | ±1 | 16.7 | 静态界面、按钮点击 |
| 100 | ±2 | 10.0 | 通用场景 |
| 120 | ±3 | 8.3 | 滑动列表、拖拽 |
| 200 | ±5 | 5.0 | 不推荐,抖动明显 |
避坑指南:我曾经把采样率设到 200Hz,然后发现触摸中断每 5ms 触发一次,CPU 大量时间花在中断处理上。更糟的是,抖动导致去抖算法需要更大的窗口,反而增加了延迟。最后我老老实实改回 100Hz,配合硬件滤波和 4 点滑动平均,效果很好。
3.4 采样率优化流程图
下面这张图总结了采样率优化的完整流程,从硬件配置到软件去抖,每一步都有明确的决策点。
这张图把整个优化流程串起来了。从选择采样率开始,到硬件滤波,再到软件去抖,每一步都有明确的输入输出。我个人习惯在项目初期就把这张图贴在墙上,开发过程中对照检查,避免遗漏。
小技巧:调试采样抖动时,可以用 TouchGFX 的 TouchCalibration 工具实时查看原始坐标。如果发现坐标在静止时跳动超过 ±3 像素,就需要优化了。
总结一下,采样率优化的核心就三句话:选对采样率(100~120Hz),做好硬件滤波,加上软件去抖。这三步走完,触摸响应基本不会出大问题。