⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps2.c

📁 PS2读出键盘驱动程序
💻 C
字号:


#include <at89x51.h>
#include <intrins.h>
#include "scancodes.h"

// PS2 相关口线
#define Key_Data  P2_3 //定义Keyboard引脚
#define Key_CLK  P2_4


unsigned char Keyboard_out(void) ;      // 读 PS2 键盘
unsigned char Decode(unsigned char ScanCode) ;   // 解码

void main(void)
{
unsigned char TempCyc;
unsigned char KEY=0;
                                                              
Delay400Ms();  //  启动等待,等LCM  进入工作状态
LCMInit();   //  LCM初始化 
Delay5Ms();  //  延时片刻(可不要)

for (TempCyc=0; TempCyc<10; TempCyc++);
Delay400Ms();  //  
DisplayListChar(0, 1, Cls); 
IT0 = 0;   //  设外部中0?为低电平触发
IT1 = 0;   //  设外部中断1为低电平触发

DI=0;
DA=0;
TTT=0;
AntiCW=1;
do
{
/*    EA=1;
    if (Mode==1)  AutoKey();            // 双键
*/  

// 上面这几行如果注释掉程序就完全正常

    KEY=Keyboard_out();  // 读键盘
   if(KEY)
        {
        CW_char(KEY);
        ROCK(0,KEY);
        KEY=0;
        }

}
while(1);
}


unsigned char Keyboard_out(void)
{
unsigned char KeyV=0;
unsigned char IntNum = 0;
Key_CLK=1;
EA=0;
if(!Key_CLK)
{
do  {
    if ((IntNum >0) && (IntNum < 9))
    { 
       KeyV = KeyV >> 1;     //因键盘数据是低>>高,结合上一句所以右移一位
    if (Key_Data) 
        KeyV = KeyV | 0x80;    //当键盘数据线为1时为1到最高位
    }
    Key_CLK=1;
    IntNum++;
    while (!Key_CLK);      //等待PS/2CLK拉高
    } while (IntNum<12);
   return (Decode(KeyV));    // 键盘解码
}
return 0;
}


unsigned char  Decode(unsigned char ScanCode)
//注意:如SHIFT+G为12H 34H F0H 34H F0H 12H?
//也就是说shift的通码+G的通码+shift的断码+G的断码
{
unsigned char TempCyc; 
unsigned char KeyChar=0;
if (!Key_UP) //当键盘松开时
{
switch (ScanCode)
  {
  case 0xF0 : // 当收到0xF0,Key_UP置1表示断码开始
         Key_UP = 1;
      break;

  case 0x12 : // 左 SHIFT
      Shift = 1;
         break;

  case 0x59 : // 右 SHIFT
         Shift = 1;
            break;

  default: 
      if (DisNum > 15) DisNum = 0; 
         if(!Shift) //如果SHIFT没按下
         {
       for (TempCyc = 0;(UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表显示
          if (UnShifted[TempCyc][0] == ScanCode) 
                    KeyChar=UnShifted[TempCyc][1];
          DisNum++;
         } 
      else //按下SHIFT
          {
         for(TempCyc = 0; (Shifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表显示
       if (Shifted[TempCyc][0] == ScanCode) 
                    KeyChar=Shifted[TempCyc][1];
        DisNum++;
       }

      break;
     }
}
else
{ 
Key_UP = 0;
switch (ScanCode) //当键松开时不处理判码,如G 34H F0H 34H 那么第二个34H不会被处理
  {
  case 0x12 : // 左 SHIFT
      Shift = 0;
         break;
  case 0x59 : // 右 SHIFT
      Shift = 0;
         break;
  }
}
//BF = 0;
return KeyChar;
} 



{
/*    EA=1;
    if (Mode==1)  AutoKey();            // 双键
*/  

// 上面这几行如果注释掉程序就完全正常

    KEY=Keyboard_out();  // 读键盘
   if(KEY)
        {
        CW_char(KEY);
        ROCK(0,KEY);
        KEY=0;
        }

}

/*------------------------------------
     PS2键盘外部INT1中断服务程序

原创:           HotPower@126.com   
------------------------------------*/
void int1proc() interrupt IE1_VECTOR using 1
{
unsigned char i, key;
code unsigned char PS2TAB[] = {//20键PS2小键盘键码表
  0x70,//0
  0x69,//1
  0x72,//2
  0x7a,//3
  0x6b,//4
  0x73,//5
  0x74,//6
  0x6c,//7
  0x75,//8
  0x7d,//9
  0x05,//F1
  0x06,//F2
  0x04,//F3
  0x0c,//F4
  0x03,//F5
  0x0b,//F6
  0x5a,//Enter
  0x76,//Esc
  0x66,//Bksp
  0x71//KP.
  };
  if (PS2Buffers.PS2KeyCount == 0){//PS2起始位测试
    if (!PS2CLOCK && !PS2DATA){//低电平是起始位
      if (PS2Buffers.PS2KeyExtFlage != 0xf0){
        PS2Buffers.PS2KeyTemp = 0;
        PS2Buffers.PS2KeyExtFlage = 0;
        PS2Buffers.PS2KeyPopError = 0;
      }
      PS2Buffers.PS2KeyCount ++;//脉冲计数
    }
    else PS2Buffers.PS2KeyPopError = 0xeb;//置键起始位错误号0xeb
  }
  else if (PS2Buffers.PS2KeyCount < 9){//PS2数据位
    key = PS2Buffers.PS2KeyTemp;//取键盘缓冲区移位数据
    key >>= 1;
    if (PS2DATA) key |= 0x80;
    PS2Buffers.PS2KeyTemp = key;
    PS2Buffers.PS2KeyCount++;//脉冲计数
  }
  else if (PS2Buffers.PS2KeyCount == 9){//PS2数据奇校验
    ACC = PS2Buffers.PS2KeyTemp;//取键盘缓冲区移位数据(C51取偶校验位)
    if (P != PS2DATA) PS2Buffers.PS2KeyCount ++;//脉冲计数
    else{
      PS2Buffers.PS2KeyPopError = 0xec;////置键奇校验位错误号0xec
      PS2Buffers.PS2KeyCount = 0;//脉冲计数归零
    }
  }
  else if (PS2Buffers.PS2KeyCount == 10){//停止位
    key = PS2Buffers.PS2KeyTemp;//取键盘缓冲区移位数据
    PS2Buffers.PS2KeyCount = 0;//脉冲计数归零
    if (PS2DATA){//高电平是停止位
      if (key == 0xe0){//本次是扩展键
        PS2Buffers.PS2KeyExtFlage = 0xe0;//置扩展键标志(小键盘只有回车键)
      }
      else if (key == 0xf0){//本次是键断码,键释放
        PS2Buffers.PS2KeyExtFlage = 0xf0;//置键释放标志
      }
      else{//本次必为键值
        if ((key == 0xaa) || (key == 0xfa)) PS2Buffers.PS2KeyPushCount = 0;//长
压键计数器清零
        else{
            PS2CLOCK = 0;//阻止PS2键盘立即回送数据
          PS2Buffers.PS2KeyPopError = 0xaa;//出错码
          for (i = 0; i < 20; i++){
            if (key == (PS2TAB[i])){//搜索
              key = i + 1;
              if (PS2Buffers.PS2KeyExtFlage == 0xf0){
                key |= 0x80;//键释放
                PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零
                PS2Buffers.PS2KeyMessage = key;//存入当前键值并执行命令
              }
              else{
                if (key != PS2Buffers.PS2KeyVal){//换了一个键
                  PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零
                  PS2Buffers.PS2KeyMessage = key;//存入当前键值并执行命令
                }
                else{//未换键
                  PS2Buffers.PS2KeyPushCount ++;//长压键计数器计数
                  if (PS2Buffers.PS2KeyPushCount > DEFPS2PUSHCOUNT){//长压时间到
                    PS2Buffers.PS2KeyMessage = key | 0x40;//存入当前键值并执行命
                    PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零
                  }
                }
              }
              PS2Buffers.PS2KeyVal = key;//存入当前键值值1~20或0x80+(1~20)
              PS2Buffers.PS2KeyTemp = 0;//键码移位记录器
              PS2Buffers.PS2KeyExtFlage = 0;//扩展键标志
              PS2Buffers.PS2KeyPopError = 0;//键释放标志或出错码
              break;
            }
          }
          if (PS2Buffers.PS2KeyPopError) PS2Buffers.PS2KeyPushCount = 0;//长压键
计数器清零
          PS2CLOCK = 1;//释放PS2时钟总线
        }
      }
    }
    else PS2Buffers.PS2KeyPopError = 0xed;//置停止位错误号0xed
  }
  else PS2Buffers.PS2KeyCount = 0;//PS2键盘出错
}
  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -