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

📄 ps2_bin.c

📁 ps2的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/
//main.c
//功能:从PS/2口接受键盘信息,解码成ACSII码,通过UART发送出去,并且控制键盘
//修改:
//时间:2006-7-8
//作者:R.S.J
/*****************************************************************************/

#include <reg51.h>
#include <intrins.h>

//#include "PS2.h"

#define EINT (EA = 1)
#define DINT (EA = 0)

#define MAXBUFFER 15

#define WAITFORKEYBOARDPULSE  while(!scl); while(scl)

#define COMMAND_RESET     0xFF  //命令:复位键盘
#define COMMAND_READID    0xF2 //命令:读键盘ID
#define COMMAND_SETSTATUS 0xED //命令:设置状态CapsLock,NumLock,ScrollLock
#define COMMAND_SETRATE   0xF3 //命令:设置速率,延时
#define COMMAND_ENABLE    0xF4 //命令:使能键盘
#define CAPSLOCK_EN       0x04  //使能CapsLock  灯
#define NUMLOCK_EN        0x02  //使能NumLock   灯
#define SCROLLLOCK_EN     0x01  //使能ScrollLock灯
#define CAPSLOCK_DIS      0x03  //关闭CapsLock灯
#define NUMLOCK_DIS       0x05  //关闭NumLock灯
#define SCROLLLOCK_DIS    0x06 //关闭ScrollLock灯
#define DISALL            0x00  //关闭所有灯


#define CODE_POST     0xAA  //键盘上电自检成功 Power On Self Test
#define CODE_ACK      0xFA  //键盘应答码
#define CODE_ECHO     0xEE  //键盘的回应码
#define CODE_BREAK    0xF0  //断码
#define CODE_EXTEND   0xE0  //扩展码
#define CODE_PAUSE    0xE1  //Pause键起始码 E1+14+77/E1+F0+14/F0+77
#define CODE_LSHIFT   0x12  //左Shift键通码
#define CODE_RSHIFT   0x59  //右Shift键通码
#define CODE_LCTRL    0x14  //左CTRL键通码
#define CODE_RCTRL    0x14  //右CTRL键通码 0xE0,0x14
#define CODE_LALT     0x11  //左ALT键通码
#define CODE_RALT     0x11  //右ALT键通码  0xE0,0x11
#define CODE_NUMLOCK  0x77  //NumLock键
#define CODE_CAPSLOCK 0x58  //CapsLock键
#define CODE_SCROLLLOCK 0x7E//SCROLLLOCK键
#define nodefinedkey   0x00//

#define OUTPORT P2    //电平输出口定义

/* 函数定义 */
unsigned char ReadPS2(); //读PS2端口获取PS2发送的数据
void KeyScan();          //获得键值
void KeyTransmit();      //发送键值
void Order(unsigned char);            //向键盘发送命令
//void KickDog();          //喂狗
void Delay(unsigned char);
void LedLock(unsigned char);
/* 变量定义 */
sbit sda = P3^4;     //P3.7做为数据线//^^^^^^^^^^^^^^^^^^^^^^
sbit scl = P3^2;     //P3.2做为时钟线
sbit key_sw = P1^1;  //P1.2作为键盘电源开关

int  i;
unsigned char KeyCodeBuff[MAXBUFFER+1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//键值缓存
unsigned char KeyCodeSum      = 0; //键码数
bit KeyFlag                   = 0; //有键标志
bit KeyUpFlag                 = 0; //键弹起标志
bit KeyExtendFlag             = 0; //扩展键标志
bit KeyLedLockFlag            = 0; //三个Led键被按下的标志
bit KeyBoardConnectFlag       = 0; //键盘连接标志
bit KeyPauseFlag              = 0; //Pause键标志
bit KeyMakeCodeFlag           = 0; //键盘发送通码标志
/*
bit CapsLockFlag              = 0; //CapsLock标志
bit NumLockFlag               = 0; //NumLock标志
bit ScrollLockFlag            = 0; //ScrollLock标志
*/
unsigned char E1flag                    = 0;//我家的
unsigned char E0flag                    = 0;//
///////////////////////////////////////////
unsigned char KeyIDLo   = 0; //键盘ID低字节
unsigned char KeyIDHi   = 0; //键盘ID高字节
unsigned char LedStatus = 0; //NumLock,CapsLock,ScrollLock灯控制
unsigned char dat[6]= 0x00;  // 输出数据缓存
unsigned char sum=0x00;
/*********************************************************/
//函数:main()
//功能:主函数
//输入:无
//输出:无
//描述:
/*********************************************************/
unsigned char code keyval[]=
{
0x76,0x05,0x06,0x04,0x0c,0x03,0x0b,0x83,0x0a,0x01,0x09,0x78,0x07,
0x0e,0x16,0x1e,0x26,0x25,0x2e,0x36,0x3d,0x3e,0x46,0x45,0x4e,0x55,
0x5d,0x66,0x0d,0x15,0x1d,0x24,0x2d,0x2c,0x35,0x3c,0x43,0x44,0x4d,
0x54,0x5b,0x58,0x1c,0x1b,0x23,0x2b,0x34,0x33,0x3b,0x42,0x4b,0x4c,
0x52,0x5a,0x12,0x1a,0x22,0x21,0x2a,0x32,0x31,0x3a,0x41,0x49,0x4a,
0x59,0x14,0x11,0x29,0x7e,0x77,0x7c,0x7b,0x6c,0x75,0x7d,0x6b,0x73,
0x74,0x69,0x72,0x7a,0x70,0x71,0x69,0x79,

};
unsigned char code e0_keyval[]=
{0x11,0x1F,0x14,0x12,0x70,0x6c,0x7d,0x71,0x69,0x7a,0x4a,0x5a,0x75,0x6b,0x72,0x74,0x5e,0x3f,0x37,0x7c,0x27,0x2f};
unsigned char code pausekey[]={0xe1,0x14};
//unsigned char code pausekey[]={0xe1,0x14}

void main()
{
DINT; //关中断
        
for(i=0;i<1000;i++)
                ;//延时稳定
        
        /*  初始化变量  */
sda = 0;
scl = 0;      //端口设置为高
key_sw = 1;   //关键盘
        for(i=0;i<1000;i++)
                Delay(10);
        for(i = 0;i<16;i++)
        {
                KeyCodeBuff[i] = 0;
        }
        KeyCodeSum              = 0;
        KeyFlag                 = 0;
        KeyUpFlag               = 0;
        KeyExtendFlag           = 0;
        KeyLedLockFlag          = 0;
        KeyBoardConnectFlag     = 0;
        KeyPauseFlag            = 0;
        KeyMakeCodeFlag         = 0;
        KeyIDLo                 = 0;
        KeyIDHi                 = 0;
        LedStatus               = 0;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TMOD=0x22; // 定时器1 工作于方式2
//20
SCON=0x40; // 串口工作于方式1
TH1=0xfa; //装入初值,22.1184MHZ 的晶振,9600 的波特率
TL1=0xfa;
TL0 = 0xff;
TH0 = 0xff;
PCON=0x00; //波特率无倍增
TR1=1; //开启定时器1 开始工作
TR0=1; //开启定时器0 开始工作
//EA=1;
WDT_CONTR = 0x3f;   //开硬件狗
ES=1;	
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
        TMOD = 0x22;  //T1为波特率发生器设置19200波特率
        //T0为采样键盘时钟发生器
        TL1 = 0xFD;
        TH1 = 0xFD;
// TL0 =
// TH0 =
PCON |= 0x80; //SMOD设置为1
SCON = 0x50;  //串口控制寄存器
      //工作方式
      //非多机通讯方式
      //允许接收
      //

TR1 = 1;      //定时器1开始
*/
        IT0 = 0;      //低电平引起中断

        ES = 1;       //开串口中断
        EX0 = 1;      //开外部0中断
        key_sw = 0;   //开键盘电源
        scl = 1;
        sda = 1;
          
Delay(1);
        while(!KeyBoardConnectFlag)
                ReadPS2();//等待键盘自检成功
                
        Order(COMMAND_RESET);   //复位键盘
        ReadPS2();              //等待键盘应答
        Delay(5);
        
        Order(COMMAND_SETSTATUS);//设置状态灯CapsLock,NumLock,ScrollLock
        ReadPS2();               //等待键盘应答
        LedStatus = DISALL;
        Order(LedStatus);        //关闭所有灯
        ReadPS2();               //等待键盘应答
        /*
        Order(COMMAND_READID);   //读键盘ID
        ReadPS2();               //等待键盘应答
        KeyIDLo = ReadPS2();     //获得键盘ID低字节
        KeyIDHi = ReadPS2();     //获得键盘ID高字节
        */
        LedStatus = NUMLOCK_EN;  //开NumLock灯
        Order(COMMAND_SETSTATUS);   
        ReadPS2();               //等待应答
        Order(LedStatus);        //
        ReadPS2();               //等待应答
        Order(COMMAND_SETRATE);  //设置速率延时
        ReadPS2();               //等待应答
        Order(0x20);             //500ms/30
        ReadPS2();
        Order(COMMAND_ENABLE);   //使能键盘
        ReadPS2();
        Order(COMMAND_SETRATE);  //设置速率延时
        ReadPS2();
        Order(0x20);             //
        ReadPS2();
        
        Delay(200);              //延时
        
        EINT;                    //开总中断
     
while(1)
{
//  KeyScan();//扫描键盘
  if(KeyFlag == 1)
  {
   KeyFlag = 0;
   KeyTransmit();//
  
  }

WDT_CONTR = 0x3f;// 喂狗

}
}

/*********************************************************/
//函数:uart
//功能:串口中断
//输入:无
//输出:无
//描述:
/*********************************************************/
void uart() interrupt 4 using 2
{
ES=0;
TH1=0xfa; //装入初值,22.1184MHZ 的晶振,9600 的波特率
TL1=0xfa;

if(RI == 1)       //接收中断
{
  RI= 0;

}
else if(TI == 1)  //发送中断
{
  if(KeyCodeSum >1)
  {
 //  SBUF = KeyCodeBuff[--KeyCodeSum];  
//   SBUF = 0x00;
  }
                else
                {
                        KeyCodeSum = 0;                        
                }
  TI = 0;
}
ES=1;
}

unsigned char findcode(unsigned char dat,unsigned char sort)
{
	unsigned char conter=0x00;
	switch (sort)
	{
	case 0xE0:
	{
	for(conter=0x00;conter<22;conter++)
	{
	if(dat==e0_keyval[conter])return conter; 
	}
    return nodefinedkey;
	//break;
	}
	case 0xE1:
	{
	for(conter=0x00;conter<2;conter++)
	{
	if(dat==pausekey[conter])return conter; 
	}
    return nodefinedkey;
	//break;

	}
	default:
	for(conter=0x00;conter<86;conter++)
	{
	if(dat==keyval[conter])return conter; 
	}
    return nodefinedkey;	
	//break;
	}

}
/*********************************************************/
//函数:KeyTransmit()
//功能:串口中断
//输入:
//输出:
//描述:
/*********************************************************/
void KeyTransmit(void)
{      
		EA=0;
        
     	if((KeyCodeBuff[0x00]==0xE0)&(KeyCodeBuff[0x01]==0x12)&(KeyCodeBuff[0x02]!=0x00))
		{
		OUTPORT=findcode(KeyCodeBuff[0x02],0xE0)+80;//是扩展建?
		}
		else if((KeyCodeBuff[0x00]==0xE0)&(KeyCodeBuff[0x02]==0x00))
		{
		OUTPORT=findcode(KeyCodeBuff[0x01],0xE0)+58;//是普通扩展键?
		}
		if(KeyCodeBuff[0x00]==0xE1)OUTPORT=200; //pause的键显示200
		else
		{
		if((KeyCodeBuff[0x00]!=0xE0)&(KeyCodeBuff[0x00]!=0x00))
 	    {
		OUTPORT=findcode(KeyCodeBuff[0x00],0x12);//是普通键吗?
		}
		}
		//KeyCodeSum -= 0x01;  
		SBUF = KeyCodeBuff[0x00];//发送键值
	//	KeyCodeSum += 0x01;
        //KeyCodeSum = 0;                   //
//		KeyExtendFlag = 0;
EA=1;
}
/*********************************************************/
//函数:timer0()
//功能:定时器0中断
//输入:
//输出:
//描述:
/*********************************************************/
void timer0(void) interrupt 1 using 3
{
unsigned char compare=0x00;
switch(dat[0x00])

case 0xe0:  //是扩展键吗?
		for(compare=0x00;compare<100;compare++)
		{
		if(dat[0x01]==e0_keyval[compare])break;
		}
}
/*********************************************************/

⌨️ 快捷键说明

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