根据客户的要求利用
单片机制作一个小的工控键盘,将下面对应的键值发送到电脑显示,利用的协议就是PS2,单片机型号为
stc89c52rc,晶振为12M;
#include
#include "PS2.H"
BYTE PS2RecChar=0xCC;
BOOL KeyBoardFlag=FALSE;
#define Key_line P0//键盘行入口
#define Key_list P2//键盘列入口
#define PS2_1 0 //16
#define PS2_0 1 //45
#define PS2_6 2//36
#define PS2_5 3 //2e
#define PS2_4 4 //25
#define PS2_3 5 //26
#define PS2_2 6 //1e
#define PS2_7 7 //3d
#define PS2_8 8 //3e
#define PS2_9 9 //46
#define PS2_dec 10 //4e
#define PS2_eq 11 //55
#define PS2_y 12 //35
#define PS2_u 13//3c
#define PS2_i 14 //43
#define PS2_o 15 //44
#define PS2_p 16//4d
#define PS2_q 17 //15
#define PS2_w 18//1d
#define PS2_e 19 //24
#define PS2_r 20 //2d
#define PS2_t 21 //2c
//第二套键盘码
unsigned char PS2Value[22]={0x16,0x45,0x36,0x2e,0x25,0x26,0x1e,0x3d,0x3e,0x46,0x4e,0x55,0x35,0x3c,
0x43,0x44,0x4d,0x15,0x1d,0x24,0x2d,0x2c};
unsigned char Key_Press(void)
{
unsigned temp3;
unsigned char flag=0; //设定标志位
Key_line=0xe0; //将P0口低5位全部设置位0
temp3=Key_list; //读取P2口的状态,若果P2口的值temp3:(temp3&0xff)!=0xff成立,表示有键按下
if(((temp3&0xff)!=0xff)) //有键按下条件判断
{
flag=1;
//Key_line=0XFF; //清零键盘行端口
Key_list=0xff; //清零键盘列端口
}
else
flag=0; //无键按下标志
return flag;
}
void delay(unsigned int ms)
{
unsigned int i,j;
for(i=ms;i>0;i--)
for(j=100;j>0;j--);
}
unsigned char Key_Scan(void)
{
unsigned char temp2=0,temp3=0; //temp2用来保存行键盘数据,temp3保存列键盘数据
unsigned char temp=0,flag=0; //函数返回值temp
unsigned char i=0,key=0; //i位循环控制变量,给行送数据,key保存检测键盘按下的标志位
if((key=Key_Press())!=0) //判断是否有键按下
{
delay(30);
if((key=Key_Press())!=0)
{
for(i=0x01;i!=0x20;i=i<1) //循环控制变量,扫描5行
{
Key_line=(~i); //将循环控制变量赋值行地址
temp2 =(~i); //保存行地址
//temp2=Key_line;
temp3=Key_list;//读取列地址数据
switch((temp3&0xff))//判断是那列有键按下
{
case 0xfe://第一列有键按下
switch((temp2&0xff)) //判断第一列有键按下时,对应的行按键
{
case 0xfe:
temp=23; //第一行有键按下
break; //该键无键盘号定义
case 0xfd: //第二行有键按下
temp=PS2_6;flag=1; //对应键值位PS2键盘的数字6,对应的键盘扫描码为0x36
break;
case 0xfb: //第三行有键按下
temp=PS2_7; flag=1;//对应键值位PS2键盘的数字7,对应的键盘扫描码为0x3d
break;
case 0xf7: //第四行有键按下
temp=PS2_y; flag=1; //对应键值位PS2键盘的字母y,对应的键盘扫描码为0x35
break;
case 0xef: //第五行有键按下
temp=PS2_q ;flag=1; //对应键值位PS2键盘的字母q,对应的键盘扫描码为0x15
break;
}
break;
case 0xfd:
switch((temp2&0xff)) // 第二列有键按下
{
case 0xfe: //第一行有键按下
temp=23; //该键无键盘号定义
break;
case 0xfd: //第二行有键按下
temp=PS2_5;flag=1; //对应键值位PS2键盘的数字5,对应的键盘扫描码为0x2e
break;
case 0xfb: //第三行有键按下
temp=PS2_8;flag=1; //对应键值位PS2键盘的数字8,对应的键盘扫描码为0x8e
break;
case 0xf7: //第四行有键按下
temp=PS2_u;flag=1; //对应键值位PS2键盘的字母u,对应的键盘扫描码为0x3c
break;
case 0xef: //第五行有键按下
temp=PS2_w ; flag=1; //对应键值位PS2键盘的字母w,对应的键盘扫描码为0x1d
break;
}
break;
case 0xfb:
switch((temp2&0xff)) // 第三列有键按下
{
case 0xfe: //第一行有键按下
temp=23;//该键无键盘号定义
break;
case 0xfd: //第二行有键按下
temp=PS2_4;flag=1;//对应键值位PS2键盘的数字4,对应的键盘扫描码为0x25
break;
case 0xfb: //第三行有键按下
temp=PS2_9;flag=1;//对应键值位PS2键盘的数字9,对应的键盘扫描码为0x46
break;
case 0xf7: //第四行有键按下
temp=PS2_i;flag=1;//对应键值位PS2键盘的字母i,对应的键盘扫描码为0x43
break;
case 0xef: //第五行有键按下
temp=PS2_e; flag=1; //对应键值位PS2键盘的字母e,对应的键盘扫描码为0x24
break;
}
break;
case 0xf7:
switch((temp2&0xff)) // 第四列有键按下
{
case 0xfe: //第一行有键按下
temp=PS2_1;flag=1; //对应键值位PS2键盘的数字1,对应的键盘扫描码为0x16
break;
case 0xfd: //第二行有键按下
temp=PS2_3;flag=1; //对应键值位PS2键盘的数字3,对应的键盘扫描码为0x26
break;
case 0xfb: //第三行有键按下
temp=PS2_dec;flag=1; //对应键值位PS2键盘的减号,对应的键盘扫描码为0x4e
break;
case 0xf7: //第四行有键按下
temp=PS2_o;flag=1; //对应键值位PS2键盘的字母o,对应的键盘扫描码为0x44
break;
case 0xef: //第五行有键按下
temp=PS2_r; flag=1; //对应键值位PS2键盘的字母r,对应的键盘扫描码为0x2d
break;
}
break;
case 0xef:
switch((temp2&0xff)) // 第五列有键按下
{
case 0xfe: //第一行有键按下
temp=PS2_0;flag=1;//对应键值位PS2键盘的数字0,对应的键盘扫描码为0x45
break;
case 0xfd: //第二行有键按下
temp=PS2_2;flag=1; //对应键值位PS2键盘的数字2,对应的键盘扫描码为0x1e
break;
case 0xfb: //第三行有键按下
temp=PS2_eq;flag=1; //对应键值位PS2键盘的等号,对应的键盘扫描码为0x55
break;
case 0xf7: //第四行有键按下
temp=PS2_p;flag=1; //对应键值位PS2键盘的字母p,对应的键盘扫描码为0x4d
break;
case 0xef: //第五行有键按下
temp=PS2_t;flag=1; //对应键值位PS2键盘的字母t,对应的键盘扫描码为0x2c
break;
}
break;
}
//P0=0XFF; //每当检测完一行时清零行端口和列端口
//P2=0xff;
if((key=Key_Press())!=0);
delay(30);
}
}
}
else temp=23; //无键按下返回数字23,对应数组内的0;
if(flag==1)
return temp;//返回按键扫描值
else
return 23;
}
void OnKeyBoardOnline(BOOL i)
{
KeyBoardFlag=i;
}
//---------------------------------------------------------------------------
void OnPS2ReceiveChar(BYTE ReceChar,BOOL P)
{
BOOL ParityBit=0;
ACC=ReceChar;
CY=P;
ParityBit=(BOOL)(CY?0x00:0x80);//奇校验位
if(P==ParityBit);
PS2RecChar=ReceChar;
}
//---------------------------------------------------------------------------
void OnPS2SendChar(BYTE dat)
{
BOOL ParityBit;
BYTE i;
ACC=dat;
CY=P;
ParityBit=(BOOL)(CY?0x00:0x80);//奇校验位
CLSSIGNAL();