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

📄 ps2_keyboard.c

📁 ps2键盘的时序介绍和开发程序
💻 C
字号:
//====================================================================================
//文 件 名:PS2_Keyboard.c
//功能描述: PS2键盘驱动程序
//维护记录: 2007年3月17日
//====================================================================================
#include "PS2_Keyboard.h"

#define KEYB_CMD_RESET			0xFF
#define KEYB_CMD_PAUSE			0xF5
#define KEYB_CMD_RESUME			0xF4
#define KEYB_CMD_LED			0xED

#define KEYB_RSP_ACK			0xFA
#define KEYB_RSP_TESTOK			0xAA

extern void Delay(unsigned int Delays);
KEYB_STATUS Key_Status;
unsigned int Repeat = 0 ;//sign 0
volatile unsigned int LKeyCount = 0;

//=============================================================
//语法格式:	short Keyboard_Init(void);
//实现功能:	键盘初始化
//参数:		无
//返回值:		0:	成功
//				-1:	失败
//=============================================================
short Keyboard_Init(void)
{
	PS2_Init();
	return Keyboard_Reset();
}

//=============================================================
//语法格式:	short Keyboard_Command(unsigned char Command);
//实现功能:	向键盘发送命令(内部调用)
//参数:		Command:	待发送的命令字
//返回值:		0:	成功
//				-1:	失败
//=============================================================
short Keyboard_Command(unsigned char Command)
{
	PS2_ClearBuf();
	PS2_Write(Command);
	while(PS2_Status()&PS2_STATUS_WRITING);					// 等待写入完成
	if(PS2_Status()&PS2_STATUS_WRITEERR)
		return -1;
	while((PS2_Status()&PS2_STATUS_DATARDY)==0)           //接收缓冲区有新数据跳出
	{
		if(PS2_Status()&PS2_STATUS_READERR)return -1;			
	}
	if(PS2_Read()!=KEYB_RSP_ACK)
		return -1;
	return 0;
}

//=============================================================
//语法格式:	short Keyboard_Reset(void);
//实现功能:	复位键盘
//参数:		无
//返回值:		0:	成功
//				-1:	失败
//=============================================================
short Keyboard_Reset(void)
{
	if(Keyboard_Command(KEYB_CMD_RESET)!=0)
		return -1;
	while((PS2_Status()&PS2_STATUS_DATARDY)==0)
		if(PS2_Status()&PS2_STATUS_READERR)return -1;			
	if(PS2_Read()!=KEYB_RSP_TESTOK)
		return -1;
	return 0;
}

//=============================================================
//语法格式:	short Keyboard_Pause(void);
//实现功能:	暂停键盘扫描
//参数:		无
//返回值:		0:	成功
//				-1:	失败
//=============================================================
short Keyboard_Pause(void)
{
	if(Keyboard_Command(KEYB_CMD_PAUSE)!=0)
		return -1;
	return 0;
}

//=============================================================
//语法格式:	short Keyboard_Resume(void);
//实现功能:	恢复被暂停的键盘扫描
//参数:		无
//返回值:		0:	成功
//				-1:	失败
//=============================================================
short Keyboard_Resume(void)
{
	if(Keyboard_Command(KEYB_CMD_RESUME)!=0)
		return -1;
	return 0;
}

//=============================================================
//语法格式:	short Keyboard_SetupLED(unsigned char LEDCode);
//实现功能:	控制键盘上的三个LED点亮或熄灭
//参数:		LEDCode:
//					KEYB_LED_SCROLL:	Scroll Lock点亮
//					KEYB_LED_NUM:		Num Lock点亮
//					KEYB_LED_CAPS:		Caps Lock点亮
//返回值:		0:	成功
//				-1:	失败
//=============================================================
short Keyboard_SetupLED(unsigned char LEDCode)
{
	if(Keyboard_Command(KEYB_CMD_LED)!=0)
		return -1;
	if(Keyboard_Command(LEDCode)!=0)
		return -1;
	return 0;
}

//=============================================================
//语法格式:	void Keyboard_Get(KEYB_STATUS *pKeyStatus);
//实现功能:	捕捉按键事件
//参数:		pKeyStatus:		存储当前按键状态的结构体地址
//返回值:		0:	键盘有动作
//				-1: 键盘无动作
//例如:   shift+A   0x12 0x1C 0xF0 0x1C 0xF0 0x12   存在PS2_ReadBuf[PS2_BUFSIZE]中
//=============================================================
short Keyboard_Get(KEYB_STATUS *pKeyStatus)
{
	static unsigned char PS2_Buf[8];						// 暂存上次读取到的不完整数据
	static short PS2_BufPointer = 0;
	static KEYB_STATUS KeyStatusBuf = {0, {0x0000}};
															// 上次的按键状态
	unsigned short TempData;
	short i, KeyFlag = -1;
	
	while(PS2_Status()&PS2_STATUS_DATARDY)					// 如果接收到新数据
	{
		if(KeyStatusBuf.KeyCode[0]==0xE012 || KeyStatusBuf.KeyCode[0]==0xE114)
		{													// 如果之前按键为PrintScreen或Pause则清除
			KeyStatusBuf.KeyCount = 0;
		}
		if(PS2_BufPointer<8)								
		{
			TempData = PS2_Read();
			PS2_Buf[PS2_BufPointer++] = TempData;
			PS2_Buf[PS2_BufPointer] = 0x00;
			switch(PS2_Buf[0])
			{
				case 0xE0:									// 扩展按键
					switch(PS2_Buf[1])
					{
						case 0xF0:							// E0 F0 xx, 扩展按键断码
							if(PS2_Buf[2]!=0x00)
							{
								KeyStatusBuf.KeyCount -= 1;
								if(KeyStatusBuf.KeyCount<0) KeyStatusBuf.KeyCount = 0;
								TempData = 0xE000|PS2_Buf[2];
								for(i=0; i<KeyStatusBuf.KeyCount; i++)
								{
									if(KeyStatusBuf.KeyCode[i]==TempData)
									{
										KeyStatusBuf.KeyCode[i] = KeyStatusBuf.KeyCode[i+1];
										KeyStatusBuf.KeyCode[i+1] = TempData;
									}
								}
								PS2_Buf[0] = 0x00;
								PS2_BufPointer = 0;
								KeyFlag = 0;
							}
							break;
						case 0x00:							// 码尚未接收完							
							break;
						case 0x12:							// E0 12 E0 7C, PrintScreen键
							if(PS2_Buf[2]==0xE0 && PS2_Buf[3]==0x7C)
							{
								KeyStatusBuf.KeyCount = 1;
								KeyStatusBuf.KeyCode[0] = 0xE012;
								PS2_Buf[0] = 0x00;
								PS2_BufPointer = 0;
								KeyFlag = 0;
							}
							break;
						default:							// E0 xx, 扩展按键通码
							TempData = 0xE000|PS2_Buf[1];
							for(i=0; i<KeyStatusBuf.KeyCount; i++)
							{
								if(KeyStatusBuf.KeyCode[i]==TempData) break;
							}
							if(i==KeyStatusBuf.KeyCount)
							{
								KeyStatusBuf.KeyCode[i] = TempData;
								KeyStatusBuf.KeyCount += 1;
							}
							PS2_Buf[0] = 0x00;
							PS2_BufPointer = 0;
							KeyFlag = 0;
					}            //switch(PS2_Buf[1])
					break;
				case 0xE1:									// E1 14 77 E1 F0 14 F0 77, Pause键
					if(PS2_BufPointer==8 && PS2_Buf[7]==0x77)
					{
						KeyStatusBuf.KeyCount = 1;
						KeyStatusBuf.KeyCode[0] = 0xE114;
						PS2_Buf[0] = 0x00;
						PS2_BufPointer = 0;
						KeyFlag = 0;
					}
					break;
				case 0xF0:									// F0 xx, 普通键断码
					if(PS2_Buf[1]!=0x00)
					{
						KeyStatusBuf.KeyCount -= 1;
						if(KeyStatusBuf.KeyCount<0) KeyStatusBuf.KeyCount = 0;
						for(i=0; i<KeyStatusBuf.KeyCount; i++)
						{
							if(KeyStatusBuf.KeyCode[i]==PS2_Buf[1])
							{
								KeyStatusBuf.KeyCode[i] = KeyStatusBuf.KeyCode[i+1];
								KeyStatusBuf.KeyCode[i+1] = PS2_Buf[1];
							}
						}
						PS2_Buf[0] = 0x00;
						PS2_BufPointer = 0;
						KeyFlag = 0;
					}
					break;
				default:									// xx, 普通键通码
					for(i=0; i<KeyStatusBuf.KeyCount; i++)
					{
						if(KeyStatusBuf.KeyCode[i]==PS2_Buf[0]) 
						break;
					}
					if(i==KeyStatusBuf.KeyCount)
					{
						if(KeyStatusBuf.KeyCount<KEYB_MAX_PRESS)
						{
							KeyStatusBuf.KeyCode[i] = PS2_Buf[0];
							KeyStatusBuf.KeyCount += 1;
						}
					}
					PS2_Buf[0] = 0x00;
					PS2_BufPointer = 0;
					KeyFlag = 0;
			}          //switch(PS2_Buf[0])
		}           //if(PS2_BufPointer<8)
	}            //while(PS2_Status()&PS2_STATUS_DATARDY)

	pKeyStatus->KeyCount = KeyStatusBuf.KeyCount;
	for(i=0; i<KeyStatusBuf.KeyCount; i++)
	{
		pKeyStatus->KeyCode[i] = KeyStatusBuf.KeyCode[i];
	}
	return KeyFlag;
}

//=============================================================
//语法格式:	int Key_Get()
//实现功能:	得到键盘的扫描码
//参数:		无
//返回值:		键盘的扫描码
//=============================================================
int Key_Get()
{
	unsigned int Key = 0,i = 0;
	if(Keyboard_Get(&Key_Status)==0)
	{
		Delay(10);
		if(LKeyCount < Key_Status.KeyCount)
		{
			Key = Key_Status.KeyCode[Key_Status.KeyCount-1];//sign-0 //
			for(i = 0; i < KEYB_MAX_PRESS; i++)
			{
				Key_Status.KeyCode[i] = 0;
			}			
			return Key;	
		}
		LKeyCount = Key_Status.KeyCount;
	}
	return 0;
}

⌨️ 快捷键说明

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