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

📄 keyboardps2_44b0.c

📁 标准PS2键盘源程序(S3C44B0XKeyboardPS2_44B0)
💻 C
📖 第 1 页 / 共 2 页
字号:
			if(KeyboardState[CapsLock]&0x80 && KeyboardMap[i].KeyAscii>=0x61 && KeyboardMap[i].KeyAscii<=0x7a)
			{
				if(KeyboardState[SCAN_KEY_LSHIFT]&0x80 || KeyboardState[SCAN_KEY_RSHIFT]&0x80)
				{
					return KeyboardMap[i].KeyAscii;
				}
				else if(KeyboardState[SCAN_KEY_LCTRL]&0x80 || KeyboardState[SCAN_KEY_RCTRL]&0x80)
				{
					return KeyboardMap[i].KeyCtrlAscii;
				}
				else if(KeyboardState[SCAN_KEY_LALT]&0x80 || KeyboardState[SCAN_KEY_RALT]&0x80)
				{
					return KeyboardMap[i].KeyAltAscii;
				}
				else
				{
					return KeyboardMap[i].KeyShiftAscii;
				}
			}
			else
			{
				if(KeyboardState[SCAN_KEY_LSHIFT]&0x80 || KeyboardState[SCAN_KEY_RSHIFT]&0x80)
				{
					return KeyboardMap[i].KeyShiftAscii;
				}
				else if(KeyboardState[SCAN_KEY_LCTRL]&0x80 || KeyboardState[SCAN_KEY_RCTRL]&0x80)
				{
					return KeyboardMap[i].KeyCtrlAscii;
				}
				else if(KeyboardState[SCAN_KEY_LALT]&0x80 || KeyboardState[SCAN_KEY_RALT]&0x80)
				{
					return KeyboardMap[i].KeyAltAscii;
				}
				else
				{
					return KeyboardMap[i].KeyAscii;
				}
			}
		}
	}
	for(i=0;SmallKeyboardMap_NumOn[i].KeyScanCode;i++)
	{
		if(SmallKeyboardMap_NumOn[i].KeyScanCode == ScanCode)
		{
			if(KeyboardState[NumLock]&0x80)
			{
				if(KeyboardState[SCAN_KEY_LSHIFT]&0x80 || KeyboardState[SCAN_KEY_RSHIFT]&0x80)	
				{
					return SmallKeyboardMap_NumOn[i].KeyShiftAscii;					
				}
				else if(KeyboardState[SCAN_KEY_LCTRL]&0x80 || KeyboardState[SCAN_KEY_RCTRL]&0x80)
				{
					return SmallKeyboardMap_NumOn[i].KeyCtrlAscii;
				}
				else if(KeyboardState[SCAN_KEY_LALT]&0x80 || KeyboardState[SCAN_KEY_RALT]&0x80)
				{
					return SmallKeyboardMap_NumOn[i].KeyAltAscii;
				}
				else
				{
					return SmallKeyboardMap_NumOn[i].KeyAscii;
				}
			}
			else
			{
				if(KeyboardState[SCAN_KEY_LSHIFT]&0x80 || KeyboardState[SCAN_KEY_RSHIFT]&0x80)	
				{
					return SmallKeyboardMap_NumOff[i].KeyShiftAscii;					
				}
				else if(KeyboardState[SCAN_KEY_LCTRL]&0x80 || KeyboardState[SCAN_KEY_RCTRL]&0x80)
				{
					return SmallKeyboardMap_NumOff[i].KeyCtrlAscii;
				}
				else if(KeyboardState[SCAN_KEY_LALT]&0x80 || KeyboardState[SCAN_KEY_RALT]&0x80)
				{
					return SmallKeyboardMap_NumOff[i].KeyAltAscii;
				}
				else
				{
					return SmallKeyboardMap_NumOff[i].KeyAscii;
				}
			}
		}
	}
	return 0;
}

/***********************************************************************************/
/******************************** 按键处理主程序 ***********************************/
/***********************************************************************************/
static void HandleKeyEven(unsigned char KState,unsigned char KValue)
{
	unsigned char Key;
	Key = ScanKey2GuiKey(KValue);
	if (Key)
	{
		GUI_StoreKeyMsg(Key, KState);			//uCGUI键盘接口函数
	}
	else
	{
		if ((Key = ScanCode2Ascii(KValue)) != 0)
		{
			GUI_StoreKeyMsg(Key, KState);		//uCGUI键盘接口函数
		}
	}
}


/***********************************************************************************/
/******************************** 串口1中断服务程序 ********************************/
/***********************************************************************************/
static void __irq Uart1_RxInt()
{
	do
	{
		FIFO_KeyBoard.FIFO_Data[FIFO_KeyBoard.FIFO_RxCnt] = RdURXH1();
		FIFO_KeyBoard.FIFO_RxCnt++;
		if(FIFO_KeyBoard.FIFO_RxCnt >= sizeof(FIFO_KeyBoard.FIFO_Data))
		break;
	}while( (rUFSTAT1&0xf) >0 );	//若RxD_FIFO计数器为0退出
	rI_ISPC = BIT_URXD1;			//清除中断标志
}

/*******************************************************************************/
/*利用定时器的定时功能,可以准确测得键盘一个时钟周期的时间;从而实现波特率的检测 */
/*******************************************************************************/
static unsigned int PS2_GetBps(void)
{
	float Value;
	unsigned int Bps;
	unsigned char data;
	rTCFG0 &= ~(0xff<<8);		//Timer2预分频->1;
	rTCFG1 &= ~(0x0f<<8);
	rTCFG1 |= (0x01<<8);		//Timer2分割器->1/4
	/*MCLK = 60M; Timer2CLK = 15MHz*/
	rTCON &= ~(0x0f<<12);		//Timer2: auto load->off;inverter->off;
	rINTMSK |= BIT_TIMER2;		//Timer2 interrupt disable;
	rTCNTB2 = 0xffff;			//Timer2 初值;
	rTCON |= Timer2_Update;		//装载初值;
	rTCON &= ~Timer2_Update;
	
	PS2_SendByte(0xFF);			//Send reset command;
	PS2_Delay1us(2);			//Delay 2uS
	rPCONC &= ~(0x0f<<24);		//GPC12 = input,GPC13 = input;
	rPDATC |= (0x03<<12);		//GPC12 = 1,GPC13 = 1;
	rPUPC  |= (0x03<<12); 		//GPC12\GPC13 Disable pull-up
	PS2_Delay1us(2);			//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;START BIT
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;BIT0
	
	rTCON |= Timer2_Start;			//开启定时器2,开始计时;
	
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;BIT1
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;BIT2
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;BIT3
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;BIT4
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;BIT5
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;BIT6
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK = 0;BIT7
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK = 1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK =0;PARITY BIT
	
	rTCON &= ~Timer2_Start;			//关闭定时器2,结束计时;总共计时8个周期
	
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK =1;
	PS2_Delay1us(2);				//Delay 2uS
	while(rPDATC & PS2_SCLK_BIT);	//Wait PS2_SCLK =0;STOP BIT
	PS2_Delay1us(2);				//Delay 2uS
	while(!(rPDATC & PS2_SCLK_BIT));//Wait PS2_SCLK =1;
	PS2_Delay1us(2);				//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xAA)
	{
		return (0);
	}
	
	Value = rTCNTO2;
	Value = 0xffff - Value;			//得到计数值;
	
	Bps = (2.0*MCLK)/Value;			//得到波特率;
	
	return (Bps);
}


static void Uart1_InterruptInit(void)
{
	pISR_URXD1 = (int)Uart1_RxInt;//串口1中断注册
}

/*********************************************************************************/
/********************************* 串口1初始化 ***********************************/
/*********************************************************************************/
static void Uart1_Init(int mclk,int baud)
{
    int i;
    rPCONC &= ~(0x0f<<24);
	rPCONC |= (0x0C<<24);		//GPC12 = input,GPC13 = RxD0;
	rPDATC |= (0x03<<12);		//GPC12 = 1,GPC13 = 1;
	rPUPC  |= (0x03<<12); 		//GPC12\GPC13 Disable pull-up
	rULCON1 = 0x23;      		//Normal,Odd parity,1 bit stop,8 bit data
	rUCON1 = 0x2c1;				//Rx int->Pulse,Time out int enable,Error int enable,Rx int mode
	rUFCON1 = 0x27;      		//ENable FIFO;RxD FIFO = 12 Bytes;
	rUMCON1 = 0x00;
    rUBRDIV1=( (int)(mclk/16./baud + 0.5) -1 );//设置波特率;   
    Uart1_InterruptInit();			//初始化串口1中断;
    memset(&FIFO_KeyBoard,0,sizeof(FIFO_KeyBoard));  //清软件缓冲区     
    for(i=0;i<100;i++);
}


/*********************************************************************************/
/******************************* PS2键盘初始化程序 *******************************/
/*********************************************************************************/
unsigned char KeyboardPS2_Init(void)
{
	unsigned char data;
	unsigned int PS2_Bps;
	
	memset(KeyboardState,0,sizeof(KeyboardState));//清除按键状态;
	
/*************************************************************************/
/*** 当键盘上电后发送0xAA字节数据;但当程序跑到这里时0xAA已经发送完毕. ****/
/*** 对于这种情况有两种解决方法:1.延迟键盘的上电时间(可以用一个IO口控 ****/
/*** 制键盘电源);2.不要去检测0xAA.                   				  ****/
/*************************************************************************/

/*	data = PS2_ReadByte();
	if(data != 0xAA)
	{
		return (0);
	}
	PS2_Delay1us(100);				//Delay 100uS*/
	
	if(!PS2_SendByte(0xFF))
	{
		return (0);
	}
	PS2_Delay1us(2);			//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xFA)
	{
		return (0);
	}
	PS2_Delay1us(2);			//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xAA)
	{
		return (0);
	}
	PS2_Delay1us(100);			//Delay 100uS		
	
	PS2_Bps = PS2_GetBps();		//检测键盘串行通信波特率,以实现不同型号鼠标自适应.	
	
	PS2_SendByte(0xF0);			//将键盘设置为第三套扫描码
	PS2_Delay1us(2);			//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xFA)
	{
		return (0);
	}
	PS2_SendByte(0x03);			//第三套扫描码
	PS2_Delay1us(2);			//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xFA)
	{
		return (0);
	}
	
	PS2_SendByte(0xFA);	//使能所有键的通码,断码和机打重复(设为第三套扫描码时默认断码禁止)
	PS2_Delay1us(2);				//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xFA)
	{
		return (0);
	}
	
	PS2_SendByte(0xED);				//开数字小键盘(NumLock)
	PS2_Delay1us(2);				//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xFA)
	{
		return (0);
	}
	PS2_SendByte(0x02);				//NumLock
	PS2_Delay1us(2);				//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xFA)
	{
		return (0);
	}
	KeyboardState[NumLock] = 0x80;	//键盘状态数组,NumLock字节Bit7置1;
		
	PS2_SendByte(0xF4);				//使能键盘
	PS2_Delay1us(2);				//Delay 2uS
	data = PS2_ReadByte();
	if(data != 0xFA)
	{
		return (0);
	}
	
	if(!PS2_Bps)
	{
		return (0);
	}
	Uart1_Init(MCLK,PS2_Bps);
	
	return (1);
}


void KeyBoard_Check(void)
{
	static unsigned char BreakCode = 0;	//当接收到0xF0置1,表示下一个数据为断码;
	unsigned char KeyState = 0;				//按键按下置1;按键松开为0;
	unsigned char KeyCode = 0;				//按键扫描码;
	unsigned char LockEven = 0;				//当CapsLock,NumLock,ScrollLock其一被按下,该变量置1;
	if(FIFO_KeyBoard.FIFO_RxCnt)
	{
		KeyCode = FIFO_KeyBoard.FIFO_Data[0];
		memmove(&FIFO_KeyBoard.FIFO_Data[0],&FIFO_KeyBoard.FIFO_Data[1],sizeof(FIFO_KeyBoard.FIFO_Data)-1);
		FIFO_KeyBoard.FIFO_Data[sizeof(FIFO_KeyBoard.FIFO_Data)-1] = 0;
		FIFO_KeyBoard.FIFO_RxCnt--;			
		if(KeyCode != 0xf0)			//1字节通码;
		{
			if(BreakCode == 0)		//通码;
			{
				KeyState = 1;
				if(KeyCode==CapsLock || KeyCode==NumLock || KeyCode==ScrollLock)
				{
					LockEven = 1;
					KeyboardState[KeyCode] = (~KeyboardState[KeyCode])&0x80;	//Bit7取反
				}
				else
				{
					KeyboardState[KeyCode] = 0x80;		//Bit7置1;
				}
			}
			else					//断码;
			{
				KeyState = 0;
				if(KeyCode!=CapsLock && KeyCode!=NumLock && KeyCode!=ScrollLock)
				{
					KeyboardState[KeyCode] = 0x00;		//Bit7置0;
				}
				BreakCode = 0;
			}
		
			
			if(KeyCode)
			{
				HandleKeyEven(KeyState,KeyCode);
			}
			
			if(LockEven)
			{
				OS_ENTER_CRITICAL();
				HandleLockEven();
				OS_EXIT_CRITICAL();
				LockEven = 0;
			}		
		}
		else
		{
			BreakCode = 1;
		}
	}
}

void KeyBoard_Task(void *pdata)
{	
	for(;;)
	{
		KeyBoard_Check();	
		OSTimeDly(30);
	}
}


⌨️ 快捷键说明

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