2.1 矩阵键盘的Linux驱动程序设计
矩阵键盘是作为Linux的一个字符设备注册到系统中的。为了降低对系统资源的损耗,采用中断处理函数对按键做处理;同时考虑到按键的抖动问题,采用定时器来消除抖动。
该驱动程序的流程如图3所示。首先,使用S3C2440_Kb_init()函数将键盘作为一个字符设备进行注册,初始化行线引脚为:输出、非上拉,并将所有行输出置为低电平;注册该键盘设备。初始化列线所连接的中断引脚为:输入、下降沿触发中断,并建立中断与中断处理函数Key_interrupt()的连接。
当有按键按下后,由于所有的行为低电平,必然有一行和一列线导通,从而将相应的列线拉低,触发中断。然后,中断处理函数 Key_interrupt()记录相应的中断号码,由于按键存在抖动,单凭一次中断的触发就判定相应的按键按下很不可靠,所以在中断触发后开启定时器 kb_timer对按键状态再次进行判定。
上层应用程序使用S3C2440_Kb_open ()打开键盘设备,开启列线中断,初始化定时器。当中断触发后,开启定时器,定时器定时时间到后,触发定时器中断kb_timer_handler()。 kb_timer_handler()首先会调用键盘扫描函数Scan_keyboard()扫描按键状态,Scan_keyboard()流程如图4所示。如果经过3次键盘扫描,每次都扫描到相同的按键值被按下,则证明确实有按键被按下,Scan_keyboard()函数返回:KEYDOWN。如果按本次按键值与上一次按键值不同,则保存本次按键值到循环队列,这样可以不保存重复数据到缓冲队列。如果连续10次扫描到按键的状态都不为 KEY_DOWN,则证明按键已经弹起,关闭定时器kb_timer。
S3C2440_Kb_read()函数负责从循环队列中读取按键值反馈给上层应用程序。
2.2 Qt/Embedded的键盘映射
Qt/Embedded是Trolltech公司针对采用嵌人式Linux的电子设备开发的综合应用平台。Qt/Embedded包含完整的应用层、灵活的用户界面、窗口操作系统、应用程序以及开发框架。
Qt/Embedded本身提供了对按键的支持,它在文件qkeyboard_qws.cpp中提供了一个 QWSKeyboardHandler类来处理按键事件。本系统创建了QWSKeyboardHandler类的一个子类 QWSKEYMATRIXHandler。在QWSKEYMATRIXHandler类的构造函数中,通过open()函数打开矩阵键盘 key_matrix,通过对打开的键盘设备创建一个QscoketNotifer来监控按键设备,通过信号与槽机制,建立该 QscoketNotifer与读键盘函数ReadKeyboardData()的连接,当key_matrix被激活时,就会触发读键盘函数 ReadKeyboardData()。代码如下:
notifier=new QSocketNotifier(key_matrix,QSock-etNotifier::Read,this);
connect(notifier,SIGNAL(activated(int)),this,SLOT(ReadKeyboardData()));
在读键盘函数ReadKeyboardData()中,调用矩阵键盘驱动程序的读函数Read()来获取按键值。为了使得按键值能够传送给应用程序,要使用QWSKeyboardHandler类的成员函数processKeyEvent(int unicode,int keycode,int modifiers,bool isPress,bool autoRepeat),各参数功能如下:
①Unicode:按键的Unicode编码,如数字1的unicode编码为1,字母A的unicode编码为A。如果该项为0,则为功能键Shift、Left、Right等;如果该项为0xFFFF,则只传送键值keycode,不打印编码。
②Keycode:Qt中使用的按键名称,如Qt::Key_Backspace、Qt::Key_Enter等。
③Modifiers:Qt所支持的键盘组合键。
④isPress:判断按键的状态是“按下”还是“弹起”。
⑤autoRepeat:判断本次事件是有自动重复机制产生,还是由一个现实中的按键产生。
通过processKeyEvent()函数可以发送数字、小写英文、大写英文,但是目前Qt/Embedded上没有中文输入法,不能输入中文。