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

📄 ps2.c

📁 基于51单片机的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 + -