久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2761|回復: 6
打印 上一主題 下一主題
收起左側

6條語句搞定16矩陣鍵盤掃描單片機C語言程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:230500 發表于 2023-2-26 12:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我自己寫了一段51單片機的代碼分享給大家,有完整的注釋,和解碼過程圖解,這個矩陣鍵盤掃描程序不同于網上那些逐行掃描; 思路新穎,語句簡單,識別準確;
掃描子函數中包含變量定義,所有代碼就10行;真正做解碼的只用了6條語句
這段演示程序中沒有任何延時阻塞函數;識別率挺高; 做項目最好加入中斷定時掃描;如果單片機資源緊張,也可以在1-3 或者4-7;4條IO口上對地加4個104電容做硬件消抖;
程序在下面,里面還有一個LCD1602的顯示函數, 用來演示按鍵掃描結果!


單片機源程序如下:
  1. #include <REGX51.H>
  2. #include "LCD1602.H"

  3. /*** 0-15鍵值 ***/        
  4. /*****************
  5. 0x77,0x7B,0x7D,0x7E
  6. 0xB7,0xBB,0xBD,0xBE
  7. 0xD7,0xDB,0xDD,0xDE
  8. 0xE7,0xEB,0xED,0xEE

  9. ******************/

  10. unsigned char Key_Scan();                //按鍵掃描函數聲明

  11. /* 主函數從這里開始 */
  12. void main(void)
  13. {        
  14.         static unsigned char Key_Code = 0x00;                //定義一個靜態變量
  15.         
  16.         LCD_Init();                //初始化LCD1602,用來顯示鍵值

  17.         while(1)
  18.         {
  19.                 Key_Code = Key_Scan();
  20.                 switch (Key_Code)                //演示示例;用switch語句操作鍵碼;比如我在1602液晶屏上顯示數字1-16;也可以用數組來操作,自由發揮!
  21.                 {
  22.                         case 0x77: LCD_ShowNum(1,2,1,2); break;
  23.                         case 0x7B: LCD_ShowNum(1,2,2,2); break;
  24.                         case 0x7D: LCD_ShowNum(1,2,3,2); break;
  25.                         case 0x7E: LCD_ShowNum(1,2,4,2); break;
  26.                         case 0xB7: LCD_ShowNum(1,2,5,2); break;
  27.                         case 0xBB: LCD_ShowNum(1,2,6,2); break;
  28.                         case 0xBD: LCD_ShowNum(1,2,7,2); break;
  29.                         case 0xBE: LCD_ShowNum(1,2,8,2); break;
  30.                         case 0xD7: LCD_ShowNum(1,2,9,2); break;
  31.                         case 0xDB: LCD_ShowNum(1,2,10,2); break;
  32.                         case 0xDD: LCD_ShowNum(1,2,11,2); break;
  33.                         case 0xDE: LCD_ShowNum(1,2,12,2); break;
  34.                         case 0xE7: LCD_ShowNum(1,2,13,2); break;
  35.                         case 0xEB: LCD_ShowNum(1,2,14,2); break;
  36.                         case 0xED: LCD_ShowNum(1,2,15,2); break;
  37.                         case 0xEE: LCD_ShowNum(1,2,16,2); break;                        
  38.                         default: break;
  39.                 }
  40.         }
  41. }

  42. /* 帶返回值的按鍵掃描函數*/
  43. unsigned char Key_Scan()
  44. {
  45.         unsigned char Key_Temp;                        //定義一個存放組合鍵碼的變量
  46.         unsigned char Key_A,Key_B;        //        定義兩個變量,Key_A 用于存放正向掃描的鍵碼; Key_B 用于存放反向掃描的鍵碼。
  47.         
  48.         P1 = 0xF0;                                                                        //把P1口的高4位(P1.4-P1.7)置高,低4位置低;(如果有按鍵按下 高4位肯定有一條線會被拉低)。
  49.         Key_Temp = P1;                                                        //把P1口的狀態讀回來,傳遞給Key_Temp。沒有按鍵按下Key_Temp肯定是0XF0; 否則就是其它的數;
  50.         if(Key_Temp!= 0xF0)                                 // 進入if判斷語句;如果Key_Temp不等于0XF0,說明有鍵按下了。
  51.         {
  52.                 Key_A = P1;        // 把P1口此時被按下的狀態傳遞給Key_A保存
  53.                 P1 = 0x0F;        //開始反轉掃描;把P1口的高4位置低,低4位(P1.0-P1.3)置高;(如果有按鍵按下 低4位肯定有一條線會被拉低)。
  54.                 Key_B = P1;        //把P1口此時被按下的狀態傳遞給Key_A保存
  55.         }

  56.         Key_Temp = (Key_A | Key_B); //把正反兩次掃描的結果相或, 就會得到按鍵按下的正確鍵碼
  57.         return Key_Temp;  //把鍵碼返回,給其他的函數調用
  58. }


  59. //下面是圖解正反轉掃描的程序工作原理

  60. /*
  61. 正向掃描,比如P1.7和P1.3連接的按鍵被按下 那么P1口的0XF0:1111 0000  就會變成0X70:0111 0000

  62.                                 P1.3        P1.2        P1.1        P1.0
  63.                                  0                 0                 0                 0
  64. P1.7        1        -+-                ---                ---                ---

  65. P1.6        1        ---                ---                ---                ---

  66. P1.5        1        ---                ---                ---                ---

  67. P1.4        1        ---                ---                ---                ---



  68. 反向掃描,比如P1.7和P1.3連接的按鍵被按下 那么P1口的0X0F:0000 1111  就會變成0X07:0000 0111

  69.                                 P1.3        P1.2        P1.1        P1.0
  70.                                  1                 1                 1                 1
  71. P1.7        0        -+-                ---                ---                ---

  72. P1.6        0        ---                ---                ---                ---

  73. P1.5        0        ---                ---                ---                ---

  74. P1.4        0        ---                ---                ---                ---


  75. 最后把 正反兩次掃描的結果 0X70 與0X07相或 就會得到0X77的鍵碼
  76. 只要得到正確的鍵碼,就可以用這個鍵碼做任何事情。比如我在液晶屏上顯示數字1;表示數字1鍵被按下。
  77. */

  78. //下面這組鍵值根據不同的接線方式,會有不同的鍵值,需要提前自己算好;就類似數碼管的段碼一樣;也可以做成一個數組。
  79. /*** 0-15鍵值 ***/        
  80. /*****************
  81. 0x77,0x7B,0x7D,0x7E
  82. 0xB7,0xBB,0xBD,0xBE
  83. 0xD7,0xDB,0xDD,0xDE
  84. 0xE7,0xEB,0xED,0xEE

  85. ******************/


復制代碼
Keil代碼下載:
6條語句搞定4X4矩陣按鍵.rar (35.42 KB, 下載次數: 45)

評分

參與人數 2黑幣 +92 收起 理由
ldc2000 + 12 很給力!
admin + 80 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:366877 發表于 2023-2-26 15:48 | 只看該作者
簡單問題復雜化了,本來處理就是幾句話的事。
回復

使用道具 舉報

板凳
ID:526108 發表于 2023-2-26 18:31 | 只看該作者
跟我寫的非常接近了,但還能簡化,對于高速單片機這代碼行不通,給兩點建議:實時性和性能問題
回復

使用道具 舉報

地板
ID:807591 發表于 2023-2-27 08:58 | 只看該作者
全鍵無沖沒解決
回復

使用道具 舉報

5#
ID:409878 發表于 2023-2-27 13:45 | 只看該作者
個人看樓主的程序很好。樓上有好的想法和寫法的,可以分享下。
回復

使用道具 舉報

6#
ID:971308 發表于 2023-2-28 21:44 | 只看該作者
思路不錯
回復

使用道具 舉報

7#
ID:213173 發表于 2023-3-9 10:01 | 只看該作者
還能再省一句
  1. #include <REGX51.H>
  2. #include "LCD1602.H"

  3. /*** 0-15鍵值 ***/       
  4. /*****************
  5. 0x77,0x7B,0x7D,0x7E
  6. 0xB7,0xBB,0xBD,0xBE
  7. 0xD7,0xDB,0xDD,0xDE
  8. 0xE7,0xEB,0xED,0xEE

  9. ******************/

  10. unsigned char Key_Scan();                //按鍵掃描函數聲明

  11. /* 主函數從這里開始 */
  12. void main(void)
  13. {       
  14. //        static unsigned char Key_Code = 0x00;                //定義一個靜態變量
  15.        
  16.         LCD_Init();                //初始化LCD1602,用來顯示鍵值

  17.         while(1)
  18.         {
  19. //                Key_Code = Key_Scan();
  20.                 switch (Key_Scan())                //演示示例;用switch語句操作鍵碼;比如我在1602液晶屏上顯示數字1-16;也可以用數組來操作,自由發揮!
  21.                 {
  22.                         case 0x77: LCD_ShowNum(1,2,1,2); break;
  23.                         case 0x7B: LCD_ShowNum(1,2,2,2); break;
  24.                         case 0x7D: LCD_ShowNum(1,2,3,2); break;
  25.                         case 0x7E: LCD_ShowNum(1,2,4,2); break;
  26.                         case 0xB7: LCD_ShowNum(1,2,5,2); break;
  27.                         case 0xBB: LCD_ShowNum(1,2,6,2); break;
  28.                         case 0xBD: LCD_ShowNum(1,2,7,2); break;
  29.                         case 0xBE: LCD_ShowNum(1,2,8,2); break;
  30.                         case 0xD7: LCD_ShowNum(1,2,9,2); break;
  31.                         case 0xDB: LCD_ShowNum(1,2,10,2); break;
  32.                         case 0xDD: LCD_ShowNum(1,2,11,2); break;
  33.                         case 0xDE: LCD_ShowNum(1,2,12,2); break;
  34.                         case 0xE7: LCD_ShowNum(1,2,13,2); break;
  35.                         case 0xEB: LCD_ShowNum(1,2,14,2); break;
  36.                         case 0xED: LCD_ShowNum(1,2,15,2); break;
  37.                         case 0xEE: LCD_ShowNum(1,2,16,2); break;                       
  38.                         default: break;
  39.                 }
  40.         }
  41. }

  42. /* 帶返回值的按鍵掃描函數*/
  43. unsigned char Key_Scan()
  44. {
  45.         unsigned char Key_Temp;                //定義一個存放組合鍵碼的變量
  46. //        unsigned char Key_A,Key_B;        //        定義兩個變量,Key_A 用于存放正向掃描的鍵碼; Key_B 用于存放反向掃描的鍵碼。
  47.         P1 = 0xf0;                                        //把P1口的高4位(P1.4-P1.7)置高,低4位置低;(如果有按鍵按下 高4位肯定有一條線會被拉低)。
  48.         if(P1!= 0xf0)                 // 進入if判斷語句;如果Key_Temp不等于0XF0,說明有鍵按下了。
  49.         {
  50.                 Key_Temp = P1;        // 把P1口此時被按下的高4位狀態保存
  51.                 P1 = 0x0f;        //開始反轉掃描;把P1口的高4位置低,低4位(P1.0-P1.3)置高;(如果有按鍵按下 低4位肯定有一條線會被拉低)。
  52.                 Key_Temp |= P1&0x0f;        //把P1口此時被按下的低4位狀態與高4位狀態合并
  53.         }
  54.         return Key_Temp;  //把鍵碼返回,給其他的函數調用
  55. }
復制代碼
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 黄色一级毛片 | 国产福利小视频 | 亚洲国产成人精品女人久久久野战 | 丁香婷婷在线视频 | 91免费在线视频 | 一级毛片在线播放 | 欧美一区二区三区在线播放 | 综合久久av | 狠狠影院| 久久久久亚洲 | 中文字幕一区在线观看视频 | 日韩av在线中文字幕 | 国产视频精品区 | 蜜桃毛片 | 一级片av | 国产69精品久久久久777 | 日本不卡一区二区三区在线观看 | 久久久国产精品 | 久久久久久免费毛片精品 | 欧美性猛交一区二区三区精品 | 天天干天天谢 | 一呦二呦三呦国产精品 | 欧美日韩久久久久 | 中文在线视频 | 日日夜夜免费精品 | k8久久久一区二区三区 | 久久久国产精品视频 | 精品在线免费观看视频 | 日韩中文一区二区三区 | 99国产精品久久久 | 国产美女视频一区 | 精品福利一区二区三区 | 久久网一区二区三区 | 亚洲一区不卡在线 | 亚洲天堂一区 | 麻豆av电影网 | 久久精品视频网站 | 天堂免费看片 | 91爱啪啪| 午夜成人免费电影 | 在线观看精品 |