4. 刷新机制概述:事件驱动与轮询模式的对比

说到触摸偏移的解决,绕不开一个核心问题:系统怎么知道触摸发生了? 或者说,应用层怎么拿到最新的触摸坐标?

这就引出了两种最基本的刷新模式——轮询(Polling) 和 事件驱动(Event-Driven)。我做了这么多年触控交互,可以说这两者的选择直接决定了你的方案是「省电流畅」还是「卡顿费电」。今天咱们就把它们掰开揉碎,看看各自的门道。

4.1 轮询模式:主动去问

轮询,说白了就是「定时去查一下」。系统每隔固定时间(比如每 10ms)主动去读取触摸控制器的寄存器,看看有没有新数据。

核心特征: 不管有没有触摸事件,CPU 都得按时醒来干活。

我在早期做嵌入式触控项目时,就踩过这个坑。当时用的一个低端 MCU,轮询间隔设了 5ms,结果 CPU 负载直接飙到 60% 以上,UI 动画都开始掉帧。嗯,这就是轮询的代价。

轮询的优缺点

维度 说明
实现简单 一个定时器 + 一个读取函数,搞定。不需要中断、不需要回调。
可预测性高 执行周期固定,适合对时序要求严格的场景(比如游戏中的固定帧率)。
CPU 空转 大部分轮询周期其实没有新数据,白白浪费功耗。
响应延迟不稳定 最坏情况下,触摸发生后的等待时间接近一个轮询周期。
我曾经踩过的坑: 轮询周期设得太短(< 2ms),导致触摸控制器 I²C 总线被频繁占用,反而影响了其他传感器的通信。后来我把周期放宽到 8ms,配合一个「数据就绪」引脚做辅助判断,才解决了问题。

4.2 事件驱动模式:等着被通知

事件驱动就聪明多了。触摸控制器一旦检测到触摸,主动发一个中断信号给 CPU。CPU 收到中断后,再去读取坐标数据。没有触摸时,CPU 可以安心睡大觉。

核心特征: 有事件才干活,没事件就休息。

你想想看,现在的手机为什么能待机那么久?就是因为大部分时间 CPU 都在深度睡眠,只有触摸、按键这些事件才能唤醒它。这就是事件驱动的威力。

事件驱动的优缺点

维度 说明
省电高效 CPU 空闲时进入低功耗模式,事件到来才唤醒。
响应快 中断响应通常在微秒级,触摸到处理的延迟极低。
实现复杂 需要配置中断控制器、编写中断服务函数、处理中断嵌套和优先级。
可能丢失事件 如果中断处理时间过长,或者中断频率过高,可能造成事件丢失。
我的个人习惯: 在中断服务函数里只做「标记」和「拷贝最小数据」,真正的坐标滤波、偏移校准放到任务线程里做。这样能保证中断不被阻塞。

4.3 两种模式的对比总览

为了让你看得更清楚,我整理了一张对比表。这张表我每次做方案选型时都会拿出来对照一下。

对比项 轮询模式 事件驱动模式
触发方式 定时主动查询 外部中断被动响应
CPU 占用 持续占用(即使无事件) 仅在事件发生时占用
功耗 高 低
响应延迟 0.5 ~ 1 个轮询周期 微秒级
实现难度 低 中高
适用场景 简单系统、固定帧率应用 移动设备、低功耗嵌入式

4.4 核心逻辑流程图

下面这张 SVG 图,把两种模式的完整流程画出来了。你可以对照着看,理解它们从「触摸发生」到「应用层拿到坐标」的完整链路。

轮询 vs 事件驱动 核心流程对比 轮询 vs 事件驱动 核心流程对比 轮询模式 触摸发生 定时器触发 读取触摸寄存器 判断是否有新数据 处理触摸数据 CPU 持续工作 即使无触摸也在空转 事件驱动模式 触摸发生 硬件产生中断信号 CPU 响应中断 读取触摸坐标 处理触摸数据 无触摸时 CPU 休眠 事件到来才唤醒

4.5 实际项目中的选择策略

你可能会问:那我到底该用哪种?

我的经验是,没有绝对的好坏,只有合不合适的场景。我列几个典型情况,你可以对号入座:

  • 低功耗电池设备(手表、遥控器、触控笔):必须用事件驱动。轮询会快速耗尽电池。
  • 高帧率游戏(120fps 触控采样):可以用轮询,因为游戏本身就在以固定帧率运行,轮询周期可以和帧率对齐,减少额外开销。
  • 工业控制面板:建议事件驱动 + 轮询兜底。事件驱动保证响应速度,轮询作为防丢失的保险。
  • 简单原型验证:先用轮询快速跑通,后期再优化成事件驱动。
一个小技巧: 如果你不确定选哪个,可以先实现事件驱动,然后在中断处理中加一个「超时轮询」的 fallback。这样既有事件驱动的低功耗,又有轮询的可靠性。我在一个医疗设备项目中就用过这个方案,效果很好。

4.6 本章小结