📄 ps2.c
字号:
#include <at89x52.h>
#include "PS2.h"
#include "INTRINS.H"
uchar code kb_plain_map[132]={
'N',
'N','N','N','N','N','N','N','N','N','N',
'N','N','N','`','N','N','N','N','N','N',
'q','1','N','N','N','z','s','a','w','2',
'N','N','c','x','d','e','4','3','N','N',
' ','v','f','t','r','5','N','N','n','b',
'h','g','y','6','N','N','N','m','j','u',
'7','8','N','N',',','k','i','o','0','9',
'N','N','.','/','l',';','p','-','N','N', //'/'==0x2f
'N',0x27,'N','[','=','N','N','N','N',0xff, //'\'==0x5c
']','N',0x5c,'N','N','N','N','N','N','N', //'''==0x27
'N',0xfe,'N','N','1','N','4','7','N','N', //0xfe==backspace,0xff=enter,
'N','0','.','2','5','6','8','N','N','N',
'+','3','-','*','9','N','N','N','N','N',
'N'
};
uchar code kb_shift_map[]={
'N',
'N','N','N','N','N','N','N','N','N','N',
'N','N','N','~','N','N','N','N','N','N',
'Q','!','N','N','N','Z','S','A','W','@',
'N','N','C','X','D','E','$','#','N','N',
' ','V','F','T','R','%','N','N','N','B',
'H','G','Y','^','N','N','N','M','J','U',
'&','*','N','N','<','K','I','O',')','(',
'N','N','>','?','L',':','P','_','N','N', //'/'==0x2f
'N','"','N','{','+','N','N','N','N','N', //'\'==0x5c
'}','N','|','N','N','N','N','N','N','N', //'''==0x27
'N','N','N','N','1','N','4','7','N','N',
'N','0','.','2','5','6','8','N','N','N',
'+','3','-','*','9','N','N','N','N','N',
'N'
};
bit Make_Code=0; // 通码标志位
bit Break_Code=0; //断码标志位
bit Decode_Ready=0;
//struct
//{
bit Caps_Flag=0;
bit Caps_Release=1;
bit Num_Flag=0;
bit Num_Release=1;
bit Scroll_Flag=0;
bit Scroll_Release=1;
bit Shift_Flag=0;
bit Ctrl_Flag=0;
bit Alt_Flag=0;
bit GUI_Flag=0;
bit Insert_Flag=0;
bit Home_Flag=0;
bit PageUp_Flag=0;
bit Delete_Flag=0;
bit End_Flag=0;
bit PageDown_Flag=0;
bit Up_Flag=0;
bit Left_Flag=0;
bit Down_Flag=0;
bit Right_Flag=0;
bit E0_Flag=0;
bit F0_Flag=0;
bit E1_Flag=0;
//}flag;
uchar PS2_Val=0;
uchar key=0;
uchar Code=0;
uchar cout=0;
bit PS2_Flag=0;
void Delay15(uchar n) //about 15us
{
do{ _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
n--;
}while(n);
}
void PS2_Init(void)
{
IT1=1;//下降沿触发
EA=1;
EX1=1;//中断允许
while(!PS2_Flag);
PS2_Flag=0;
if(PS2_Val!=0xAA) Error();
PS2_Send(0xed); //设置LED
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
PS2_Send(0x00); //关LED
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
PS2_Send(0xf3); //设置机打延时和速率
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
PS2_Send(0x00); //(250ms,2.0cps)
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
PS2_Send(0xed); //设置LED
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
PS2_Send(0x07); //开所有LED
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
PS2_Send(0xed); //设置LED
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
PS2_Send(0x00); //关LED
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
PS2_Send(0xf4); // 允许键盘
while(!PS2_Flag);//接收0xfa
PS2_Flag=0;
}
void Error()
{
P1_7=0;Delay(100);P1_7=1;Delay(100); P1_7=0;Delay(100);P1_7=1;
}
void PS2_Send(uchar dat)
{
bit Parity=1;
uchar i=0;
EA=0;
PS2_CLK=1;
for(i=0;i<8;i++)
{
if((dat>>i)&0x01) Parity=!Parity;
}
PS2_CLK=0;
Delay15(10); //延时100us
PS2_DATA=0; //start
_nop_();
PS2_CLK=1;
for(i=0;i<8;i++) //发送数据
{
while(PS2_CLK) _nop_(); //等待低电平
PS2_DATA=(dat>>i)&0x01;
// if(dat&0x01) Parity++; //计算奇偶校验位
while(!PS2_CLK) _nop_(); //等待高电平
// dat>>=1;
}
while(PS2_CLK) _nop_();
PS2_DATA=Parity; //发送奇偶校验位
while(!PS2_CLK) _nop_();//等待高电平
while(PS2_CLK) _nop_();//等待低电平
PS2_DATA=1;//停止位
while(!PS2_CLK) _nop_();//等待高电平
while(PS2_CLK) _nop_();//等待低电平
if(PS2_DATA) Error();
while(!PS2_CLK) _nop_();//等待高电平
PS2_DATA=1;// release PS2_DATA
PS2_CLK=1; // release PS2_CLK
EA=1;
}
void PS2_Read(void) interrupt 2 //external interrupt 1
{
EX1=0;
switch(cout)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
PS2_Val>>=1;
if(PS2_DATA) {PS2_Val|=0x80;}
cout++;
PS2_DATA=1;
break;
case 0: //start bit
if(PS2_DATA) break; //如果数据线不是低电平,则退出
cout++;break;
case 9: //parity bit
cout++;break;
case 10: //stop bit
cout=0;
if(!PS2_DATA) break;//如果数据线不是高电平,则退出
PS2_Flag=1;
break;
default:
break;
}
EX1=1;
}
void Decode()
{
// PrintString("\r\n Decode.\r\n");
if(!PS2_Flag) return;
if(E1_Flag) Special_Decode();
else if(E0_Flag) Decode_2();
else
{
switch(PS2_Val)
{
case 0xE0: E0_Flag=1;break;
case 0xE1: E1_Flag=1;break;
case 0xF0: F0_Flag=1;break;
default: Decode_1(); break;
}
}
}
void Decode_1()
{
if(F0_Flag)
{
F0_Flag=0;
switch(PS2_Val)
{
case 0x58://caps
Caps_Release=1;
PS2_LED();
break;
case 0x12://L Shift
Shift_Flag=0;
break;
case 0x14://L Ctrl
Ctrl_Flag=0;
break;
case 0x11://L Alt
Alt_Flag=0;
break;
case 0x59://R Shift
Shift_Flag=0;
break;
case 0x77://Num Lock
Num_Release=1;
PS2_LED();
break;
case 0x7e://Scroll Lock
Scroll_Release=1;
PS2_LED();
break;
default:
break;
}
}
else
{
switch(PS2_Val)
{
case 0x58://caps
if(Caps_Flag==Caps_Release) Caps_Flag=0;
else Caps_Flag=1;
Caps_Release=0;
break;
case 0x12://L Shift
Shift_Flag=1;
break;
case 0x14://L Ctrl
Ctrl_Flag=1;
break;
case 0x11://L Alt
Alt_Flag=1;
break;
case 0x59://R Shift
Shift_Flag=1;
break;
case 0x77://Num Lock
if(Num_Flag==Num_Release) Num_Flag=0;
else Num_Flag=1;
Num_Release=0;
break;
case 0x7e://Scroll Lock
if(Scroll_Flag==Scroll_Release) Scroll_Flag=0;
else Scroll_Flag=1;
Scroll_Release=0;
break;
default:
if(Caps_Flag==Shift_Flag) Code=kb_plain_map[PS2_Val];
else Code=kb_shift_map[PS2_Val];
Decode_Ready=1;
break;
}
}
}
void Decode_2()
{
if(F0_Flag)
{
F0_Flag=0;E0_Flag=0;
switch(PS2_Val)
{
case 0x1f://L GUI
GUI_Flag=0;break;
case 0x27://R GUI
GUI_Flag=0;break;
case 0x14://R CTRL
Ctrl_Flag=0;break;
case 0x11://R Alt
Alt_Flag=0;break;
case 0x2f://APPS
break;
case 0x70://INSERT
Insert_Flag=0;break;
case 0x6c://Home
Home_Flag=0;break;
case 0x7d://PageUp
PageUp_Flag=0;break;
case 0x71://Delete
Delete_Flag=0;break;
case 0x69://End
End_Flag=0;break;
case 0x7a://PageDown
PageDown_Flag=0;break;
case 0x75://Up Arrow
Up_Flag=0;break;
case 0x6b://Left Arrow
Left_Flag=0;break;
case 0x72://Down Arrow
Down_Flag=0;break;
case 0x74://Right Arrow
Right_Flag=0;break;
default:break;
}
}
else if(PS2_Val==0xF0)
{
F0_Flag=1;
}
else
{
E0_Flag=0;
switch(PS2_Val)
{
case 0x1f://L GUI
GUI_Flag=1;break;
case 0x27://R GUI
GUI_Flag=1;break;
case 0x14://R CTRL
Ctrl_Flag=1;break;
case 0x11://R Alt
Alt_Flag=1;break;
case 0x2f://APPS
break;
case 0x70://INSERT
Insert_Flag=1;break;
case 0x6c://Home
Home_Flag=1;break;
case 0x7d://PageUp
PageUp_Flag=1;break;
case 0x71://Delete
Delete_Flag=1;break;
case 0x69://End
End_Flag=1;break;
case 0x7a://PageDown
PageDown_Flag=1;break;
case 0x75://Up Arrow
Up_Flag=1;break;
case 0x6b://Left Arrow
Left_Flag=1;break;
case 0x72://Down Arrow
Down_Flag=1;break;
case 0x74://Right Arrow
Right_Flag=1;break;
case 0x35:// KP/
Code='/';break;
case 0x1c://KP Enter
Code=0xff;break;
default:break;
}
}
}
void Special_Decode()
{
}
void PS2_LED()
{
uchar LED_Status=0;
if(Caps_Flag) LED_Status|=0x04;
if(Num_Flag) LED_Status|=0x02;
if(Scroll_Flag) LED_Status|=0x01;
PS2_Send(0xed); //Set/Reset LEDs
while(!PS2_Flag); //wait for 0xFA
PS2_Flag=0;
PS2_Send(LED_Status);
while(!PS2_Flag);
PS2_Flag=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -