PS2键盘解码的基本原理是通过外部中断读取键盘输出的串行信号,在根据扫描码进行查表解码。键盘发送往主机的信号总是在时钟的下降沿因此此中断是在下降沿触发,且时钟信号是由键盘给出,因此使用P1口中断(已经在初始化端口时设置)。发送的数据位11位,第一位是起始位,总为0,紧接是8个数据位,然后是奇校验位,最后是停止位总为1.
本程序只能对基本按键(即键被按下时产生三个字节的扫描码的按键)做出解码,包括所有的可显示字符键和Table,Back Space和Ente三个特殊功能键。基本按键的扫描码由三个字节组成,第1个字节为接通码,第2、3字节为断开码;其中第1字节和第3字节相同,中间字节为断开标志0xf0。例如:通码和断码是以什么样的序列发送到你的计算机使得字符G 出现在你的字处理软件里呢?因为这是一个大写字母需要发生这样的事件次序按下Shift 键按下G 键释放G 键释放Shift 键,与这些时间相关的扫描码如下:Shift 键的通码12h G键的通码34h G 键的断码F0h 34h Shift 键的断码F0h 12h 因此发送到你的计算机的数据应该是12h 34h F0h 34h F0h 12h如果按键按着不放会连续发送通码命令,可以连续显示字符(没有验证,实验验证是可以的)。
具体的说明都已经在程序中做了注释,主程序,中断服务函数中读取键盘发送的值:
-
-
-
-
-
-
-
-
-
-
-
-
- #include <msp430.h>
- #include "cry1602.h"
- #include "cry1602.C"
- #include "PS2Keyboard.h"
- #include "PS2Keyboard.C"
-
- #define SIDval P5IN & BIT6
- #define BufferSize 32 //显示缓存大小
- unsigned char bitcount=11;
- unsigned char kb_buffer[BufferSize];
- unsigned char input=0;
- unsigned char output=0;
- unsigned char pebit=0xff;
- unsigned char recdata=0;
- unsigned char tishi[]={ "this is a demo!"};
-
-
- void main(void)
- {
- uchar disptmp,i;
- uchar x = 0,y = 0;
- uchar first = 1;
-
- WDTCTL = WDTPW + WDTHOLD;
- P6DIR |= BIT2;P6OUT &= ~BIT2;
- P2DIR |= BIT3;P2OUT |= BIT3;
-
- BCSCTL1 &= ~XT2OFF;
- do
- {
- IFG1 &= ~OFIFG;
- for (i = 0xFF; i > 0; i--);
- }
- while ((IFG1 & OFIFG));
- BCSCTL2 |= SELM_2;
-
- LcdReset();
- DispNchar(0,0,15,tishi);
- Init_KB();
- _EINT();
-
- while(1)
- {
- LPM3;
-
- if(first)
- {
- first = 0;
- LcdWriteCommand(0x01, 1);
- LcdWriteCommand(0x0f, 1);
- }
-
- disptmp = GetChar();
- if(disptmp != 0xff)
- {
- if(disptmp == 8)
- {
- if((x == 0) && (y == 0))
- {
- x = 15;
- y = 1;
- Disp1Char(x,y,0x20);
- LocateXY(x,y);
- }
- else if((x == 0) && (y == 1))
- {
- x = 15;
- y = 0;
- Disp1Char(x,y,0x20);
- LocateXY(x,y);
- }
- else
- {
- Disp1Char(--x,y,0x20);
- LocateXY(x,y);
- }
- }
- else if((disptmp == 9) || (disptmp == 13))
- {
- _NOP();
- }
- else
- {
- Disp1Char(x++,y,disptmp);
- if(x == 16)
- {
- x = 0;
- y ^= 1;
- LocateXY(x,y);
- }
- }
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #pragma vector=PORT1_VECTOR
- __interrupt void PORT1_ISR(void)
- {
- if(P1IFG & BIT7)
- {
- P1IFG &=~ BIT7;
-
- if(bitcount == 11)
- {
- if(SIDval)
- return;
- else
- bitcount--;
- }
- else if(bitcount == 2)
- {
- if(SIDval)
- pebit = 1;
- else
- pebit = 0;
- bitcount--;
- }
- else if(bitcount == 1)
- {
- if(SIDval)
- {
- bitcount = 11;
- if( Decode(recdata) )
- LPM3_EXIT;
- recdata = 0;
- }
- else
- {
- bitcount = 11;
- recdata = 0;
- }
- }
- else
- {
- recdata >>= 1;
- if(SIDval) recdata |= 0x80;
- bitcount--;
- }
- }
- }
解码程序PS2Keyboard.C:
- #include <msp430x14x.h>
- #include "PS2Keyboardcode.h"
-
- #define BufferSize 32
- extern uchar kb_buffer[BufferSize];
- extern uchar input;
- extern uchar output;
- extern uchar flag;
-
-
-
-
-
-
-
- void PutChar(uchar c)
- {
- kb_buffer[input] = c;
- if (input < (BufferSize-1))
- input++;
- else
- input = 0;
- }
-
-
-
-
-
-
- uchar GetChar(void)
- {
- uchar temp;
-
- if(output == input)
- return 0xff;
- else
- {
- temp = kb_buffer[output];
- if(output < (BufferSize-1))
- {
- output++;
- }
- else
- {
- output = 0;
- }
- return temp;
- }
- }
-
-
-
-
-
-
- void Init_KB(void)
- {
- P1DIR &=~ BIT7;
- P5DIR &=~ BIT6;
- P1IES |= BIT7;
- P1IFG = 0x00;
- P1IE |= BIT7;
- P1SEL = 0x00;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- uchar Decode(uchar sc)
- {
- static uchar shift = 0;
- static uchar up = 0;
- uchar i,flag = 0;
-
- if(sc == 0xf0)
- {
- up = 1;
- return 0;
- }
- else if(up == 1)
- {
- up = 0;
- if((sc == 0x12) || ( sc==0x59)) shift = 0;
- return 0;
- }
-
-
- if((sc == 0x12) || (sc == 0x59))
- {
- shift = 1;
- flag = 0;
- }
- else
- {
- if(shift)
- {
- for(i = 0;(shifted[i][0] != sc) && shifted[i][0];i++);
- if (shifted[i][0] == sc)
- {
- PutChar(shifted[i][1]);
- flag = 1;
- }
- }
- else
- {
- for(i = 0;(unshifted[i][0] != sc) && unshifted[i][0];i++);
- if(unshifted[i][0] == sc)
- {
- PutChar(unshifted[i][1]);
- flag = 1;
- }
- }
- }
- if(flag) return 1;
- else return 0;
- }
需要查的表PS2Keyboardcode.h
-
- const unsigned char unshifted[][2] =
- {
- 0x0d,9,
- 0x0e,'`',
- 0x15,'q',
- 0x16,'1',
- 0x1a,'z',
- 0x1b,'s',
- 0x1c,'a',
- 0x1d,'w',
- 0x1e,'2',
- 0x21,'c',
- 0x22,'x',
- 0x23,'d',
- 0x24,'e',
- 0x25,'4',
- 0x26,'3',
- 0x29,' ',
- 0x2a,'v',
- 0x2b,'f',
- 0x2c,'t',
- 0x2d,'r',
- 0x2e,'5',
- 0x31,'n',
- 0x32,'b',
- 0x33,'h',
- 0x34,'g',
- 0x35,'y',
- 0x36,'6',
- 0x39,',',
- 0x3a,'m',
- 0x3b,'j',
- 0x3c,'u',
- 0x3d,'7',
- 0x3e,'8',
- 0x41,',',
- 0x42,'k',
- 0x43,'i',
- 0x44,'o',
- 0x45,'0',
- 0x46,'9',
- 0x49,'.',
- 0x4a,'/',
- 0x4b,'l',
- 0x4c,';',
- 0x4d,'p',
- 0x4e,'-',
- 0x52,0x27,
- 0x54,'[',
- 0x55,'=',
- 0x5a,13,
- 0x5b,']',
- 0x5d,0x5c,
- 0x61,'<',
- 0x66,8,
- 0x69,'1',
- 0x6b,'4',
- 0x6c,'7',
- 0x70,'0',
- 0x71,',',
- 0x72,'2',
- 0x73,'5',
- 0x74,'6',
- 0x75,'8',
- 0x79,'+',
- 0x7a,'3',
- 0x7b,'-',
- 0x7c,'*',
- 0x7d,'9',
- 0,0
- };
-
-
- const unsigned char shifted[][2] =
- {
- 0x0d,9,
- 0x0e,'~',
- 0x15,'Q',
- 0x16,'!',
- 0x1a,'Z',
- 0x1b,'S',
- 0x1c,'A',
- 0x1d,'W',
- 0x1e,'@',
- 0x21,'C',
- 0x22,'X',
- 0x23,'D',
- 0x24,'E',
- 0x25,'$',
- 0x26,'#',
- 0x29,' ',
- 0x2a,'V',
- 0x2b,'F',
- 0x2c,'T',
- 0x2d,'R',
- 0x2e,'%',
- 0x31,'N',
- 0x32,'B',
- 0x33,'H',
- 0x34,'G',
- 0x35,'Y',
- 0x36,'^',
- 0x39,'L',
- 0x3a,'M',
- 0x3b,'J',
- 0x3c,'U',
- 0x3d,'&',
- 0x3e,'*',
- 0x41,'<',
- 0x42,'K',
- 0x43,'I',
- 0x44,'O',
- 0x45,')',
- 0x46,'(',
- 0x49,'>',
- 0x4a,'?',
- 0x4b,'L',
- 0x4c,':',
- 0x4d,'P',
- 0x4e,'_',
- 0x52,'"',
- 0x54,'{',
- 0x55,'+',
- 0x5a,13,
- 0x5b,'}',
- 0x5d,'|',
- 0x61,'>',
- 0x66,8,
- 0x69,'1',
- 0x6b,'4',
- 0x6c,'7',
- 0x70,'0',
- 0x71,',',
- 0x72,'2',
- 0x73,'5',
- 0x74,'6',
- 0x75,'8',
- 0x79,'+',
- 0x7a,'3',
- 0x7b,'-',
- 0x7c,'*',
- 0x7d,'9',
- 0,0
- };
本文转自emouse博客园博客,原文链接:http://www.cnblogs.com/emouse/archive/2010/08/07/2198211.html,如需转载请自行联系原作者