📄 keyboardps2_44b0.c
字号:
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 + -