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

📄 ps2_key.c

📁 本库函数实现了C8051F020下20键PS2键盘的驱动 代码非常稳定 同时很容易移植到其它处理器中使用 接口方便 代码规范简洁
💻 C
字号:
/****************************************Copyright (c)***************************************
**
/*-----------------------------------------文件信息------------------------------------------  
**文 件 名:PS2_Key.C 
**创 建 人:王胜
**日    期:2007年3月26日  
**描    述:
**         本库函数实现了20键PS2键盘键值的解码和读取,将PS2CLOCK与P3.6连接,通过将外部中断6
**         设置为下降沿中断模式来捕抓PS2DATA中数据,从而实现PS2键值的解码,将解码得到的键值
**		   通过全局变量PS2KeyVal带出以供外部使用,同时设定按键标志,将按键标志通过全局位变量
**         PS2Key_sign供外部使用(PS2Key_sign=0无键按下,PS2Key_sign=1有键按下,键值存放在键
**		   值变量PS2KeyVal中),同时将键值读取时的按键状态通过全局变量PS2KeyMessage带出供外部
**	       使用;
**         将这两个文件复制到您的工程目录下,在主函数中使用头文件包含语句#include "PS2_Key.h" 		          
**         同时在初始化话函数CPU_Init.C中使用头文件包含语句#include "PS2_Key.h"将中断6初始化
**         函数加入到系统初始化中即可;本C文件包括两个函数:
**
**         INT6初始化函数:
**         void INT6_Init(void);
**
**         PS2键盘中断处理函数:
**         void PS2_ISR (void) interrupt 18;
**
**         供外部使用的全局变量:
**         bit  PS2Key_sign=0;            //按键标志
**         unsigned char PS2KeyVal=0;     //按键键值寄存变量
**         unsigned char PS2KeyMessage=0; //按键键值状态变量,数值定义如下: 
**                                          0x80--键值读取时按键已释放
**                                          0x40--按键为机打按键,机打模式下通码被不断发送
**                                          0x20--按键为多键按下模式,取最后一个按下键键值 
** 
**         外部硬件资源信息:
**         sbit PS2DATA	 =  P3^1;
**         sbit PS2CLOCK =  P3^6;    
**         外部中断6 INT6-> P3^6; 
********************************************************************************************/

#include <C8051f020.h>
#include "PS2_Key.h"

#define  DEFPS2PUSHCOUNT 0x0A     //长按时间

bit  PS2Key_sign=0;               //按键标志

struct Keyboard_Information
{	
	unsigned char PS2KeyCount;    //脉冲计数
	unsigned char PS2KeyExtFlage; //扩展键标志
	unsigned char PS2KeyTemp;     //键码移位记录器
	unsigned char PS2KeyPopError; //出错类别
	unsigned char PS2KeyPushCount;//长压键计数器
}PS2Buffers={0,0,0,0,0};

unsigned char PS2KeyVal=0;    //按键键值寄存变量
unsigned char PS2KeyMessage=0;/*按键键值状态变量,数值定义如下: 
                                0x80--键值读取时按键已释放
                                0x40--按键为机打按键,机打模式下通码被不断发送
                                0x20--按键为多键按下模式,取最后一个按下键键值*/  
          
//20键PS2小键盘键码表(实际按键数为18个)
unsigned  char code PS2TAB[18][2] = 
{			
	0x70,'0',	//0
	0x69,'1',	//1
	0x72,'2',	//2
	0x7A,'3',	//3
	0x6B,'4',	//4
	0x73,'5',	//5
	0x74,'6',	//6
	0x6C,'7',   //7
	0x75,'8',	//8
	0x7D,'9',	//9
	0x79,'+',	//加
	0x7B,'-',	//减
	0x7C,'*',	//乘
	0x4A,'/',	//除
	0x77,'N',	//NumberLock
	0x66,'B',	//Bksp
	0x71,'.',	//Del.
	0x5A,'E',	//Enter
};

/*****************************************************************************************************
**函数名称:INT6_Init()
**函数功能:外部中断6初始化,将外部中断设置为下降沿中断;
**入口参数:无
**出口参数:无
*****************************************************************************************************/
void INT6_Init(void)//中断6初始化
{
    P3IF &= ~0x40;//清除INT6标志,中断6为下降沿中断方式
    EIE2 |= 0x10; //使能外部中断6
}

/******************************************************************************************************
**函数名称:PS2_ISR()
**函数功能:PS2键盘中断处理,将处理得到的键值存放在外部变量PS2KeyVal中,按键状态存入变量PS2KeyMessage中;
**入口参数:无
**出口参数:无
******************************************************************************************************/
void PS2_ISR (void) interrupt 18 //PS2键盘中断处理函数
{
    unsigned char i=0;
    unsigned char key=0;//键值暂存变量

    P3IF &= ~0x40;//清除中断6标志位

  	if (PS2Buffers.PS2KeyCount ==0)
	{				//PS2起始位测试
    	if (!PS2CLOCK && !PS2DATA)
		{			//低电平是起始位
      		if (PS2Buffers.PS2KeyExtFlage !=0xF0)
			{
        		PS2Buffers.PS2KeyTemp =0;
        		PS2Buffers.PS2KeyExtFlage =0;
        		PS2Buffers.PS2KeyPopError =0;
      		}
      		PS2Buffers.PS2KeyCount++;			//脉冲计数
    	}
    	else PS2Buffers.PS2KeyPopError =0xEB;	//置键起始位错误号0xeb
  	}
  	else if (PS2Buffers.PS2KeyCount <9)
	{				//PS2数据位
    	key =PS2Buffers.PS2KeyTemp;			//取键盘缓冲区移位数据
    	key >>=1;
    	if (PS2DATA) key |=0x80;
    	PS2Buffers.PS2KeyTemp =key;
    	PS2Buffers.PS2KeyCount++;			//脉冲计数
  	}
  	else if (PS2Buffers.PS2KeyCount ==9)
	{			    //PS2数据奇校验
    	ACC = PS2Buffers.PS2KeyTemp;			//取键盘缓冲区移位数据(C51取偶校验位)
    	if (P != PS2DATA) PS2Buffers.PS2KeyCount++;	//奇校验正确,脉冲计数
    	else
		{//PSW.0为奇偶标志位,当ACC中个位和为奇数时该位为1
     	 	PS2Buffers.PS2KeyPopError =0xEC;	//置键奇校验位错误号0xec
      		PS2Buffers.PS2KeyCount =0;			//脉冲计数归零
   	 	}
  	}
  	else if (PS2Buffers.PS2KeyCount ==10)
	{			//停止位
    	key = PS2Buffers.PS2KeyTemp;	//取键盘缓冲区移位数据
		PS2Buffers.PS2KeyCount =0;		//脉冲计数归零
    	if (PS2DATA)
		{	   //高电平是停止位
      		if (key ==0xE0)	//本次是扩展键
			{PS2Buffers.PS2KeyExtFlage =0xE0;}//置扩展键标志(小键盘只有回车键)      		
      		else if (key ==0xF0)//本次是键断码,键释放
			{PS2Buffers.PS2KeyExtFlage =0xF0;}//置键释放标志      
	      		else
				{	 //本次必为键值
		        	if ((key ==0xAA) || (key ==0xFA)) PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零																			
		        	else
					{
		            	PS2CLOCK =0;//阻止PS2键盘立即回送数据
		          		PS2Buffers.PS2KeyPopError =0xAA;//出错码
		          		for (i =0; i <18; i++)
					    {
			            	if (key ==(PS2TAB[i][0])) //搜索匹配按键
							{			
			              		key =PS2TAB[i][1];
			              		if (PS2Buffers.PS2KeyExtFlage ==0xF0)//键释放
								{
			                		PS2Buffers.PS2KeyPushCount =0;//长压键计数器清零
			                		PS2KeyMessage =0x80;//当前键值由释放按键得到
								}                            
			              		else
								{
				                	if (key !=PS2KeyVal)
									{	//换了一个键
				                  		PS2Buffers.PS2KeyPushCount =0;//长压键计数器清零
				                  		PS2KeyMessage =0x20;//当前键值由多键按下,最后一个按键得到
									}
				                	else
									{	//未换键,机打模式
				                        PS2Buffers.PS2KeyPushCount++;		//长压键计数器计数
				                  		if (PS2Buffers.PS2KeyPushCount >DEFPS2PUSHCOUNT)
										{				 //长压时间到
				                            PS2KeyMessage =0x40; //存入当前键值并执行命令
				                            PS2Buffers.PS2KeyPushCount =0;	//长压键计数器清零	
									    }
				                    }
			              		}
			              		PS2KeyVal =key;	//存入当前键值
								PS2Key_sign =1;
			              		PS2Buffers.PS2KeyTemp =0;	    //键码移位记录器
			              		PS2Buffers.PS2KeyExtFlage =0;	//扩展键标志
			              		PS2Buffers.PS2KeyPopError =0;	//键释放标志或出错码
			              		break;
			                }
		          	    }//for循环出口
          	            if (PS2Buffers.PS2KeyPopError) 
						    PS2Buffers.PS2KeyPushCount =0; //长压键计数器清零
          	            PS2CLOCK =1;  //释放PS2时钟总线
                    }
               }
        }//得到停止位,完成键值处理
        else PS2Buffers.PS2KeyPopError =0xed;//置停止位错误号0xed
    }
    else PS2Buffers.PS2KeyCount =0;//PS2键盘出错
}

⌨️ 快捷键说明

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