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

📄 main.c

📁 EINT外部中断实验-PS2键盘打字练习器
💻 C
字号:
/**********************************************************
 成都模数科技
 http://www.moshukeji.com
 文 件 名: main.c
 修改时间: 2007-09-14
 版 本 号: v1.00
 功能描述: 
***********************************************************/


#define IN_MAIN
#include "config.h"
#pragma import(__use_no_semihosting_swi)        //don't delete this line


#define  LED0  0x00000010
#define  LED1  0x00000020
#define  LED2  0x00000040
#define  SPEAKER  0x02000000
#define  PS2DATA 0x00004000  //P0.14
#define  PS2CLK 0x00008000  //P0.15
#define  KEY0  0x00000080

uint8 IntNum=0;//接收数据个数
uint8 KeyV;//PS/2数据
uint8 BF;

uint8 a[255],n,m;

uint8 Shift=0,Key_UP=0;
uint8 UnShifted[256];//没有按下Shift键时PS2对应的LCD码
uint8 Shifted[256];//按下Shift键时PS2对应的LCD码
uint8 CursorY=0;
/***************************************************************
** 函 数 名:void TableIni(void)
** 入口参数:无
** 出口参数:无
** 功能描述:初始化PS2扫描码和LCD对应表
*****************************************************************/
void TableIni(void)
{
	uint8 i;
	
	for(i=0;i<255;i++)
	{
		UnShifted[i]=0;
		Shifted[i]=0;
	}
	
	//没有Shift键
	UnShifted[0x1C]='a';
	UnShifted[0x32]='b';
	UnShifted[0x21]='c';
	UnShifted[0x23]='d';
	UnShifted[0x24]='e';
	UnShifted[0x2B]='f';
	UnShifted[0x34]='g';
	UnShifted[0x33]='h';
	UnShifted[0x43]='i';
	UnShifted[0x3B]='j';
	UnShifted[0x42]='k';
	UnShifted[0x4B]='l';
	UnShifted[0x3A]='m';
	UnShifted[0x31]='n';
	UnShifted[0x44]='o';
	UnShifted[0x4D]='p';
	UnShifted[0x15]='q';
	UnShifted[0x2D]='r';
	UnShifted[0x1B]='s';
	UnShifted[0x2C]='t';
	UnShifted[0x3C]='u';
	UnShifted[0x2A]='v';
	UnShifted[0x1D]='w';
	UnShifted[0x22]='x';
	UnShifted[0x35]='y';
	UnShifted[0x1A]='z';
	
	UnShifted[0x45]='0';
	UnShifted[0x16]='1';
	UnShifted[0x1E]='2';
	UnShifted[0x26]='3';
	UnShifted[0x25]='4';
	UnShifted[0x2E]='5';
	UnShifted[0x36]='6';
	UnShifted[0x3D]='7';
	UnShifted[0x3E]='8';
	UnShifted[0x46]='9';
	
	UnShifted[0x4E]='-';
	UnShifted[0x55]='=';
	UnShifted[0x4A]='/';
	UnShifted[0x41]=',';
	UnShifted[0x49]='.';
	UnShifted[0x29]=' ';
	
	
	//有Shift键
	Shifted[0x1C]='A';
	Shifted[0x32]='B';
	Shifted[0x21]='C';
	Shifted[0x23]='D';
	Shifted[0x24]='E';
	Shifted[0x2B]='F';
	Shifted[0x34]='G';
	Shifted[0x33]='H';
	Shifted[0x43]='I';
	Shifted[0x3B]='J';
	Shifted[0x42]='K';
	Shifted[0x4B]='L';
	Shifted[0x3A]='M';
	Shifted[0x31]='N';
	Shifted[0x44]='O';
	Shifted[0x4D]='P';
	Shifted[0x15]='Q';
	Shifted[0x2D]='R';
	Shifted[0x1B]='S';
	Shifted[0x2C]='T';
	Shifted[0x3C]='U';
	Shifted[0x2A]='V';
	Shifted[0x1D]='W';
	Shifted[0x22]='X';
	Shifted[0x35]='Y';
	Shifted[0x1A]='Z';
	
	Shifted[0x55]='+';
	Shifted[0x41]='<';
	Shifted[0x49]='>';
	Shifted[0x4A]='?';
	Shifted[0x45]=')';
	Shifted[0x46]='(';
	Shifted[0x16]='!';
	
	
}



/*********************************************************************************************************
** 函 数 名:void  IRQ_Exception(void)
** 入口参数:无
** 出口参数:无
** 功能描述:异常中断句柄,根据需要可以修改它,但不用删除
********************************************************************************************************/
void  IRQ_Exception(void)
{
}


void  Delay(uint32  dly)
{  
   for(; dly>0; dly--) ;      
}


/****************************************************************************
* 名称:void    IRQ_Eint2(void)
* 功能:EINT2中断,检测PS/2 clk时钟,读取PS/2 DATA数据
* 入口参数:
* 出口参数:
****************************************************************************/

 void    IRQ_Eint2(void) 
{

	
  	VICIntEnClr=0x00010000; 
 	IRQDisable();//关中断
  
   	if ((IntNum > 0) && (IntNum < 9))
	{
		KeyV = KeyV >> 1; //因键盘数据是低>>高,结合上一句所以右移一位
		if (IOPIN&PS2DATA) 
		{
			KeyV = KeyV | 0x80; //当键盘数据线为1 时为1 到最高位
		}
		else KeyV = KeyV & 0x7F;
	}
		
	IntNum++;
		
	if (IntNum > 10)	
	{				
		IntNum = 0; //当中断11次后表示一帧数据收完,清变量准备下一次接收
		BF = 1; //标识有字符输入完了		
	}
  
  while( (EXTINT&0x04)!=0 )		
   {  EXTINT = 0x04;				// 清除EINT1中断标志
   }
  
  VICIntEnable = 0x00010000;//
   VICVectAddr = 0;					// 清除内部中断优先级硬件中断标志,为了能再次产生中断	

	
}




/****************************************
** 函 数 名:uint8 Decode(uint8 ScanCode)
** 入口参数:PS/2扫描码
** 出口参数:LCD字符代码
** 功能描述:将PS/2键码翻译成LCD码
*******************************************/
uint8 Decode(uint8 ScanCode)
{
	uint8 LcdScan;//翻译成LCD字符代码
	
	switch(ScanCode)
	{
		case 0xF0 : // 当收到0xF0,Key_UP 置1 表示断码开始
			Key_UP = 1;
			LcdScan=0;
			break;

		case 0x12 : // 左 SHIFT
			if(!Key_UP) Shift = 1;
			else 
			{
				Shift = 0;
				Key_UP=0;
			}
			LcdScan=0;
			break;

		case 0x59 : // 右 SHIFT
			if(!Key_UP) Shift = 1;
			else 
			{
				Shift = 0;
				Key_UP=0;
			}
			LcdScan=0;
			break;
				
		case 0x5A : //	ENTER
			if(Key_UP==1)
			{
				LcdScan=0;
				Key_UP=0;
			}
			else
			{ 
				if(CursorY==0)CursorY=1;
				else CursorY=0;
				GotoXY(0,CursorY);
			}
			
			LcdScan=0;
			break;
			
		case 0x76 : //	ESC
			if(Key_UP==1)
			{
				
				Key_UP=0;
			}
			else
			{
				LCD_Write(LCD_COMMAND,0x1); //清显示
			
			}
			LcdScan=0;
			break;
			
			
		default:
			if(Key_UP==1) 
			{
				LcdScan=0;
				Key_UP=0;
			}
			
			else
			{
				if(!Shift)//没按下Shift
				{				
					LcdScan=UnShifted[ScanCode];			
				}
				else//按下Shift
				{
					LcdScan=Shifted[ScanCode];			
				}
			}
			break;
	
	}

	return LcdScan;

}


/****************************************
** 函 数 名:void DisLcd(uint8 LcdScan)
** 入口参数:LCD字符代码
** 出口参数:
** 功能描述:LCD显示
*******************************************/
void DisLcd(uint8 LcdScan)
{
	if(LcdScan!=0)	LCD_Write(LCD_DATA,LcdScan);

}



/*********************************************************************************************************
** 函 数 名:void Main(void)
** 入口参数:无
** 出口参数:无
** 功能描述:主函数
********************************************************************************************************/
void Main(void)
{
	
	
	uint8 temp8;
	

	//初始化PLL-----------------
    TargetInit(VPBDIV_DATA, PLLCFG_DATA, MAMTIM_DATA);      // 不能删除,初始化锁相环和内存加速设置
    while((PLLSTAT & (1 << 10)) == 0);   //反映PLL 的锁定状态。为0 时,PLL 未锁定;为1 时,PLL 锁定到指定的频率。       
    
    
   //用户程序-----------------------------------------
	
   IntNum=0;//接收数据个数
   Shift=0;
   Key_UP=0;
   CursorY=0;

   PINSEL0 = 0x4FFF00FF;		//p0.15 eint2  
   
 
   LCD_Initial();//初始化液晶
   
   
   EXTMODE =0;//电平触发
   EXTPOLAR=0;//0触发
   
   
   
   EXTINT = 0x07;//清中断标志
   
   VICIntSelect = 0x00000000; //分配为irq中断
   VICDefVectAddr = (int)IRQ_Eint2; // 设置中断服务程序地址
   VICIntEnable = 0x00010000;		
   

   TableIni();//初始化译码表
   KeyV=0;
   
   IRQEnable();//开中断
    
    while(1)
    {
          
    	
    	if(BF==1)
    	{    		    		
    		temp8=Decode(KeyV);//翻译PS/2扫描码
    		    		
    		DisLcd(temp8);//LCD显示
    		    		
    		BF=0;//复位标志
    		KeyV=0;//复位键值
    		
    		IRQEnable();//开中断
    	}	 
    	
    	
    	
    }

}



/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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