📄 ps2_bin.c
字号:
/*****************************************************************************/
//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 + -