📄 jianpan.h
字号:
/*---------------------------------------------------------------------------------------------------
功能:实现PC机键盘(P/S2接口)与8位单片机连接使用
原理:键盘时钟接在P3.2口,既8051的外部中断INT0上,键盘数据接到P1.0上
每次按键,键盘会向单片机发脉冲使单片机发生外部中断,数据有P1.0口一位一位传进来
传回的数据格式为:1位开始位(0),8位数据位(所按按键的通码,用来识别按键),1位校验位(奇校验)
1位结束位(1)
实现:将键盘发回的数据放到一个缓冲区里(数组),当按键结束后发生内部中断来处理所按的按键
缺点:由于51单片机的容量有限所以缓冲区不可以开的太大,这就导致可以记录键盘的按键次数过少,
也就是容错性一般。不过如果正常使用键盘是不会出错的
版本:1.0
最后修改时间:2003年5月
开发人:鞠春阳
版权:哈尔滨众邦龙开发有限公司 www.hitzbl.com 单片机坐标网:www.mcuzb.com
====================================================================================================*/
/*---------------------------------------------------------------------------
嵌入20按键系统扫描键盘, 达到与PC键盘兼容的效果:
2004/2/18
修改人:梁衍龙
----------------------------------------------------------------------------*/
#include "Ku.h"
sbit JianPan_SDA= P1^6; //键盘数据线
sbit LightContrl=P1^4;
unsigned char dat=0,dat1=0; //接收键盘数据变量
unsigned char Count=11; //中数次数 中断控制变量 缓冲区数组 缓冲区指针
bit Shift=0;
bit KeyBoardModle;
unsigned char xdata Whichpress;
unsigned char LightTime=0;
//unsigned char second=60;
bit stopmode;
#define Port P0
sbit P3_5=P3^5;
bit ZT=0;
void PC_GetKey();
bit ZT;
void GetKey()
{
// unsigned int DelayData=0;
//扫描P3.5口
Port=0xff;
P3_5=0;
if(Port!=0xff)
{
KeyBoardModle=1;
switch(Port)
{
case 0xef:if(!ZT){while(Port==0xef);dat=22;} //key 1
else
{
if(Whichpress<3)Whichpress++;else Whichpress=0;
while(Port==0xef);
switch(Whichpress)
{
case 1:dat=28;break; //a
case 2:dat=50;break; //b
case 3:dat=33;break; //c
}
}
break;//P0.4 1
case 0xdf:if(!ZT){while(Port==0xdf);dat=30;}
else
{
if(Whichpress<3)Whichpress++;else Whichpress=0;
while(Port==0xdf);
switch(Whichpress)
{
case 1:dat=35;break; //d
case 2:dat=36;break; //e
case 3:dat=43;break; //f
}
}
break;//P0.5 2
case 0xbf:if(!ZT){while(Port==0xbf);dat=38;}
else
{
if(Whichpress<3)Whichpress++;else Whichpress=0;
while(Port==0xbf);
switch(Whichpress)
{
case 1:dat=52;break; //g
case 2:dat=51;break; //h
case 3:dat=67;break; //i
}
}
break;//P0.6 3
case 0x7f:if(!ZT){while(Port==0x7f);dat=37;}
else
{
if(Whichpress<3)Whichpress++;else Whichpress=0;
while(Port==0x7f);
switch(Whichpress)
{
case 1:dat=59;break; //j
case 2:dat=66;break; //k
case 3:dat=75;break; //l
}
}
break;//P0.7 4
}//switch end
}//P3.5扫描结束
//扫描P0.0口
Port=0xff;
P3_5=1;
Port=0xfe;
if(Port!=0xfe)
{
KeyBoardModle=1;
switch(Port)
{
case 0xee:if(!ZT){while(Port==0xee);dat=46;}
else
{
if(Whichpress<3)Whichpress++;else Whichpress=0;
while(Port==0xee);
switch(Whichpress)
{
case 1:dat=58;break; //m
case 2:dat=49;break; //n
case 3:dat=68;break; //o
}
}
break;//P0.4 5
case 0xde:if(!ZT){while(Port==0xde);dat=54;}
else
{
if(Whichpress<4)Whichpress++;else Whichpress=0;
while(Port==0xde);
switch(Whichpress)
{
case 1:dat=77;break; //p
case 2:dat=21;break; //q
case 3:dat=45;break; //r
case 4:dat=27;break; //s
}
}
break;//P0.5 6
case 0xbe:if(!ZT){while(Port==0xbe);dat=61;}
else
{
if(Whichpress<3)Whichpress++;else Whichpress=0;
while(Port==0xbe);
switch(Whichpress)
{
case 1:dat=44;break; //t
case 2:dat=60;break; //u
case 3:dat=42;break; //v
}
}
break;//P0.6 7
case 0x7e:if(!ZT){while(Port==0x7e);dat=62;}
else
{
if(Whichpress<4)Whichpress++;else Whichpress=0;
while(Port==0x7e);
switch(Whichpress)
{
case 1:dat=29;break; //w
case 2:dat=34;break; //x
case 3:dat=53;break; //y
case 4:dat=26;break; //z
}
}
break;//P0.7 8
}//switch end
}//扫描P0.0口结束
//扫描P0.1口
Port=0xff;
P3_5=1;
Port=0xfd;
if(Port!=0xfd)
{
KeyBoardModle=1;
switch(Port)
{
case 0xed:if(!ZT){while(Port==0xed);dat=70;}//9
else {while(Port==0xed);dat=41;}//space
break;//P0.4 9
case 0xdd:if(!ZT){while(Port==0xdd);dat=69;}break;//P0.5 0
case 0xbd:if(!ZT){while(Port==0xbd);dat=125;} //f2
else
{
while(Port==0xbd);dat=6;
}
break;//P0.6 中英 page up
case 0x7d:if(!ZT){while(Port==0x7d);dat=122;} //back ??????????
else
{
while(Port==0x7d);dat=102; // 退格 page down ?????????
}
break;//P0.7
}
}
//扫描P0.2口
Port=0xff;
P3_5=1;
Port=0xfb;
if(Port!=0xfb)
{
KeyBoardModle=1;
switch(Port)
{
case 0xeb:while(Port==0xeb);dat=117;break;//P0.4 //↑
case 0xdb:while(Port==0xdb);dat=116;break;//P0.5 //→
case 0xbb:while(Port==0xbb);dat=5;break;//P0.6 // 库操作(f1)
case 0x7b:while(Port==0x7b);dat=7;break;//P0.7 //单位转换(f12)
}
}
//扫描P0.3口
Port=0xff;
P3_5=1;
Port=0xf7;
if(Port!=0xf7)
{
KeyBoardModle=1;
switch(Port)
{
case 0xe7:while(Port==0xe7);dat=107;break;//P0.4 //←
case 0xd7:while(Port==0xd7);dat=114;break;//P0.5 //↓
case 0xb7:while(Port==0xb7);dat=118;break;//P0.6 //取消(esc)
case 0x77:while(Port==0x77);dat=90;break;//P0.7 //确认(enter)
}
}
PC_GetKey();
}//扫描结束
void ZhongDuan() interrupt 0 using 0 //外部中断0 用来接受键盘发来的数据
{
if(Count<11&& Count>2)
{
dat>>=1;
if(JianPan_SDA) dat|=0x80;
}
if(--Count==0)
{
if(dat==0xe0) Count=11;
else {KeyBoardModle=0;EA=0;delay(200);PC_GetKey();EA=1;}
}
}
void PC_GetKey() //interrupt 1 using 1 //内部中断0 用来处理缓冲区里的数据
{
unsigned char i=0;
// unsigned int aaa[2];
Count=11;
TR0=0;
TH0=0;
TL0=0;
// TR1=0;
// second=60;
if(dat!=0)
{
if(dat==0x12 || dat==0x59)
{
Shift=1;
dat1=dat;
return;
}
if((dat1==0x12 || dat1==0x59) && dat==0xf0)
{
Shift=0;
dat1=dat;
return;
}
if(dat==0xf0 && dat1==0xf0)
Shift=0;
if(Shift)
{
for(i=0;i<47;i++)
{
if(AddShift[i][0]==dat)
{
Key=AddShift[i][1];
break;
}
}
}
else
{
for(i=0;i<80;i++)
{
if(NoShift[i][0]==dat)
{
Key=NoShift[i][1];
break;
}
}
}
dat1=dat;
dat=0;
} //if(dat!=0) end
if(Key!=0){ LightContrl=1;LightTime=0;}
// temp[shu]=dat;shu++;
TR0=1;
}
void Time0() interrupt 1 using 1 //内部中断0 用来处理缓冲区里的数据
{
TR0=0;
TH0=0;
TL0=0;
LightTime++;
if(LightTime>70)//背光量的时间
{
LightTime=0;
LightContrl=0;
}
GetKey();
TR0=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -