PS2 读电脑键盘实验

ps2 协议:http://apps.hi.baidu.com/share/detail/15069948
 
/****************************************************************************************
                          PS2 读电脑键盘实验           *
连接方法 : P0口与J12连接 拔开跳线帽用杜邦线连接左针与P3.2  右针与P1.6  连接       *
使用方法:  用外部中断读取PS2键盘的数据 并在数码管上显示,此程序只处理数字键盘。     *
                       *
其余按键功能用户可以自行扩展,为了程序简单便于阅读和学习,程序中没有使用奇偶校验,     *
校验程序请自行添加。            *              *
                                            *
*****************************************************************************************/

#include<REG52.h>       

sbit LS138A=P2^2;  
sbit LS138B=P2^3;
sbit LS138C=P2^4; 

sbit BEEP = P1^5;

sbit Key_Data = P1^6 ;   //定义键盘引脚
sbit Key_CLK = P3^2;     //使用外部中断

/******************************************************************/
/*                    函数声明                                    */
/******************************************************************/
void Decode(unsigned char ScanCode);  //解码子程序
void delay(unsigned int i);      //函数声名
void display();
void beep();


// 此表为 LED 的字模            // 0    1    2    3    4    5    6   7    8    9    A    b    c    d    E    -    L   P    U    Hidden  _ (20)
unsigned char code Disp_Tab[] = { ~0xC0,~0xF9,~0xA4,~0xB0,~0x99,~0x92,~0x82,~0xF8,~0x80,~0x90,~0x88,~0x83,~0xC6,~0xA1,~0x86,~0xbf,~0xc7,~0x8c,~0xc1, ~0xff,  ~0xf7 }; 
bit BF;             
unsigned char KeyV;
unsigned char LedNumVal  ;
int KEY_val,IntNum;

/******************************************************************/
/*                    主函数                                      */
/******************************************************************/
void main()
{

IT1 = 0;                              //设外部中断1为低电平触发
EA = 1;                               //外部中断开
EX0 = 1;                              //开中断

  while(1)
 {
   if (BF)
    {  
 if (KeyV != 240)  beep();  
   
       Decode(KeyV); //解码
    
   }
    else
      EA = 1; //开中断  
   display();
 }

}

/******************************************************************/
/*                    外部中断读入信息                            */
/******************************************************************/
void Keyboard_out(void) interrupt 0
{
if ((IntNum > 0) && (IntNum < 9))
   { 
 KeyV = KeyV >> 1;                //因键盘数据是低>>高,结合上一句所以右移一位
 if (Key_Data)
     KeyV = KeyV | 0x80;          //当键盘数据线为1时到最高位
 }
 IntNum++;
 while (!Key_CLK);                //等待PS/2CLK拉高

 if (IntNum > 10)
    { 
   IntNum = 0;                  //当中断11次后表示一帧数据收完,清变量准备下一次接收
   BF = 1;                      //标识有字符输入完了
  EA = 0;                      //关中断等显示完后再开中断 
  }

  }

/******************************************************************/
/*                    解码信息                                    */
/******************************************************************/
void Decode(unsigned char ScanCode) //注意:如SHIFT+G为12H 34H F0H 34H F0H 12H,也就是说shift的通码+G的通码+shift的断码+G的断码
{
    
   switch (ScanCode)
   {
   case 0x70 :             // 当收到0xF0,Key_UP置1表示断码开始
    KEY_val = 0;
    break;

   case 0x69 :             
    KEY_val = 1;
    break;

   case 0x72 :             
    KEY_val = 2;
    break;

   case 0x7A :             
       KEY_val = 3;
    break;

   case 0x6B :             
    KEY_val = 4;
    break;

   case 0x73 :             
    KEY_val = 5;
    break;

   case 0x74 :             
    KEY_val = 6;
    break;

   case 0x6c :             
    KEY_val = 7;
    break;

   case 0x75 :             
    KEY_val = 8;
    break;

   case 0x7d :             
    KEY_val = 9;
    break;

     case 0x71 :
                  
   // dot = 0X7F;
    break;
 
 }
  
  
BF = 0; //标识字符处理完了  
} 


/***************************************************************************************/
void display( )
{
   unsigned char i;
   unsigned int LedOut[8];
 
   LedNumVal = KEY_val ;


  LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
     LedOut[1]=Disp_Tab[LedNumVal%1000/100];
     LedOut[2]=Disp_Tab[LedNumVal%100/10];
     LedOut[3]=Disp_Tab[LedNumVal%10];
  
  LedOut[4]=Disp_Tab[LedNumVal%10000/1000];    //千位
     LedOut[5]=Disp_Tab[LedNumVal%1000/100];  //百位带小数点
     LedOut[6]=Disp_Tab[LedNumVal%100/10];     //十位
     LedOut[7]=Disp_Tab[LedNumVal%10];             //个位
   
 
  for( i=0; i<8; i++) 
  {  P0 = LedOut[i];
   
   switch(i)       
      {     
   case 0:LS138A=0; LS138B=0; LS138C=0; break;         
         case 1:LS138A=1; LS138B=0; LS138C=0; break;              
         case 2:LS138A=0; LS138B=1; LS138C=0; break; 
         case 3:LS138A=1; LS138B=1; LS138C=0; break; 
   case 4:LS138A=0; LS138B=0; LS138C=1; break;
   case 5:LS138A=1; LS138B=0; LS138C=1; break;
   case 6:LS138A=0; LS138B=1; LS138C=1; break;
   case 7:LS138A=1; LS138B=1; LS138C=1; break;
   
      }
   
  delay(50);
   }
 
}

/***************************************************************************************
延时程序                      *
****************************************************************************************/
void delay(unsigned int i)
{
    char j;
    for(i; i > 0; i--)
        for(j = 200; j > 0; j--);
}

/***************************************************************************************
蜂铃器发声                      *
****************************************************************************************/
void beep()
{
  unsigned char i;
  for (i=0;i<255;i++)
   {
   delay(5);
   BEEP=!BEEP;                 //BEEP取反
   } 
  BEEP=1;                      //关闭蜂鸣器
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值