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

本文针对特定按键(如Insert、Home等)的扫描码问题进行了深入分析,并修正了原有处理逻辑中的错误。通过调整代码,实现了对这些特殊按键的正确识别。

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

     接着上篇的问题,既然是按下insert等键的问题,那我们就来打印一下这些键产生的扫描码看看。

     一看吓一跳,发现了一个现象与书中的不同,就是Insert键,Home键,Page Up键 Page Down键,End键,Delete键以及四个箭头的方向键的Make Code和Break Code和书上说的有点区别,它们的Make Code,Break Code分别为:

Insert:

Home:

Page Up:

Page_Down:

End:

Delete:

Up:

Down:

Left:

Right:

     先来分析一下出错的原因,看下列代码:

Code:
  1. else if(scan_code == 0xe0)       
  2. {       
  3.     scan_code = Get_Byte_From_KB_Buffer();       
  4.     if(scan_code == 0x2a)       
  5.     {       
  6.         if(Get_Byte_From_KB_Buffer() == 0xe0)       
  7.         {       
  8.             if(Get_Byte_From_KB_Buffer() == 0x37)       
  9.             {       
  10.                 key = PRINTSCREEN;       
  11.                 make = 1;       
  12.             }       
  13.         }       
  14.     }      

     假设我们按下的是insert键,那么到了第8行的if为假,此时的scan_code的值为0x2a,正好是左边的shift键的Make Code的值!继续向下执行,看代码:

Code:
  1. make = (scan_code & NR_SCAN_CODES)? 0 : 1;       
  2. key_row = &Key_Map[(scan_code & 0x7f) * MAP_COLS];       
  3.            
  4. if(Shift_L || Shift_R)       
  5. {       
  6.     col = 1;       
  7. }       
  8.        
  9. if(code_with_E0)       
  10. {       
  11.     col = 2;       
  12. }       
  13.            
  14. key = key_row[col];       
  15.            
  16. switch(key)       
  17. {       
  18.     case SHIFT_L:       
  19.         Shift_L = make;       
  20.         key = 0;       
  21.         break;       
  22.     case SHIFT_R:       
  23.         Shift_R = make;       
  24.         key = 0;       
  25.         break;       
  26.     default:       
  27.         if(!make)       
  28.         {       
  29.             key = 0;       
  30.             break;       
  31.         }       
  32. }      

    第一行make置1, 第二行定位到了左shift键的行,此时当做是按下左shift键来处理!!慢着,此键的Break Code为0xE0,0xD2,0xE0,0xAA,其中有个0xAA是左shift键的Break Code啊,看起来可以模拟左shift键弹起而把Shift_L置0的效果,但是经过一番分析,却不能达到目的,分析就略了,很简单的。这时我们只能人工按一下左shift键,来将Shift_L置0,此时便又恢复正常,如图所示:

     可以看到,上述这些键的Make Code和Break Code分别有四个扫描码,而书中却只有两个,Make Code多了前两个码:0xE0,0x2A,Break Code多了后两个码:0xE0,0xAA。这意味着我们的原来的逻辑是不准确的,我们就来添加处理这些键的代码,下面是修改过的Keyboard_Read函数:

Code:
  1. void Keyboard_Read()   
  2. {   
  3.     u8 scan_code;   
  4.     int make;   
  5.     char disp[2];   
  6.     u32 *key_row;   
  7.     u32 key = 0;   
  8.     int col = 0;   
  9.     int code_with_E0 = 0;   
  10.        
  11.     Memory_Set(&disp[0],2,0);   
  12.        
  13.     if(kb_input_buffer.count > 0)   
  14.     {   
  15.         scan_code = Get_Byte_From_KB_Buffer();   
  16.            
  17.         if(scan_code == 0xe1)   
  18.         {   
  19.             int i;   
  20.             u8 pause_make_code[] = {0xe1,0x1d,0x45,0xe1,0x9d,0xc5};   
  21.             int is_pause = 1;   
  22.             for(i = 1 ; i < 6 ; i++)   
  23.             {   
  24.                 if(Get_Byte_From_KB_Buffer() != pause_make_code[i])   
  25.                 {   
  26.                     is_pause = 0;   
  27.                     break;   
  28.                 }   
  29.             }   
  30.             if(is_pause)   
  31.             {   
  32.                 key = PAUSEBREAK;   
  33.             }   
  34.         }   
  35.         else if(scan_code == 0xe0)   
  36.         {   
  37.             scan_code = Get_Byte_From_KB_Buffer();   
  38.             if(scan_code == 0x2a)   
  39.             {   
  40.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  41.                 {   
  42.                     scan_code = Get_Byte_From_KB_Buffer();   
  43.                     if(scan_code == 0x37) /* print screen */  
  44.                     {   
  45.                         key = PRINTSCREEN;   
  46.                         make = 1;   
  47.                     }   
  48.                     else if(scan_code == 0x52) /* insert */  
  49.                     {   
  50.                         key = INSERT;   
  51.                         make = 1;   
  52.                     }   
  53.                     else if(scan_code == 0x47) /* home */  
  54.                     {   
  55.                         key = HOME;   
  56.                         make = 1;   
  57.                     }   
  58.                     else if(scan_code == 0x49) /* page up */  
  59.                     {   
  60.                         key = PAD_PAGEUP;   
  61.                         make = 1;   
  62.                     }   
  63.                     else if(scan_code == 0x51) /* page down */  
  64.                     {   
  65.                         key = PAD_PAGEDOWN;   
  66.                         make = 1;   
  67.                     }   
  68.                     else if(scan_code == 0x4f) /* end */  
  69.                     {   
  70.                         key = END;   
  71.                         make = 1;   
  72.                     }   
  73.                     else if(scan_code == 0x53) /* delete */  
  74.                     {   
  75.                         key = DELETE;   
  76.                         make = 1;   
  77.                     }   
  78.                     else if(scan_code == 0x48) /* up */  
  79.                     {   
  80.                         key = UP;   
  81.                         make = 1;   
  82.                     }   
  83.                     else if(scan_code == 0x50) /* down */  
  84.                     {   
  85.                         key = DOWN;   
  86.                         make = 1;   
  87.                     }   
  88.                     else if(scan_code == 0x4b) /* left */  
  89.                     {   
  90.                         key = LEFT;   
  91.                         make = 1;   
  92.                     }   
  93.                     else if(scan_code == 0x4d) /* right */  
  94.                     {   
  95.                         key = RIGHT;   
  96.                         make = 1;   
  97.                     }   
  98.                 }   
  99.             }   
  100.             else if(scan_code == 0xb7) /* print screen break */  
  101.             {   
  102.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  103.                 {   
  104.                     scan_code = Get_Byte_From_KB_Buffer();   
  105.                     if(scan_code == 0xaa)   
  106.                     {   
  107.                         key = PRINTSCREEN;   
  108.                         make = 0;   
  109.                     }   
  110.                 }   
  111.             }   
  112.             else if(scan_code == 0xd2) /* insert break */  
  113.             {   
  114.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  115.                 {   
  116.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  117.                     {   
  118.                         key = INSERT;   
  119.                         make = 0;   
  120.                     }   
  121.                 }   
  122.             }   
  123.             else if(scan_code == 0xc7) /* home break */  
  124.             {   
  125.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  126.                 {   
  127.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  128.                     {   
  129.                         key = HOME;   
  130.                         make = 0;   
  131.                     }   
  132.                 }   
  133.             }   
  134.             else if(scan_code == 0xc9) /* page up break */  
  135.             {   
  136.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  137.                 {   
  138.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  139.                     {   
  140.                         key = PAD_PAGEUP;   
  141.                         make = 0;   
  142.                     }   
  143.                 }   
  144.             }   
  145.             else if(scan_code == 0xd1) /* page down break */  
  146.             {   
  147.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  148.                 {   
  149.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  150.                     {   
  151.                         key = PAD_PAGEDOWN;   
  152.                         make = 0;   
  153.                     }   
  154.                 }   
  155.             }   
  156.             else if(scan_code == 0xcf) /* end break */  
  157.             {   
  158.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  159.                 {   
  160.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  161.                     {   
  162.                         key = END;   
  163.                         make = 0;   
  164.                     }   
  165.                 }   
  166.             }   
  167.             else if(scan_code == 0xd3) /* delete break */  
  168.             {   
  169.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  170.                 {   
  171.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  172.                     {   
  173.                         key = DELETE ;   
  174.                         make = 0;   
  175.                     }   
  176.                 }   
  177.             }   
  178.             else if(scan_code == 0xc8) /* up break */  
  179.             {   
  180.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  181.                 {   
  182.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  183.                     {   
  184.                         key = UP;   
  185.                         make = 0;   
  186.                     }   
  187.                 }   
  188.             }   
  189.             else if(scan_code == 0xd0) /* down break */  
  190.             {   
  191.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  192.                 {   
  193.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  194.                     {   
  195.                         key = DOWN;   
  196.                         make = 0;   
  197.                     }   
  198.                 }   
  199.             }   
  200.             else if(scan_code == 0xcb) /* left break */  
  201.             {   
  202.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  203.                 {   
  204.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  205.                     {   
  206.                         key = LEFT;   
  207.                         make = 0;   
  208.                     }   
  209.                 }   
  210.             }   
  211.             else if(scan_code == 0xcd) /* right break */  
  212.             {   
  213.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  214.                 {   
  215.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  216.                     {   
  217.                         key = RIGHT;   
  218.                         make = 0;   
  219.                     }   
  220.                 }   
  221.             }   
  222.             else  
  223.             {   
  224.                 code_with_E0 = 1;   
  225.             }   
  226.         }   
  227.            
  228.         if((key != PRINTSCREEN) && (key != PAUSEBREAK) && (key != INSERT) && (key != HOME) && (key != PAD_PAGEUP) &&   
  229.              (key != PAD_PAGEDOWN) && (key != END) && (key != DELETE) && (key != UP) && (key != DOWN) && (key != LEFT) &&   
  230.              (key != RIGHT))   
  231.         {   
  232.             make = (scan_code & NR_SCAN_CODES)? 0 : 1;   
  233.             key_row = &Key_Map[(scan_code & 0x7f) * MAP_COLS];   
  234.                    
  235.             if(Shift_L || Shift_R)   
  236.             {   
  237.                 col = 1;   
  238.             }   
  239.                
  240.             if(code_with_E0)   
  241.             {   
  242.                 col = 2;   
  243.             }   
  244.                    
  245.             key = key_row[col];   
  246.                    
  247.             switch(key)   
  248.             {   
  249.                 case SHIFT_L:   
  250.                     Shift_L = make;   
  251.                     key = 0;   
  252.                     break;   
  253.                 case SHIFT_R:   
  254.                     Shift_R = make;   
  255.                     key = 0;   
  256.                     break;   
  257.                 default:   
  258.                     if(!make)   
  259.                     {   
  260.                         key = 0;   
  261.                         break;   
  262.                     }   
  263.             }   
  264.         }   
  265.            
  266.         if(key)   
  267.         {   
  268.             disp[0] = key;   
  269.             Disp_Color_Str(disp,0xa);   
  270.         }    
  271.     }   
  272. }  

     make,运行,结果正常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值