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

📄 main.c

📁 PS2 读取键盘数具,非常好的一个软件PCB
💻 C
字号:
#include <PIC.h>
#include "..\include\PIC_SET.H"
#include "..\include\ps2.h"

/******************************************************************/
/*****************************isr program**************************/
/******************************************************************/
void interrupt isr(void)
{
////////////////////////////////////////////////////interrupt start  
//###################################################int0 interrupt start
	unsigned char keyval;	
	if(INT0IE&&INT0IF)//键盘数据读取中断
	{
		keyval = ReadPs2();	//读取键盘数据
		if(keyval != 0)
		{
			 keybuff[keyinpt] = keyval;
			 keyinpt++;
			 keyinpt&= 0x3f;
		}
		while((!KEY_CLK)||(!KEY_DAT));	//等待PS2总线恢复
		asm("movf _PORTA,w");
	 	INT0IF = 0;
   }
//###################################################int0 interrupt over
   if(TMR0IE&&TMR0IF) //定时中断
   {
//##################################################timer0 interrupt start
      TMR0IF=0;TMR0=0x87;                 //1ms
      id_1ms=1;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@LED_KEYBORADMOUSE 处理
      LED_KEYBORADMOUSE_DIR=0;KEYBORADMOUSEVCC_DIR=0;KEYBORADMOUSE_DIR=1;
      KEYBORADMOUSEVCC=1;
      led_keyboradmouse_count++;

      if(KEYBORADMOUSE)
         id_led_keyboradmouse=1;   //KEYBORAD
      else 
         id_led_keyboradmouse=0;   //MOUSE

      switch (id_led_keyboradmouse)
      {
         case 0:
              if(led_keyboradmouse_count<=250)       //0.25秒
                 LED_KEYBORADMOUSE=0;
              else if(led_keyboradmouse_count<=500)  //0.5秒
                 LED_KEYBORADMOUSE=1;
              else led_keyboradmouse_count=0x00;
              break;
         case 1:
         	  if(led_keyboradmouse_count<=2000)       //2秒
                 LED_KEYBORADMOUSE=0;
              else if(led_keyboradmouse_count<=4000)  //4秒
                 LED_KEYBORADMOUSE=1;
              else led_keyboradmouse_count=0x00;
              break;
      }
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@LED_STAUTS 处理
      led_status_count++;LED_STAUTS_DIR=0;
      switch (led_status)
      {
         case 0: //data
              if(led_status_count<=250)       //0.25秒
                 LED_STAUTS=0;
              else if(led_status_count<=500)  //0.5秒
                 LED_STAUTS=1;
              else led_status_count=0x00;
              break;
         case 1: //reset
         	  if(led_status_count<=2000)       //2秒
                 LED_STAUTS=0;
              else if(led_status_count<=4000)  //4秒
                 LED_STAUTS=1;
              else led_status_count=0x00;
              break;
         case 2: //clr eeprom
              if(led_status_count<=4000)        //4秒
                 LED_STAUTS=0;
              else if(led_status_count<=8000)   //8秒
                 LED_STAUTS=1;
              else led_status_count=0x00;
              break;
         case 3: //no 
              LED_STAUTS=1;
              break;
         default: LED_STAUTS=0;
      }
//###################################################timer0 interrupt over
   }
////////////////////////////////////////////////////interrupt over  
}

//******************************************************************
//***********************main program 主程序************************
//******************************************************************
main()
{
//##################################################初始化开始
     WDTCON=0x00;
//..............................清除RAM
     STATUS=0x00;FSR=0x20;
     while(FSR!=0x80)
    	{INDF=0x00;FSR++;}

     STATUS=0x00;STATUS=STATUS|0x20;FSR=0xa0;
     while(FSR!=0xf0)
    	{INDF=0x00;FSR++;}

     STATUS=0x00;STATUS=STATUS|0xc0;FSR=0x10;
     while(FSR!=0x70)
    	{INDF=0x00;FSR++;}

     STATUS=0x00;STATUS=STATUS|0xe0;FSR=0x90;
     while(FSR!=0xf0)
    	{INDF=0x00;FSR++;}
//..............................特殊寄存器赋值  
     OPTION=0x02;         //1:8 timer0
     CMCON=0x0ff;         //COMPARATOR OFF
     T1CON=0x00;          //timer1 OFF 
     INTCON=0x00;
     TMR0=0x87;                                     //1ms 0x87
     INT0IE=1;TMR0IE=1;GIE=1;
//..............................RAM赋值 
	 keyinpt = 0;
	 keyoutpt = 0;
     led_status=0x03;
//..............................外设初始化
	 Ps2PortInit();
//..............................EEPROM数据结构初始化
	 eepromaddrpt = (unsigned char)(EE_ReadByte(STARTADDR));
	 DxmS();
//##################################################初始化完毕	 
	 while(1)
	 {
//##################################################主程序开始
//===============================================按键扫描
        KeyScan();    
//===============================================按键处理        
        KeyProc(); 
//按键处理
		 ButtonHandle(); 
//===============================================键盘数据检测记录
		 if(keyinpt!= keyoutpt)
		 {
			 //记录数据
			 do
			 {
				 EE_WriteByte (eepromaddrpt, keybuff[keyoutpt]);
                 asm("nop");
                 eepromaddrpt++;
				 if(eepromaddrpt==0x00)
					{eepromaddrpt = DEFADDR;}

                 
				 keyoutpt++;
				 keyoutpt&= 0x3f;
			 }while(keyinpt!= keyoutpt);
			 //记录新指针
			 EE_WriteByte(STARTADDR, (unsigned char)eepromaddrpt);
		 }	
//#######################################################主程序完毕
	 }
}

//*****************************************************************
//*******************************sub program***********************
//*****************************************************************
//************************************
//名称:DxmS()
//功能:延迟xmS
//入口:无
//出口:无
//说明:
//************************************
void DxmS(void)
{
	 unsigned int cnt;
	 for(cnt=0xffff; cnt>0; cnt--)
		{;}
}

//************************************
//名称:EE_ReadByte()
//功能:读取指定地址字节的数据
//入口:操作数据地址
//出口:数据
//说明:
//************************************
unsigned char EE_ReadByte (unsigned char addr)
{
	WREN=0;
    EEADR=addr;EEPGD=0;RD=1;
   	while(RD)
      	asm("nop");
   	return EEDATA;
}

//************************************
//名称:EE_WriteByte()
//功能:向指定地址写入一字节数据
//入口:操作数据地址。操作数据
//出口:无
//说明:
//************************************
void EE_WriteByte (unsigned char addr, unsigned char data)
{
	gie_ram=GIE;
    GIE=0;
    while(WR)
	   asm("nop");
    EEADR=addr;EEDATA=data;
    EEPGD=0;WREN=1;EECON2=0X55;EECON2=0XAA;WR=1;
    while(WR)
	   asm("nop");
    GIE=gie_ram;
    asm("nop");
    asm("nop");
    asm("nop");
    WREN=0;
}

//************************************
//名称:D10mS()
//功能:延迟10mS
//入口:无
//出口:无
//说明:
//************************************
void D10mS(void)
{
	 unsigned int cnt;
	 for(cnt=5200; cnt>0; cnt--)
		{;}
}

//******************************************
//按键码转换函数()
//作用:将数据转成标准按键码
//入口:被转换数据
//出口:转换后的按键码
//******************************************
unsigned char KeyCode(unsigned char data)
{
	 unsigned char temp;
	 data&=0x0f;
	 switch(data)
	 {
		 case 0: 	temp = 0x45; break;
		 case 1: 	temp = 0x16; break;
		 case 2: 	temp = 0x1e; break;
		 case 3: 	temp = 0x26; break;
		 case 4: 	temp = 0x25; break;
		 case 5: 	temp = 0x2e; break;
		 case 6: 	temp = 0x36; break;
		 case 7: 	temp = 0x3d; break;
		 case 8: 	temp = 0x3e; break;
		 case 9: 	temp = 0x46; break;
		 case 10: 	temp = 0x1c; break;
		 case 11: 	temp = 0x32; break;
		 case 12:	temp = 0x21; break;
		 case 13: 	temp = 0x23; break;
		 case 14:	temp = 0x24; break;
		 case 15: 	temp = 0x2b; break;
		 default:	temp = 0x22;
	 }
	 return(temp);
}

//******************************************
//按键处理函数;ButtonHandle()
//作用:按键处理函数;
//入口:无;
//出口:无;
//*******************************************
void ButtonHandle(void)
{
	unsigned int cnt;
	unsigned int bakadd;
	unsigned char keyval;
    BUTTON_DIR = 1;BUTGND_DIR=0;BUTVCC_DIR=0;
    BUTGND=0;BUTVCC=1;
	D10mS();	//按键消抖

	if(!BUTTON)
	{
		for(cnt=65000; cnt>0 ;cnt--)
		{
			 if(BUTTON)
				{break;}
		}

		if(cnt!=0)
		{//短按键,发送存储数据			 
			for(cnt=50000; cnt>0 ;cnt--)
			{
				 if(!BUTTON)
					{break;}
			}

			if(cnt!=0)
			{//双击按键	 
				if(eepromaddrpt > DEFADDR)
				{
					//发送数据
					bakadd = eepromaddrpt;
					cnt = DEFADDR;
					do
					{
						 keyval = EE_ReadByte(cnt);
						 SendPs2(keyval);
						 cnt++;
						 if(cnt & 0x0001)
							{}
						 else
							{}
					}while(eepromaddrpt!=cnt);
					eepromaddrpt = bakadd;
				}
				else
				{
					 for(cnt=10; cnt>0; cnt--)
						{D10mS();}
				}
			}
		    else
		    {//单次按键
                 led_status=0x01;
				//发送存储器大小(24C512为0x00)
				 SendPs2(KeyCode(0));
				 SendPs2(0xf0);
				 SendPs2(KeyCode(0));
				 SendPs2(KeyCode(0));
				 SendPs2(0xf0);
				 SendPs2(KeyCode(0));

				//发送地址字符
				 SendPs2(KeyCode((unsigned char)((eepromaddrpt>>12)&0x000f)));
				 SendPs2(0xf0);	
				 SendPs2(KeyCode((unsigned char)((eepromaddrpt>>12)&0x000f)));

				 SendPs2(KeyCode((unsigned char)((eepromaddrpt>>8)&0x000f)));
				 SendPs2(0xf0);	
				 SendPs2(KeyCode((unsigned char)((eepromaddrpt>>8)&0x000f)));

				 SendPs2(KeyCode((unsigned char)((eepromaddrpt>>4)&0x000f)));
				 SendPs2(0xf0);	
				 SendPs2(KeyCode((unsigned char)((eepromaddrpt>>4)&0x000f)));

				 SendPs2(KeyCode((unsigned char)(eepromaddrpt&0x000f)));
				 SendPs2(0xf0);
				 SendPs2(KeyCode((unsigned char)(eepromaddrpt&0x000f)));	

				//发送字符		 
				 if(eepromaddrpt> DEFADDR)
				 {
						//发送数据
					 	bakadd = eepromaddrpt;
					 	do
						{
						 	eepromaddrpt--;
						 	keyval = EE_ReadByte(eepromaddrpt);
						 	SendPs2(KeyCode(keyval>>4));
						 	SendPs2(0xf0);
						 	SendPs2(KeyCode(keyval)>>4);
						 	SendPs2(KeyCode(keyval));
						 	SendPs2(0xf0);
						 	SendPs2(KeyCode(keyval));
						 	if(eepromaddrpt & 0x0001)
								{}
						 	else
								{}
						}while(eepromaddrpt!= DEFADDR);
					 	eepromaddrpt = bakadd;
				 }
				 else
				 {
					 for(cnt=10; cnt>0; cnt--)
						{D10mS();}
				 }
                 led_status=0x03;
			}
		 }
		 else
		 {//长按键,清空存储数据
                led_status=0x02;
			 	//存数据指针初始化
			 	EE_WriteByte (STARTADDR, (unsigned char)DEFADDR);
			 	for(cnt=10; cnt>0; cnt--)
					{D10mS();}
			 	//初始化操作指针
			 	eepromaddrpt = DEFADDR;
                led_status=0x03;
		}
	}

	while(!BUTTON);	//等待按键释放
}

//=============================================================
//  scan key扫描按键
//	IN:NONE
//	OUT:have_key:1有键按下;0:无新的按键
//=============================================================
void KeyScan(void)
{
    BUTTON_DIR = 1;BUTGND_DIR=0;BUTVCC_DIR=0;
    BUTGND=0;BUTVCC=1;
    
    if(BUTTON==0)  
	    i_check_code=1;  
    else
        i_check_code=0;                
	
    if(have_key==0)
    {
        if(i_check_code)
        {
            if(id_1ms)
            {
                id_1ms=0;
                key_count++;
	   			if(key_count>=800)     //3秒
	   				{key_count=0x00;have_key=1;}
            }
        }
        else key_count=0x00;
    }
    else
    {
        if(i_check_code==0)
            have_key=0;       
    }	
}

//=============================================================
//  key  proc 按键处理
//	IN: none
//	OUT:none
//=============================================================
void KeyProc(void)
{
//...............................................key power

		
}

⌨️ 快捷键说明

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