<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 51單片機模擬PS2協(xié)議制作5X5矩陣工業(yè)鍵盤(pán)

51單片機模擬PS2協(xié)議制作5X5矩陣工業(yè)鍵盤(pán)

作者: 時(shí)間:2016-11-23 來(lái)源:網(wǎng)絡(luò ) 收藏
根據客戶(hù)的要求利用單片機制作一個(gè)小的工控鍵盤(pán),將下面對應的鍵值發(fā)送到電腦顯示,利用的協(xié)議就是PS2,單片機型號為stc89c52rc,晶振為12M;
   10
65432
789減號等號
yuiop
qwert


#include
#include "PS2.H"

本文引用地址:http://dyxdggzs.com/article/201611/320263.htm

BYTE PS2RecChar=0xCC;
BOOL KeyBoardFlag=FALSE;
#define Key_line P0//鍵盤(pán)行入口
#define Key_list P2//鍵盤(pán)列入口

#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

//第二套鍵盤(pán)碼

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口的狀態(tài),若果P2口的值temp3:(temp3&0xff)!=0xff成立,表示有鍵按下
if(((temp3&0xff)!=0xff)) //有鍵按下條件判斷
{
flag=1;
//Key_line=0XFF; //清零鍵盤(pán)行端口
Key_list=0xff; //清零鍵盤(pán)列端口
}
else
flag=0; //無(wú)鍵按下標志
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用來(lái)保存行鍵盤(pán)數據,temp3保存列鍵盤(pán)數據
unsigned char temp=0,flag=0; //函數返回值temp
unsigned char i=0,key=0; //i位循環(huán)控制變量,給行送數據,key保存檢測鍵盤(pán)按下的標志位
if((key=Key_Press())!=0) //判斷是否有鍵按下
{
delay(30);
if((key=Key_Press())!=0)
{
for(i=0x01;i!=0x20;i=i<<1) //循環(huán)控制變量,掃描5行
{
Key_line=(~i); //將循環(huán)控制變量賦值行地址
temp2 =(~i); //保存行地址
//temp2=Key_line;
temp3=Key_list;//讀取列地址數據
switch((temp3&0xff))//判斷是那列有鍵按下
{
case 0xfe://第一列有鍵按下
switch((temp2&0xff)) //判斷第一列有鍵按下時(shí),對應的行按鍵
{
case 0xfe:
temp=23; //第一行有鍵按下
break; //該鍵無(wú)鍵盤(pán)號定義
case 0xfd: //第二行有鍵按下
temp=PS2_6;flag=1; //對應鍵值位PS2鍵盤(pán)的數字6,對應的鍵盤(pán)掃描碼為0x36
break;
case 0xfb: //第三行有鍵按下
temp=PS2_7; flag=1;//對應鍵值位PS2鍵盤(pán)的數字7,對應的鍵盤(pán)掃描碼為0x3d
break;
case 0xf7: //第四行有鍵按下
temp=PS2_y; flag=1; //對應鍵值位PS2鍵盤(pán)的字母y,對應的鍵盤(pán)掃描碼為0x35
break;
case 0xef: //第五行有鍵按下
temp=PS2_q ;flag=1; //對應鍵值位PS2鍵盤(pán)的字母q,對應的鍵盤(pán)掃描碼為0x15
break;
}
break;

case 0xfd:
switch((temp2&0xff)) // 第二列有鍵按下
{
case 0xfe: //第一行有鍵按下
temp=23; //該鍵無(wú)鍵盤(pán)號定義
break;
case 0xfd: //第二行有鍵按下
temp=PS2_5;flag=1; //對應鍵值位PS2鍵盤(pán)的數字5,對應的鍵盤(pán)掃描碼為0x2e
break;
case 0xfb: //第三行有鍵按下
temp=PS2_8;flag=1; //對應鍵值位PS2鍵盤(pán)的數字8,對應的鍵盤(pán)掃描碼為0x8e
break;
case 0xf7: //第四行有鍵按下
temp=PS2_u;flag=1; //對應鍵值位PS2鍵盤(pán)的字母u,對應的鍵盤(pán)掃描碼為0x3c
break;
case 0xef: //第五行有鍵按下
temp=PS2_w ; flag=1; //對應鍵值位PS2鍵盤(pán)的字母w,對應的鍵盤(pán)掃描碼為0x1d
break;
}
break;

case 0xfb:
switch((temp2&0xff)) // 第三列有鍵按下
{
case 0xfe: //第一行有鍵按下
temp=23;//該鍵無(wú)鍵盤(pán)號定義
break;
case 0xfd: //第二行有鍵按下
temp=PS2_4;flag=1;//對應鍵值位PS2鍵盤(pán)的數字4,對應的鍵盤(pán)掃描碼為0x25
break;
case 0xfb: //第三行有鍵按下
temp=PS2_9;flag=1;//對應鍵值位PS2鍵盤(pán)的數字9,對應的鍵盤(pán)掃描碼為0x46
break;
case 0xf7: //第四行有鍵按下
temp=PS2_i;flag=1;//對應鍵值位PS2鍵盤(pán)的字母i,對應的鍵盤(pán)掃描碼為0x43
break;
case 0xef: //第五行有鍵按下
temp=PS2_e; flag=1; //對應鍵值位PS2鍵盤(pán)的字母e,對應的鍵盤(pán)掃描碼為0x24
break;
}
break;

case 0xf7:
switch((temp2&0xff)) // 第四列有鍵按下
{
case 0xfe: //第一行有鍵按下
temp=PS2_1;flag=1; //對應鍵值位PS2鍵盤(pán)的數字1,對應的鍵盤(pán)掃描碼為0x16
break;
case 0xfd: //第二行有鍵按下
temp=PS2_3;flag=1; //對應鍵值位PS2鍵盤(pán)的數字3,對應的鍵盤(pán)掃描碼為0x26
break;
case 0xfb: //第三行有鍵按下
temp=PS2_dec;flag=1; //對應鍵值位PS2鍵盤(pán)的減號,對應的鍵盤(pán)掃描碼為0x4e
break;
case 0xf7: //第四行有鍵按下
temp=PS2_o;flag=1; //對應鍵值位PS2鍵盤(pán)的字母o,對應的鍵盤(pán)掃描碼為0x44
break;
case 0xef: //第五行有鍵按下
temp=PS2_r; flag=1; //對應鍵值位PS2鍵盤(pán)的字母r,對應的鍵盤(pán)掃描碼為0x2d
break;
}
break;

case 0xef:
switch((temp2&0xff)) // 第五列有鍵按下
{
case 0xfe: //第一行有鍵按下
temp=PS2_0;flag=1;//對應鍵值位PS2鍵盤(pán)的數字0,對應的鍵盤(pán)掃描碼為0x45
break;
case 0xfd: //第二行有鍵按下
temp=PS2_2;flag=1; //對應鍵值位PS2鍵盤(pán)的數字2,對應的鍵盤(pán)掃描碼為0x1e
break;
case 0xfb: //第三行有鍵按下
temp=PS2_eq;flag=1; //對應鍵值位PS2鍵盤(pán)的等號,對應的鍵盤(pán)掃描碼為0x55
break;
case 0xf7: //第四行有鍵按下
temp=PS2_p;flag=1; //對應鍵值位PS2鍵盤(pán)的字母p,對應的鍵盤(pán)掃描碼為0x4d
break;
case 0xef: //第五行有鍵按下
temp=PS2_t;flag=1; //對應鍵值位PS2鍵盤(pán)的字母t,對應的鍵盤(pán)掃描碼為0x2c
break;
}
break;
}
//P0=0XFF; //每當檢測完一行時(shí)清零行端口和列端口
//P2=0xff;
if((key=Key_Press())!=0);
delay(30);
}
}
}
else temp=23; //無(wú)鍵按下返回數字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();

CT_KB=OFF;
EX0=0;

H_DATA=0;Delay10us();//start bit
H_CLK=1;
Delay10us();
H_CLK=0;
Delay30us();

for(i=0;i<8;i++)
{
if(dat&0x01==0x01){H_DATA=1;Delay10us();}
else {H_DATA=0;Delay10us();}
dat>>=1;
H_CLK=1;
Delay10us();
H_CLK=0;
Delay30us();
}

H_DATA=ParityBit;Delay10us();//parity bit
H_CLK=1;
Delay10us();
H_CLK=0;
Delay30us();

H_DATA=1;Delay10us();//stop bit
H_CLK=1;
Delay10us();
H_CLK=0;
Delay30us();

IE0=0;
EX0=1;
H_CLK=1;
H_DATA=1;
CT_KB=ON;
Delay30us();
}
//---------------------------------------------------------------------------
void ExternInterrupt0(void) interrupt 0
{
BOOL ParityBit=0,CLKFlag=1;
BYTE i=0,j=8,dat=0x00;

EX0=0;

while(CLKFlag)
{
i++;
if(H_CLK==1)CLKFlag=0;
if(i>0xEE)
{
IE0=0;
EX0=1;
return ;
}
}
while(j--)//延時(shí)等待大鍵盤(pán)的動(dòng)作
{
for(i=0;i<0x88;i++)//檢查是否有數據處理0x88
{
if(H_CLK==0)//有動(dòng)作則是大鍵盤(pán)存在
{
OnKeyBoardOnline(TRUE);//大鍵盤(pán)存在,開(kāi)機由大鍵盤(pán)應答
IE0=0;
EX0=1;
return ;//存在的話(huà)置標志位,并返回
}
}
}
OnKeyBoardOnline(FALSE);//大鍵盤(pán)不存在,由小鍵盤(pán)應答

//轉到接收
for(i=0;i<8;i++)//read 8bit
{
Delay30us();
H_CLK=0;
Delay30us();
H_CLK=1;
dat=dat>>1;
if(H_DATA)dat|=0x80;

if(H_CLK==0){return;}//如果時(shí)鐘被拉低,則有錯誤發(fā)生
}

Delay30us();
H_CLK=0;
Delay30us();
H_CLK=1;
if(H_DATA)ParityBit=1;
else ParityBit=0;

Delay30us();
H_CLK=0;
Delay30us();
H_CLK=1;//STOP BIT H_DATA 0 ERR

Delay10us();
H_DATA=0;//ACK bit
Delay10us();
H_CLK=0;
Delay30us();Delay30us();
H_CLK=1;
Delay30us();
H_DATA=1;

OnPS2ReceiveChar(dat,ParityBit);

IE0=0;
EX0=1;
return ;
}
//---------------------------------------------------------------------------
void ProcessPS2(void)
{
if(KeyBoardFlag==FALSE)//大鍵盤(pán)不存在
{
if(PS2RecChar==0xF3)//1
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0x00)//11
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0x02)//111
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0x20)//1111
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xED)//2
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xF0)//3
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xF2)//4
{
OnPS2SendChar(0xFA);
Delay30us();
OnPS2SendChar(0xAB);
Delay30us();
OnPS2SendChar(0x83);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xEF)//5
{
OnPS2SendChar(0xFA);
Delay30us();
OnPS2SendChar(0xBF);
Delay30us();
OnPS2SendChar(0xB0);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xF3)//6
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xFE)//7 //resend
{
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xEE)//8
{
OnPS2SendChar(0xEE);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xEE)//9
{
OnPS2SendChar(0xEE);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xF1)//10
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xF4)//11
{
OnPS2SendChar(0xFA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xAA)//12
{
OnPS2SendChar(0xAA);
PS2RecChar=0xCC;
}
else if(PS2RecChar==0xFF)//13
{
OnPS2SendChar(0xFA);
Delay30us();
OnPS2SendChar(0xAA);
Delay30us();
PS2RecChar=0xCC;
}
else ;
}
}
//---------------------------------------------------------------------------
void PS2Init(void)
{
IT0=0;//低電平觸發(fā)中斷
PX0=1;
EX0=1;
}
//---------------------------------------------------------------------------

extern void ProcessPS2(void);
extern void PS2Init(void);
void main(void)
{
unsigned char tem;
PS2Init();
ProcessPS2();
while(1)
{
tem=Key_Scan();
switch(tem&0xff)
{
case 23 :
break;
default:
{
OnPS2SendChar(PS2Value[tem]);
}
break;
}
//開(kāi)機應答,使電腦能識別到鍵盤(pán)
//other code
}
}
仿真矩陣鍵盤(pán)電路圖,該電路未連接PS2,但可通過(guò)LED燈觀(guān)察每個(gè)按鍵按下之后的鍵值返回知否和第二套鍵盤(pán)碼對應一致


第二套鍵值碼對應表:




評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>