首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Windows CE.Net下的矩阵键盘开发设计 02

Windows CE.Net下的矩阵键盘开发设计 02

矩阵键盘作为一种输入设备与其他外围设备有很大的区别,应用层不能对其发布命令来操作它。因此一般流驱动接口函数中对设备进行操作的接口函数在矩阵键盘驱动中只是作了保留,并未有实质性的功能。接口函数中比较重要的是PWR_Init和PWR_DllEntry。下面简单介绍这两个函数:
  ① PWR_DllEntry。驱动程序的入口函数,当Windows CE.NET加载或断开DLL时调用,其中dwReason指明了调用的原因。
  ② PWR_Init。接口函数PWR_Init完成矩阵键盘流驱动程序的初始化,首先完成矩阵键盘驱动涉及的CPU的I/O口寄存器和中断控制寄存器的地址映射工作。接下来设置中断服务线程优先级,最后创建中断服务线程和初始化I/O口。
  3.4 矩阵键盘驱动中断处理设计
  (1) 矩阵键盘驱动实现原理概述
  矩阵键盘驱动的主要作用就是实时监测外部按键中断,一旦发现外部有键按下就向内核发送键盘消息实现键盘输入功能。键盘驱动创建了中断服务线程和4个键盘中断事件,每行按键对应一个键盘中断事件。有键被按下时,中断服务例程得到对应的中断标识符并报告给系统任务调度进程,同时产生键盘中断事件,键盘中断服务线程响应键盘中断事件,开始扫描矩阵键盘。
根据产生的中断事件类型不同,可以首先确定被按下键的行位置。由于键盘被按下后,该键对应的行和列被连通,因此根据判断各列对应的I/O口的电平,可以得到被按下键的列位置;得到按键的准确位置后,通过向操作系统发送键盘消息KEYBD_EVENT,实现一次键盘输入。循环扫描键盘,直到按键被弹起则发送KEYEVENTF_KEYUP事件。响应键盘中断输入的整个流程如图2所示。

图2 响应键盘中断输入流程图

  实际上,矩阵键盘驱动的设计就是键盘中断处理的设计。下面就对矩阵键盘驱动中的中断处理设计作详细的介绍。
  (2) 在OAL层加入中断源
  矩阵键盘采用4路I/O口中断,每路中断对应1个中断源。矩阵键盘驱动首先要在OAL层加入这些中断源。以其中一路中断为例:
  #define SYSINTR_KEYONE(SYSINTR_FIRMWARE+0)
  (3) 中断服务例程(ISR)设计
  本键盘驱动将GPIO_6、GPIO_7、GPIO_16、GPIO_17四个I/O口作为中断 I/O口。有键被按下时将产生一个I/O中断,内核首先进入异常中断处理程序,由它屏蔽所有中断,再调用中断服务例程ISR得到该中断的逻辑中断标识。鉴于ISR的任务比较单一,ISR通常都要求越短、越快越好。矩阵键盘驱动的ISR设计如下:
  
if(v_pGPIOReg﹥GEDR_x & GPIO_6) {//中断触发
    v_pGPIOReg﹥GEDR_x = GPIO_6;//清除中断
    return SYSINTR_KEYONE;//返回中断标识}

  其他三路中断的ISR设计与此类似。
  (4) 中断服务线程(IST)设计
  中断服务例程以键盘中断的逻辑中断标识符形式返回给系统任务调度进程,中断服务线程则在矩阵键盘驱动中负责具体中断处理。因为中断服务例程较小,并且只做很少的处理工作,中断服务线程就必须完成大多数中断处理工作,功能主要包括响应中断、扫描按键位置、发送键盘消息等。
  矩阵键盘驱动的IST设计如下:矩阵键盘驱动设计了4个中断事件HANDLE hKEYEvents[4],分别对应矩阵键盘4行产生的中断。在矩阵键盘驱动的IST中,调用CreateEvent函数创建4个事件对象,接着调用系统函数InterruptInitialize完成中断和事件的关联并使能中断。完成这些初始化工作后,就可以调用 WaitForMultipleObjects  (hKEYEvents)函数进入键盘事件的等待队列中。当有事件被捕获后,根据不同的事件类型进入不同的键盘扫描处理程序(以其中一路中断为例):
switch (dwEventWAIT_OBJECT_0){//事件类型
  case 0://第1行键盘有键按下
  v_pGPIOReg﹥GPDR_x &= ~ (GPIO_13);//设为输入
  v_pGPIOReg﹥GPDR_x |= (GPIO_6);//中断I/O输出
  v_pGPIOReg﹥GPCR_x |= (GPIO_6);//输出低电平
  while(!(v_pGPIOReg﹥GPLR_x & GPIO_13)) {//扫描矩阵键盘,判断按键列位置
    if(num==1)//第1次连发延时400 ms
      Sleep(400);
    else
      Sleep(100);//按键延时去抖
    if(!(v_pGPIOReg﹥GPLR_x & GPIO_13)){//列位置
      keybd_event('0' ,0x71, 0, 0);//发键盘消息
      num++;//连发计数
    }
    else{
      if((v_pGPIOReg->GPLR_x & GPIO_13)&&num>0){
        num=0;//按键弹起
        keybd_event('0',0x71, KEYEVENTF_KEYUP, 0);}
    }
  }

  中断处理完成后恢复I/O口的初始电平,调用InterruptDone函数恢复中断,使其能响应下一次同样的中断。
  结语
  随着嵌入式设备应用的日益广泛,特别是微软的嵌入式操作系统Windows CE.NET的普及,Windows CE.NET下矩阵键盘设计得到了越来越多开发者的重视。本文所讨论的Windows CE.NET下矩阵键盘设计方案简单、高效、实用。特别适合于I/O口资源充足的嵌入式PDA上,现已成功应用于某卫星定位系统的键盘设计上。
返回列表