硬件设计
目前,移动终端上的大多数按钮都是电容式按钮。电容式按钮的基本原理与电容式触摸屏相同,感知电极之间电容值的变化,以判断当前是否有触摸动作。
除了触摸屏,市场上大多数独立电容按钮的设计都是RC串联电路(如图1所示),VCC一端不断发出扫描脉冲,使电路中的电容C1重复充放电A点引起电压变化。当触摸时,电容值会增加,从而延长充放电周期。如果触摸,电容C1.充放电周期为T1.当没有触摸时,周期是T0。则T1 > T0
从而判断目前是否有触摸动作。这种设计在普通家电控制面板上很常见,耐用,不易损坏,设计简单。
回到触摸屏的环境。由于基本原理的相似性,现有的按钮设计没有使用独立的扫描电路,而是从触摸屏控制器中拉出一个驱动通道作为按钮公共端(VCC脚),按键的另一端(A脚)连接到触摸屏的感应通道。从而在触摸屏中扩展电容按钮,并由触摸屏控制IC检查按钮是否被触摸。
在触摸屏上,还有一种扩展按钮的方法,那就是根本没有按钮。直接将触摸屏的一部分(一般为底部,高度为30-40)用作按键区域,并控制触摸屏IC在固件中定义相应的按键区域。当触摸点落入该区域时,控制IC把这个触摸作为一个按钮动作。我们可以称之为虚拟电容按钮,上述方法称之为独立电容按钮。虚拟电容按钮的优点是,不需要在触摸屏上植入额外的感应电极。触摸屏制造商只需在丝网印刷过程中在指定区域打印特定的按钮形状。
软件处理(基于Android)
触摸屏上的虚拟电容按键和独立电容按键有一个共性,那就是两者都是由触摸屏控制IC控制。也就是说,向驱动层报告数据的格式也由控制IC决定的。
懒人模式
控制IC按钮的处理也分为两种,一种是懒惰的模式,即什么也不做,按钮作为触摸,直接向驱动层报告具体坐标,按钮分析工作完全推到上层软件。
在这种模式下,触摸屏的驱动不会做任何按钮处理,而是继续将触摸坐标转移到Android上层传输。相应的按键区域通常会提前在驱动层中定义,配置信息会通过linux kernel的sysfs暴露在上层。例如://按钮数量
#define TPD_KEY_COUNT 4
//按键中心坐标
#define key_1 60,850
#define key_2 180,850
#define key_3 300,850
#define key_4 420,850
//按键类型
#define TPD_KEYS {KEY_BACK,KEY_HOME,KEY_MENU,KEY_SEARCH}
//按键区域,每个数字分别表示:{X_CENTER,Y_CENTER,X_RANGE,Y_RANGE}
#define TPD_KEYS_DIM { {key_1,50,30},{key_2,50,30},{key_3,50,30},{key_4,50,30} }
而在Android Native层,frameworks/base/services/input/EventHub.cpp:loadVirtualKeyMapLocked本按钮配置文件将被读取,具体定义在源文件frameworks/base/libs/androidfw/VirtualKeyMap.cpp。
这里需要注意的是,在驱动层中,并非所有情况下,按键分析工作都传递给上层。当手机在时factory mode和recovery mode因为Android上层并没有运行起来,所以在这种情况下,驱动层还是得做按键解析工作。
好人模式
触控IC另一种模式是好人模式IC寄存器标志位将专门分配给每个电容按钮,以标记当前按钮状态。驱动层读取此状态后,也将直接使用input_report_key上报keyevent给Android上层。
结语
当然,这里解释的只是正常过程中的处理。对于一些有特殊需求的人,可能需要触摸IC固件,触摸屏驱动和Android上层三者相互配合,处理情况与这里描述的不同。