51单片机模拟PS2协议制作5X5矩阵工业键盘

来源:本站
导读:目前正在解读《51单片机模拟PS2协议制作5X5矩阵工业键盘》的相关信息,《51单片机模拟PS2协议制作5X5矩阵工业键盘》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《51单片机模拟PS2协议制作5X5矩阵工业键盘》的详细说明。
简介:本文给大家而分享了51单片机模拟PS2协议制作5X5矩阵工业键盘。

根据客户的要求利用单片机制作一个小的工控键盘,将下面对应的键值发送到电脑显示,利用的协议就是PS2,单片机型号为stc89c52rc,晶振为12M;

1 0

6 5 4 3 2

7 8 9 减号 等号

y u i o p

q w e r t

#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(); 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--)//延时等待大键盘的动作 {  for(i=0;i<0x88;i++)//检查是否有数据处理 0x88  {   if(H_CLK==0)//有动作则是大键盘存在   {    OnKeyBoardOnline(TRUE);//大键盘存在,开机由大键盘应答    IE0=0;    EX0=1;    return ;//存在的话置标志位,并返回   }  } } OnKeyBoardOnline(FALSE);//大键盘不存在,由小键盘应答  //转到接收 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; }//如果时钟被拉低,则有错误发生 }           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)//大键盘不存在 {  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; //低电平触发中断 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;      }  //开机应答,使电脑能识别到键盘  //other code }}

提醒:《51单片机模拟PS2协议制作5X5矩阵工业键盘》最后刷新时间 2024-03-14 00:58:04,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《51单片机模拟PS2协议制作5X5矩阵工业键盘》该内容的真实性请自行鉴别。