【第7章】解析扫描码【一】

本文介绍如何将键盘扫描码映射到ASCII码,通过创建键位映射表实现字符的打印,并展示了如何根据扫描码获取相应的ASCII码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     上一篇中我们打印的只是扫描码而已,我们想根据扫描码打印出相应的字符,这就需要一个扫描码和相应字符的ASCII码的一个映射,这就需要建一章表。我们先来看看扫描码,Scan Code Set 1:

     那么我们怎么把扫描码和相应ASCII对应起来呢,就是建立一张表,用Make Code的值当作数组的下标,相应下标的值就是对应的ASCII码,那么Break Code怎么跟ASCII码对应呢?从上表中看出一个规律,Make Code | 0x80 = Break Code,就可以先把Break Code转换为Make Code,再利用Make Code找到ASCII码。

     在include文件夹下建立一个keymap.h文件,我直接copy作者的代码了,写这玩意太费神了:

Code:
  1. /*====================================================================  
  2.                               keymap.h  
  3. ====================================================================*/  
  4.   
  5. #ifndef _KEY_MAP_H_   
  6. #define _KEY_MAP_H_   
  7.   
  8. /* Keymap for US MF-2 keyboard. */  
  9.   
  10. u32 Key_Map[NR_SCAN_CODES * MAP_COLS] = {   
  11.   
  12. /* scan-code            !Shift      Shift       E0 XX   */  
  13. /* ==================================================================== */  
  14. /* 0x00 - none      */  0,      0,        0,   
  15. /* 0x01 - ESC       */  ESC,        ESC,        0,   
  16. /* 0x02 - '1'       */  '1',        '!',        0,   
  17. /* 0x03 - '2'       */  '2',        '@',        0,   
  18. /* 0x04 - '3'       */  '3',        '#',        0,   
  19. /* 0x05 - '4'       */  '4',        '$',        0,   
  20. /* 0x06 - '5'       */  '5',        '%',        0,   
  21. /* 0x07 - '6'       */  '6',        '^',        0,   
  22. /* 0x08 - '7'       */  '7',        '&',        0,   
  23. /* 0x09 - '8'       */  '8',        '*',        0,   
  24. /* 0x0A - '9'       */  '9',        '(',        0,   
  25. /* 0x0B - '0'       */  '0',        ')',        0,   
  26. /* 0x0C - '-'       */  '-',        '_',        0,   
  27. /* 0x0D - '='       */  '=',        '+',        0,   
  28. /* 0x0E - BS        */  BACKSPACE,  BACKSPACE,  0,   
  29. /* 0x0F - TAB       */  TAB,        TAB,        0,   
  30. /* 0x10 - 'q'       */  'q',        'Q',        0,   
  31. /* 0x11 - 'w'       */  'w',        'W',        0,   
  32. /* 0x12 - 'e'       */  'e',        'E',        0,   
  33. /* 0x13 - 'r'       */  'r',        'R',        0,   
  34. /* 0x14 - 't'       */  't',        'T',        0,   
  35. /* 0x15 - 'y'       */  'y',        'Y',        0,   
  36. /* 0x16 - 'u'       */  'u',        'U',        0,   
  37. /* 0x17 - 'i'       */  'i',        'I',        0,   
  38. /* 0x18 - 'o'       */  'o',        'O',        0,   
  39. /* 0x19 - 'p'       */  'p',        'P',        0,   
  40. /* 0x1A - '['       */  '[',        '{',        0,   
  41. /* 0x1B - ']'       */  ']',        '}',        0,   
  42. /* 0x1C - CR/LF     */  ENTER,      ENTER,      PAD_ENTER,   
  43. /* 0x1D - l. Ctrl   */  CTRL_L,     CTRL_L,     CTRL_R,   
  44. /* 0x1E - 'a'       */  'a',        'A',        0,   
  45. /* 0x1F - 's'       */  's',        'S',        0,   
  46. /* 0x20 - 'd'       */  'd',        'D',        0,   
  47. /* 0x21 - 'f'       */  'f',        'F',        0,   
  48. /* 0x22 - 'g'       */  'g',        'G',        0,   
  49. /* 0x23 - 'h'       */  'h',        'H',        0,   
  50. /* 0x24 - 'j'       */  'j',        'J',        0,   
  51. /* 0x25 - 'k'       */  'k',        'K',        0,   
  52. /* 0x26 - 'l'       */  'l',        'L',        0,   
  53. /* 0x27 - ';'       */  ';',        ':',        0,   
  54. /* 0x28 - '/''      */  '/'',       '"',        0,   
  55. /* 0x29 - '`'       */  '`',        '~',        0,   
  56. /* 0x2A - l. SHIFT  */  SHIFT_L,    SHIFT_L,    0,   
  57. /* 0x2B - '/'       */  '//',       '|',        0,   
  58. /* 0x2C - 'z'       */  'z',        'Z',        0,   
  59. /* 0x2D - 'x'       */  'x',        'X',        0,   
  60. /* 0x2E - 'c'       */  'c',        'C',        0,   
  61. /* 0x2F - 'v'       */  'v',        'V',        0,   
  62. /* 0x30 - 'b'       */  'b',        'B',        0,   
  63. /* 0x31 - 'n'       */  'n',        'N',        0,   
  64. /* 0x32 - 'm'       */  'm',        'M',        0,   
  65. /* 0x33 - ','       */  ',',        '<',        0,   
  66. /* 0x34 - '.'       */  '.',        '>',        0,   
  67. /* 0x35 - '/'       */  '/',        '?',        PAD_SLASH,   
  68. /* 0x36 - r. SHIFT  */  SHIFT_R,    SHIFT_R,    0,   
  69. /* 0x37 - '*'       */  '*',        '*',        0,   
  70. /* 0x38 - ALT       */  ALT_L,      ALT_L,      ALT_R,   
  71. /* 0x39 - ' '       */  ' ',        ' ',        0,   
  72. /* 0x3A - CapsLock  */  CAPS_LOCK,  CAPS_LOCK,  0,   
  73. /* 0x3B - F1        */  F1,     F1,     0,   
  74. /* 0x3C - F2        */  F2,     F2,     0,   
  75. /* 0x3D - F3        */  F3,     F3,     0,   
  76. /* 0x3E - F4        */  F4,     F4,     0,   
  77. /* 0x3F - F5        */  F5,     F5,     0,   
  78. /* 0x40 - F6        */  F6,     F6,     0,   
  79. /* 0x41 - F7        */  F7,     F7,     0,   
  80. /* 0x42 - F8        */  F8,     F8,     0,   
  81. /* 0x43 - F9        */  F9,     F9,     0,   
  82. /* 0x44 - F10       */  F10,        F10,        0,   
  83. /* 0x45 - NumLock   */  NUM_LOCK,   NUM_LOCK,   0,   
  84. /* 0x46 - ScrLock   */  SCROLL_LOCK,    SCROLL_LOCK,    0,   
  85. /* 0x47 - Home      */  PAD_HOME,   '7',        HOME,   
  86. /* 0x48 - CurUp     */  PAD_UP,     '8',        UP,   
  87. /* 0x49 - PgUp      */  PAD_PAGEUP, '9',        PAGEUP,   
  88. /* 0x4A - '-'       */  PAD_MINUS,  '-',        0,   
  89. /* 0x4B - Left      */  PAD_LEFT,   '4',        LEFT,   
  90. /* 0x4C - MID       */  PAD_MID,    '5',        0,   
  91. /* 0x4D - Right     */  PAD_RIGHT,  '6',        RIGHT,   
  92. /* 0x4E - '+'       */  PAD_PLUS,   '+',        0,   
  93. /* 0x4F - End       */  PAD_END,    '1',        END,   
  94. /* 0x50 - Down      */  PAD_DOWN,   '2',        DOWN,   
  95. /* 0x51 - PgDown    */  PAD_PAGEDOWN,   '3',        PAGEDOWN,   
  96. /* 0x52 - Insert    */  PAD_INS,    '0',        INSERT,   
  97. /* 0x53 - Delete    */  PAD_DOT,    '.',        DELETE,   
  98. /* 0x54 - Enter     */  0,      0,      0,   
  99. /* 0x55 - ???       */  0,      0,      0,   
  100. /* 0x56 - ???       */  0,      0,      0,   
  101. /* 0x57 - F11       */  F11,        F11,        0,     
  102. /* 0x58 - F12       */  F12,        F12,        0,     
  103. /* 0x59 - ???       */  0,      0,      0,     
  104. /* 0x5A - ???       */  0,      0,      0,     
  105. /* 0x5B - ???       */  0,      0,      GUI_L,     
  106. /* 0x5C - ???       */  0,      0,      GUI_R,     
  107. /* 0x5D - ???       */  0,      0,      APPS,      
  108. /* 0x5E - ???       */  0,      0,      0,     
  109. /* 0x5F - ???       */  0,      0,      0,   
  110. /* 0x60 - ???       */  0,      0,      0,   
  111. /* 0x61 - ???       */  0,      0,      0,     
  112. /* 0x62 - ???       */  0,      0,      0,     
  113. /* 0x63 - ???       */  0,      0,      0,     
  114. /* 0x64 - ???       */  0,      0,      0,     
  115. /* 0x65 - ???       */  0,      0,      0,     
  116. /* 0x66 - ???       */  0,      0,      0,     
  117. /* 0x67 - ???       */  0,      0,      0,     
  118. /* 0x68 - ???       */  0,      0,      0,     
  119. /* 0x69 - ???       */  0,      0,      0,     
  120. /* 0x6A - ???       */  0,      0,      0,     
  121. /* 0x6B - ???       */  0,      0,      0,     
  122. /* 0x6C - ???       */  0,      0,      0,     
  123. /* 0x6D - ???       */  0,      0,      0,     
  124. /* 0x6E - ???       */  0,      0,      0,     
  125. /* 0x6F - ???       */  0,      0,      0,     
  126. /* 0x70 - ???       */  0,      0,      0,     
  127. /* 0x71 - ???       */  0,      0,      0,     
  128. /* 0x72 - ???       */  0,      0,      0,     
  129. /* 0x73 - ???       */  0,      0,      0,     
  130. /* 0x74 - ???       */  0,      0,      0,     
  131. /* 0x75 - ???       */  0,      0,      0,     
  132. /* 0x76 - ???       */  0,      0,      0,     
  133. /* 0x77 - ???       */  0,      0,      0,     
  134. /* 0x78 - ???       */  0,      0,      0,     
  135. /* 0x78 - ???       */  0,      0,      0,     
  136. /* 0x7A - ???       */  0,      0,      0,     
  137. /* 0x7B - ???       */  0,      0,      0,     
  138. /* 0x7C - ???       */  0,      0,      0,     
  139. /* 0x7D - ???       */  0,      0,      0,     
  140. /* 0x7E - ???       */  0,      0,      0,   
  141. /* 0x7F - ???       */  0,      0,      0   
  142. };   
  143.   
  144. #endif   

     此数组类似于二维数组,一个扫描码占一行,每一行有三列,分别是单独按某键,Shift+某键,有0xE0前缀的扫描码对应的字符。此头文件中还有许多宏,把它们定义在keyboard.h中,还是复制吧:

Code:
  1.     /************************************************************************/  
  2.     /*                          Macros Declaration                          */  
  3.     /************************************************************************/  
  4.     #define KB_IN_BYTES 32  /* size of keyboard input buffer */   
  5.     #define MAP_COLS    3   /* Number of columns in keymap */   
  6.     #define NR_SCAN_CODES   0x80    /* Number of scan codes (rows in keymap) */   
  7.        
  8.     #define FLAG_BREAK  0x0080      /* Break Code           */   
  9.     #define FLAG_EXT    0x0100      /* Normal function keys     */   
  10.     #define FLAG_SHIFT_L    0x0200      /* Shift key            */   
  11.     #define FLAG_SHIFT_R    0x0400      /* Shift key            */   
  12.     #define FLAG_CTRL_L 0x0800      /* Control key          */   
  13.     #define FLAG_CTRL_R 0x1000      /* Control key          */   
  14.     #define FLAG_ALT_L  0x2000      /* Alternate key        */   
  15.     #define FLAG_ALT_R  0x4000      /* Alternate key        */   
  16.     #define FLAG_PAD    0x8000      /* keys in num pad      */   
  17.        
  18.     #define MASK_RAW    0x01FF      /* raw key value = code passed to tty & MASK_RAW   
  19.                            the value can be found either in the keymap column 0   
  20.                            or in the list below */   
  21.        
  22.     /* Special keys */  
  23.     #define ESC     (0x01 + FLAG_EXT)   /* Esc      */   
  24.     #define TAB     (0x02 + FLAG_EXT)   /* Tab      */   
  25.     #define ENTER       (0x03 + FLAG_EXT)   /* Enter    */   
  26.     #define BACKSPACE   (0x04 + FLAG_EXT)   /* BackSpace    */   
  27.        
  28.     #define GUI_L       (0x05 + FLAG_EXT)   /* L GUI    */   
  29.     #define GUI_R       (0x06 + FLAG_EXT)   /* R GUI    */   
  30.     #define APPS        (0x07 + FLAG_EXT)   /* APPS */   
  31.        
  32.     /* Shift, Ctrl, Alt */  
  33.     #define SHIFT_L     (0x08 + FLAG_EXT)   /* L Shift  */   
  34.     #define SHIFT_R     (0x09 + FLAG_EXT)   /* R Shift  */   
  35.     #define CTRL_L      (0x0A + FLAG_EXT)   /* L Ctrl   */   
  36.     #define CTRL_R      (0x0B + FLAG_EXT)   /* R Ctrl   */   
  37.     #define ALT_L       (0x0C + FLAG_EXT)   /* L Alt    */   
  38.     #define ALT_R       (0x0D + FLAG_EXT)   /* R Alt    */   
  39.        
  40.     /* Lock keys */  
  41.     #define CAPS_LOCK   (0x0E + FLAG_EXT)   /* Caps Lock    */   
  42.     #define NUM_LOCK    (0x0F + FLAG_EXT)   /* Number Lock  */   
  43.     #define SCROLL_LOCK (0x10 + FLAG_EXT)   /* Scroll Lock  */   
  44.        
  45.     /* Function keys */  
  46.     #define F1      (0x11 + FLAG_EXT)   /* F1       */   
  47.     #define F2      (0x12 + FLAG_EXT)   /* F2       */   
  48.     #define F3      (0x13 + FLAG_EXT)   /* F3       */   
  49.     #define F4      (0x14 + FLAG_EXT)   /* F4       */   
  50.     #define F5      (0x15 + FLAG_EXT)   /* F5       */   
  51.     #define F6      (0x16 + FLAG_EXT)   /* F6       */   
  52.     #define F7      (0x17 + FLAG_EXT)   /* F7       */   
  53.     #define F8      (0x18 + FLAG_EXT)   /* F8       */   
  54.     #define F9      (0x19 + FLAG_EXT)   /* F9       */   
  55.     #define F10     (0x1A + FLAG_EXT)   /* F10      */   
  56.     #define F11     (0x1B + FLAG_EXT)   /* F11      */   
  57.     #define F12     (0x1C + FLAG_EXT)   /* F12      */   
  58.        
  59.     /* Control Pad */  
  60.     #define PRINTSCREEN (0x1D + FLAG_EXT)   /* Print Screen */   
  61.     #define PAUSEBREAK  (0x1E + FLAG_EXT)   /* Pause/Break  */   
  62.     #define INSERT      (0x1F + FLAG_EXT)   /* Insert   */   
  63.     #define DELETE      (0x20 + FLAG_EXT)   /* Delete   */   
  64.     #define HOME        (0x21 + FLAG_EXT)   /* Home     */   
  65.     #define END     (0x22 + FLAG_EXT)   /* End      */   
  66.     #define PAGEUP      (0x23 + FLAG_EXT)   /* Page Up  */   
  67.     #define PAGEDOWN    (0x24 + FLAG_EXT)   /* Page Down    */   
  68.     #define UP      (0x25 + FLAG_EXT)   /* Up       */   
  69.     #define DOWN        (0x26 + FLAG_EXT)   /* Down     */   
  70.     #define LEFT        (0x27 + FLAG_EXT)   /* Left     */   
  71.     #define RIGHT       (0x28 + FLAG_EXT)   /* Right    */   
  72.        
  73.     /* ACPI keys */  
  74.     #define POWER       (0x29 + FLAG_EXT)   /* Power    */   
  75.     #define SLEEP       (0x2A + FLAG_EXT)   /* Sleep    */   
  76.     #define WAKE        (0x2B + FLAG_EXT)   /* Wake Up  */   
  77.        
  78.     /* Num Pad */  
  79.     #define PAD_SLASH   (0x2C + FLAG_EXT)   /* /        */   
  80.     #define PAD_STAR    (0x2D + FLAG_EXT)   /* *        */   
  81.     #define PAD_MINUS   (0x2E + FLAG_EXT)   /* -        */   
  82.     #define PAD_PLUS    (0x2F + FLAG_EXT)   /* +        */   
  83.     #define PAD_ENTER   (0x30 + FLAG_EXT)   /* Enter    */   
  84.     #define PAD_DOT     (0x31 + FLAG_EXT)   /* .        */   
  85.     #define PAD_0       (0x32 + FLAG_EXT)   /* 0        */   
  86.     #define PAD_1       (0x33 + FLAG_EXT)   /* 1        */   
  87.     #define PAD_2       (0x34 + FLAG_EXT)   /* 2        */   
  88.     #define PAD_3       (0x35 + FLAG_EXT)   /* 3        */   
  89.     #define PAD_4       (0x36 + FLAG_EXT)   /* 4        */   
  90.     #define PAD_5       (0x37 + FLAG_EXT)   /* 5        */   
  91.     #define PAD_6       (0x38 + FLAG_EXT)   /* 6        */   
  92.     #define PAD_7       (0x39 + FLAG_EXT)   /* 7        */   
  93.     #define PAD_8       (0x3A + FLAG_EXT)   /* 8        */   
  94.     #define PAD_9       (0x3B + FLAG_EXT)   /* 9        */   
  95.     #define PAD_UP      PAD_8           /* Up       */   
  96.     #define PAD_DOWN    PAD_2           /* Down     */   
  97.     #define PAD_LEFT    PAD_4           /* Left     */   
  98.     #define PAD_RIGHT   PAD_6           /* Right    */   
  99.     #define PAD_HOME    PAD_7           /* Home     */   
  100.     #define PAD_END     PAD_1           /* End      */   
  101.     #define PAD_PAGEUP  PAD_9           /* Page Up  */   
  102.     #define PAD_PAGEDOWN    PAD_3           /* Page Down    */   
  103.     #define PAD_INS     PAD_0           /* Ins      */   
  104.     #define PAD_MID     PAD_5           /* Middle key   */   
  105.     #define PAD_DEL     PAD_DOT         /* Del      */  

     头文件中还定义了许多暂时用不到的宏,等用到的时候再说明。

     我们知道,按下某些键是能打印出可见的字符的,比如字符键和数字键,但有些键对应的不是可打印字符,这些键就不能直接打印的,而是需要做一些其它的工作。我们暂时先把可以打印的键先打印出来。修改一下Keyboard_Read函数:

Code:
  1. void Keyboard_Read()   
  2. {   
  3.     u8 scan_code;   
  4.     int make;   
  5.     char disp[2];   
  6.        
  7.     Memory_Set(&disp[0],2,0);   
  8.        
  9.     if(kb_input_buffer.count > 0)   
  10.     {   
  11.         Disable_Int();   
  12.         scan_code = *(kb_input_buffer.p_head);   
  13.         kb_input_buffer.p_head++;   
  14.         kb_input_buffer.count--;   
  15.         if(kb_input_buffer.p_head >= kb_input_buffer.buffer + 256)   
  16.         {   
  17.             kb_input_buffer.p_head = kb_input_buffer.buffer;   
  18.         }   
  19.         Enable_Int();   
  20.            
  21.         if(scan_code == 0xe1)   
  22.         {   
  23.             /* 暂时不做任何操作 */  
  24.         }   
  25.         else if(scan_code == 0xe0)   
  26.         {   
  27.             /* 暂时不做任何操作 */  
  28.         }   
  29.         else  
  30.         {   
  31.             make = (scan_code & NR_SCAN_CODES)? 0 : 1;   
  32.             if(make)   
  33.             {   
  34.                 disp[0] = Key_Map[(scan_code & 0x7f) * MAP_COLS];   
  35.                 Disp_Color_Str(disp,0xa);   
  36.             }    
  37.         }   
  38.            
  39.         /* Disp_Int(scan_code); */  
  40.     }   
  41. }  

     首先定义了一个局部变量来标识此扫描码是否是Make Code,再定义了一个两字节局部字符数组来作为待打印的空间,先用Memory_Set函数把次空间初始化为0,因为我们打印的串必须以0结尾。在从缓冲区取得扫描码之后,判断一下是否为0xE0和0xE1,是的话先不从处理,日后再说,不是的话,再判断一下是否是Make Code,不是的话就不打印了;是的话,从Key_Map取出相应的ASCII码来打印一下,有一个细节,在从Key_Map中取数据的时候进行了一次与操作,一方面,如果当前扫描码是Break Code,可以把它变成Make Code,这样似乎有点多余,因为已经在if里判断过了是否是Make Code了;另一方面,也是为了避免越界,Key_Map的大小为0x80。

     由于新添了一个keymap.h,所以要修改MAKEFILE。

     make,运行,按几个可打印的键,结果如下图所示:

     嗯,很好的开始。下一步就弄复杂点,与shift键配合搞个组合键之类的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值