用户中心

资讯 > 嵌入式系统

基于Small RTOS51的PS/2键盘驱动程序开发

来源:嵌入式应用2006.09.22阅读 2177

1 驱动的设计
  驱动的实现一般可用以下几种方法:① 使用任务编写;② 使用消息编写;③ 使用信号量编写。PS/2键盘既不需要CPU周期服务,又不具有自己的中断设备,但为了实现实时响应,本驱动采用中断方式,利用全局变量传递数据,并在中断服务程序唤醒处理任务。
1.1 中断服务程序
  驱动程序使用中断接收按键的部分扫描码,并使用全局变量缓存它们。使用一个任务处理这些扫描码来获取按键键值。通过对各种按键扫描码的分析,可将扫描码分为下列3种情况:a. 普通按键。通码为唯一标识自己的1个字节;断码为2个字节。第1字节为F0H,第2字节为通码。b. 功能键,如CTR。通码第1字节为E0H,第2字节为区别于其他按键的标识码;断码有3个字节,分别为E0H、F0H和标识码。c. 组合键,如G。得到G的按键顺序是:按shift,按gCONTROL ENGINEERING China版权所有,释放g,最后释放shift。所以扫描码应为:12H,34H,F0H,34H,F0H,12H。
  由以上分析可知,无论是何种按键,只要知道扫描码的前两个字节,就可以确定哪个按键或那些组合键被按下,并可通过查表找到相应的ASCII码。这样,只接收2个字节,就可大大减少中断次数,

节省CPU资源。中断程序如下:
void Receive() interrupt 0 {
  IE0=0;
  dat>>=1; //接收数据,低→高
  if(sda) dat|=0x80;
  count++;
  if(count==num) {
    if(num==9) {
      temp[0]=dat;
      num=20;
    }
    else {
      temp[1]=dat;
      IE&=0xfe;
      count=0;
      num=9;
      OSSendIntSignal(KeyCodeTranst_ID);
      OSIntExt();
    }
  }
}
  程序首先按照Small RTOS51的中断编写规范调用宏OS_Int_ENTER()。如果用户禁止中断嵌套管理(EN_OS_Int_ENTER=0),那么不必调用宏。接着,接收扫描码的前面两个字节,并存放在数组temp[2]中。当判断接收完毕(count==20)时,就要将接收中断关闭,以拒绝接收键盘发送后面的扫描码。 然后, 直接调用 OSSendInt Signal(KeyCodeTranst_ID),使键码转换处理任务就绪。最后,根据Small RTOS51的中断编写规范调用函数OSIntExt(),通知退出中断服务程序并进行任务切换。
1.2 键码处理任务设计
  这个任务完全可以在中断服务中完成控制工程网版权所有,但为了避免接收扫描码的后面部分,在接收到前两个字节后,必须进行一定的延时。若放在中断服务中完成,会增加中断延时。键码处理任务设计主要完成从中断服务程序返回的扫描码的前两个字节,判断按键属于何种类型,并通过查表找到相应的ASCII码。任务源代码如下:
KeyCodeTranst() {
  uint8Key;
  PS2Int();//键盘初始化
  OSQCreate(Key_ASCIICONTROL ENGINEERING China版权所有,16);//创建存放按键ASCII码数据队列
  while(1) {
    OSWait(K_SIG,0);//等待按键
    IE&=0x0fe;//屏蔽无用扫描码
    if(temp[1]==0xf0&&temp[0]!=0xe0)Key=noshift[temp[0]];//键码转换
    else if(temp[0]==0xe0&&temp[1]!=0xf0)Key=noshift[temp[1]];
    else if(temp[0]==0x12||temp[0]==0x59)Key=addshift[temp[1]];
    OSWait(K_TMO,5);//延时5个滴答
    IE0=0;
    IE|=0x01;//准备接收下一个按键
    OSQPost(Key_ASCIICONTROL ENGINEERING China版权所有,Key);//发送ASCII码
  }
}
  任务首先创建一个存放按键ASCII码的消息队列,然后对PS/2键盘初始化PS2Int()。初始化中控制工程网版权所有,可以简单地开始所使用的中断CONTROL ENGINEERING China版权所有,也可以在该函数中加上其他一些用户程序。
  下面服务函数开始进入一个无限循环中。OSWait(K_SIG,0);是等待信号,当中断程序接收完扫描码时,会通过函数OSSendIntSignal(KeyCodeTranst_ID)唤醒该任务。此时数组temp[2]中存放当前按键扫描码的前两个字节:
  若temp[1]为0xf0,且temp[0]不等于0xe0,则说明是普通按













































版权声明:版权归控制工程网所有,转载请注明出处!

频道推荐

关于我们

控制工程网 & CONTROL ENGINEERING China 全球工业控制、自动化和仪器仪表领域的先锋媒体

CE全球

联系我们

商务及广告合作
任小姐(北京)                 夏小姐(上海)
电话:010-82053688      电话:18616877918
rendongxue@cechina.cn      xiashuxian@cechina.cn
新闻投稿:王小姐

关注我们的微信

关于我们 | 网站地图 | 联系我们
© 2003-2020    经营许可编号:京ICP证120335号
公安机关备案号:110102002318  服务热线:010-82053688