📄 ps2键盘(at45db011).c
字号:
WriteOneByteToBuffer(0x00,Key_Reciver_Buffer); //
Reciver_Ok=1;
}
if(Reciver_Ok==1)
{
//Reciver_Ok=1;
for(i=0;i<(k-6);i++)
{
if(TRead_PS2_Port(30)==1)
{
WDT_CONTR=0x37;
while(Send_1Byte_To_PS2_Port(0xfa)==0) {}
WriteNextByteToBuffer(Key_Reciver_Buffer);
}
else
{
Reciver_Ok=0;
break;
}
}
}
SPI45DB041_CS=1;
//校验
if(Reciver_Ok==1)
{
Reciver_Ok=0;
if(Reciver_Data_Check(0xeb)==1) Reciver_Ok=1;
}
//接收完后的存储处理
if(Reciver_Ok==1)
{
WriteBufferToPageWithErase(TEMP_DATA[1]); //回写
}
WDT_CONTR=0x37;
if(TEMP_DATA[0]==127) //如果是最后一个按键包,存储标志
{
ReadOnePageToBuffer(SYSTEM_PARA_PAGE_FLASH);
WriteOneByteToBuffer(KEYCODED_TABLE,0x0); //写已重定义标志
SPI45DB041_CS=1;
Keycoded_Table=0;
WriteBufferToPageWithErase(SYSTEM_PARA_PAGE_FLASH); //回写
}
}
}
if(Reciver_Ok==1) while(Send_1Byte_To_PS2_Port(0xe8)==0) {} //包接收正确发送0xe8
else while(Send_1Byte_To_PS2_Port(0xe7)==0) {} //包接收错误发送0xe7
}
//========================================数据包接收校验===========================================
bit Reciver_Data_Check(unsigned char CMDMode)
{
unsigned char i;
unsigned int Cheksum;
Cheksum=CMDMode;
if(Cheksum==0xea)
{
for(i=0;i<3;i++)
{
Cheksum=(Cheksum+TEMP_DATA[i]);
}
if((Cheksum/256==TEMP_DATA[3])&&(Cheksum%256==TEMP_DATA[4])) return(1);
else return(0);
}
else
{
for(i=0;i<4;i++)
{
Cheksum=(Cheksum+TEMP_DATA[i]);
}
for(i=0;i<(TEMP_DATA[0]-7);i++)
{
Cheksum=(Cheksum+ReadByteFromBuffer(i));
SPI45DB041_CS=1;
}
if((Cheksum/256)==ReadByteFromBuffer(TEMP_DATA[0]-7))
{
SPI45DB041_CS=1;
if((Cheksum%256)==ReadByteFromBuffer(TEMP_DATA[0]-7+1))
{
SPI45DB041_CS=1;
return(1);
}
else
{
SPI45DB041_CS=1;
return(0);
}
}
else
{
SPI45DB041_CS=1;
return(0);
}
}
}
//**************************************************************************************************
//定时器T0中断
/********************************************************\
* 函数名:定时器T0的中断函数
产生1mS定时
\********************************************************/
Dri() interrupt 1
{
/*
TH0=0xfd;
TL0=0xad; //定时50微秒 1T
*/
//*
//TH0=0xfc;
//TL0=0x6b; //11.0592MHz且12T时的定时1毫秒,已测试,勿更改!
//*/
TH0=0xf4;
TL0=0x00; //18.4322MHz且12T时的定时1毫秒,已测试,勿更改!
Ms_Timer++;
if(Ms_Timer>=1000)
{
Ms_Timer=0;
S_Timing++;
}
Send_1Byte_To_PS2_Timer++; //发送字节到PC的间隙定时器
Code_Reci_Data_Timing++; //
gWait_Process_Timer++; //用于写Flash时的自动退出
}
/********************************************************\
函数名:定时器T1的中断函数
\********************************************************/
Dir() interrupt 3
{
if(Buzz_Rs232_Flag==0)
{
TH1=0xfe; //在18.432MHz下的104uS定时
//TL1=0xD0;
TL1=0xe0;
if(Send_RS_Bit_Num!=0)
{
if((Send_RS_Data&0x0001)==0) LED25=0;
else LED25=1;
Send_RS_Data=Send_RS_Data>>1;
Send_RS_Bit_Num--;
}
}
else
{
/*
TH1=0xfe; //在18.432MHz下的长时正确蜂鸣
TL1=0x20;
*/
TH1=0xff; //在18.432MHz下的短时正确蜂鸣
TL1=0x20;
BUZZ=~BUZZ;
Buzz_Timer++;
}
}
//**************************************************************************************************
//串口中断,使用T1做波特率发生器,
/*
void Serial() interrupt 4
{
if(TI==1)
{
TI=0;
TIB=1;
}
if(RI==1)
{
RI=0;
}
}
*/
//===============================================
//延迟函数,经测试DelayVolu=1时延迟24.3uS
void DelayTime(unsigned int DelayVolu)
{
unsigned int i;
for(i=0;i<DelayVolu;i++) {}
}
//===============================================
//延迟40uS函数,已经测试,考虑到跳转,实际上大约37uS
void Delay_uS_Time(unsigned char Delay_Time)
{
unsigned char i;
//for(i=0;i<38;i++) {}
for(i=0;i<Delay_Time;i++) {}
}
//========================扫描键盘,这个函数放在T1定时器里处理=====================================
//= =
//=================================================================================================
void ScanKey(void)
{
unsigned char i;
unsigned char k;
if((Pro_Key_Step==0)&&(Send_1Byte_To_PS2_Timer>15))
{
if(((First_Key_Number[0]==0xff)&&(First_Key_Number[1]==0xff)&&(First_Key_Number[2]==0xff))
&&((Second_Key_Number[0]!=0xff)||(Second_Key_Number[0]!=0xff)||(Second_Key_Number[0]!=0xff)))
{
//
First_Key_Number[0]=Second_Key_Number[0];
Second_Key_Number[0]=0xff;
First_Key_Number[1]=Second_Key_Number[1];
Second_Key_Number[1]=0xff;
First_Key_Number[2]=Second_Key_Number[2];
Second_Key_Number[2]=0xff;
}
if(((Second_Key_Number[0]==0xff)&&(Second_Key_Number[1]==0xff)&&(Second_Key_Number[2]==0xff))
&&((Third_Key_Number[0]!=0xff)||(Third_Key_Number[0]!=0xff)||(Third_Key_Number[0]!=0xff)))
{
//
Second_Key_Number[0]=Third_Key_Number[0];
Third_Key_Number[0]=0xff;
Second_Key_Number[1]=Third_Key_Number[1];
Third_Key_Number[1]=0xff;
Second_Key_Number[2]=Third_Key_Number[2];
Third_Key_Number[2]=0xff;
}
k=0xef; //11101111
P0=(P0|0X3f); //读前送高
P2=(P2|0xff); //13列时
for(i=0;i<5;i++)
{
P1=(P1|0x1f); //先置位键盘扫描的列线
P1=(P1&k); //复位相应的测试列
nop();
Key_Scan_Row[i]=((P0&0x3f)|0xc0);
k=(k>>1);
k=(k|0x80); //右移后置位第8位
}
P1=(P1|0x1f); //先置位键盘扫描的列线
k=0x7f; //01111111
for(i=5;i<13;i++)
{
P2=(P2|0xff); //先置位键盘扫描的列线
P2=(P2&k); //复位相应的列
nop();
Key_Scan_Row[i]=((P0&0x3f)|0xc0);
k=(k>>1); //右移后置位第8位
k=(k|0x80); //右移后置位第8位
}
P2=(P2|0xff); //
Send_1Byte_To_PS2_Timer=0;
Pro_Key_Step=1;
}
}
//========================处理键盘=================================================================
//= =
//=================================================================================================
void Process_Key(void)
{
unsigned char i;
unsigned char j;
unsigned char k;
if(Pro_Key_Step==0) return;
if(Key_Send_Buffer_PlacPoint!=0) return;
if(Pro_Key_Step==1)
{
k=0;
for(i=0;i<13;i++) //判断按键数不得超过3个
{
for(j=0;j<8;j++)
{
if((Key_Scan_Row[i]&(0x01<<j))==0) k++; //如果有键按下
}
}
if(k>3)
{
Pro_Key_Step=0;
return; //有超过3个键同时按下则不处理
}
for(j=0;j<8;j++)
{
for(i=0;i<6;i++)
{
if((Key_Scan_Row[j]&(0x20>>i))==0)
{
Find_OnKey_Position(i+j*8); //寻找按下键的放置位置
}
else Find_OffKey_Position(i+j*8); //寻找释放键的放置位置
}
}
for(j=8;j<13;j++)
{
for(i=0;i<6;i++)
{
if((Key_Scan_Row[j]&(0x20>>i))==0)
{
Find_OnKey_Position(i+(j-8)*8+64); //寻找按下键的放置位置
}
else Find_OffKey_Position(i+(j-8)*8+64); //寻找释放键的放置位置
}
}
Pro_Key_Step=2;
}
//============================如果有第3个键,它的单击处理========================================
if(Pro_Key_Step==2)
{
//处理第1个按下的键
Pro_Key_Step=3;
if((Keycoded_Table==0)&&(First_Key_Number[0]==0xff)&&(First_Key_Number[1]<128)&&(First_Key_Number[2]<128))
{
Process_MakeCode(First_Key_Number[2]);
return;
}
}
if(Pro_Key_Step==3)
{
Pro_Key_Step=4;
if((Keycoded_Table==0)&&(Second_Key_Number[0]==0xff)&&(Second_Key_Number[1]<128)&&(Second_Key_Number[2]<128))
{
Process_MakeCode(Second_Key_Number[2]);
return;
}
}
if(Pro_Key_Step==4)
{
Pro_Key_Step=5;
if((Keycoded_Table==0)&&(Third_Key_Number[0]==0xff)&&(Third_Key_Number[1]<128)&&(Third_Key_Number[2]<128))
{
Process_MakeCode(Third_Key_Number[2]);
return;
}
}
if(Pro_Key_Step==5)
{
Pro_Key_Step=6;
if((Keycoded_Table==0)&&(First_Key_Number[0]<128)&&(First_Key_Number[1]==0xff)&&(First_Key_Number[2]==0xff))
{
Process_BreakCode(First_Key_Number[0]); //有定义且是单键时发送断码
First_Key_Number[0]=0xff;
return;
}
}
if(Pro_Key_Step==6)
{
//如果有第2个键,处理它的断码
Pro_Key_Step=7;
if((Keycoded_Table==0)&&(Second_Key_Number[0]<128)&&(Second_Key_Number[1]==0xff)&&(Second_Key_Number[2]==0xff))
{
Process_BreakCode(Second_Key_Number[0]); //有定义且是单键时发送断码
Second_Key_Number[0]=0xff;
return;
}
}
if(Pro_Key_Step==7)
{
//如果有第3个键,处理它的断码
Pro_Key_Step=0;
if((Keycoded_Table==0)&&(Third_Key_Number[0]<128)&&(Third_Key_Number[1]==0xff)&&(Third_Key_Number[2]==0xff))
{
Process_BreakCode(Third_Key_Number[0]); //有定义且是单键时发送断码
Third_Key_Number[0]=0xff;
return;
}
}
}
//======================================通码的处理=============================================
void Process_MakeCode(unsigned char KeyNumber)
{
unsigned char i;
i=Load_TKey_Define(KeyNumber);
if((Beep_Enable==1)&&((Nop_Key_Flag==1)||(Beep_Nop_Key==1))) Drived_Buzz(20);
switch(i)
{
case 0x00: //空键不发送
{
break;
}
case 0x01: //单字节单键模式通码循环发送
{
Key_Send_Buffer_PlacPoint=1;
//while(Send_1Byte_To_PS2_Port(ReadByteFromBuffer(0x00))==0) {} //断码首字节
//SPI45DB041_CS=1;
break;
}
case 0x02: //双字节单键模式通码循环发送
{
Key_Send_Buffer_PlacPoint=2;
//while(Send_1Byte_To_PS2_Port(ReadByteFromBuffer(0x00))==0) {} //断码首字节
//while(Send_1Byte_To_PS2_Port(ReadNextFromBuffer())==0) {} //通码下1个字节
//SPI45DB041_CS=1;
break;
}
case 0x03: //
{
Key_Send_Buffer_PlacPoint=4;
break;
}
default:
{
break;
}
}
}
//======================================断码的处理=============================================
void Process_BreakCode(unsigned char KeyNumber)
{
unsigned char i;
i=Load_TKey_Define(KeyNumber);
switch(i)
{
case 0x00:
{
break;
}
case 0x01:
{
while(Send_1Byte_To_PS2_Port(0xf0)==0) {} //断码首字节
while(Send_1Byte_To_PS2_Port(ReadByteFromBuffer(0x00))==0) {} //断码首字节
SPI45DB041_CS=1;
break;
}
case 0x02: //双字节单键模式断码直接发送
{
while(Send_1Byte_To_PS2_Port(ReadByteFromBuffer(0x00))==0) {} //通码首字节
while(Send_1Byte_To_PS2_Port(0xf0)==0) {} //断码字节
while(Send_1Byte_To_PS2_Port(ReadNextFromBuffer())==0) {} //通码下1个字节
SPI45DB041_CS=1;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -