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

📄 ps2键盘(at45db011).c

📁 键盘针对78键的键盘开发的针对PS2的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
				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 + -