矩陣按鍵_單片機_普中


1 矩陣按鍵介紹

  4*4矩陣按鍵,又稱行列式鍵盤,它用4條I/O線作為行線,它用4條I/O線作為列線組成鍵盤。在行線和列線的每一個交叉點上設置一個按鍵,這樣鍵盤按鍵就有4*4個,這種行列式鍵盤結構能夠有效的提高單片機系統的I/O口利用率。

 

2 功能要求:通過數碼管顯示矩陣按鍵S1-S16按下后鍵值0-F。

3 硬件設計

3.1 系統框圖

3.2 矩陣按鍵和數碼管電路

  

4 軟件設計

4.1 行列式掃描法

即逐行掃描:通過高四位輪流輸出低電平來對矩陣按鍵進行逐行掃描,當低四位接收到的數據不全為1的時候,說明有按鍵按下,然后通過接受到的數據是哪一位為0來判斷是哪一個按鍵被按下。

 1 #include "reg52.h"
 2 
 3 typedef unsigned int             u16;
 4 typedef unsigned char    u8;
 5 
 6 #define KEY_MATRIX_PORT     P1          //矩陣按鍵控制端口
 7 #define SMG_SEG_PORT        P0        //數碼管段選控制端口
 8 
 9 u8 gsmg_code[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
10                 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  //0-F的字形碼,共陰型數碼管
11 
12 //延時函數,ten_us=1時,大約延時10us
13 void delay_10us(u16 ten_us)
14 {
15      while(ten_us--);
16 }
17 
18 //矩陣按鍵掃描函數,采用行列式掃描法,監測按鍵是否按下,返回對應值
19 u8 key_matrix_ranks_scan(void)
20 {
21       u8 key_value=0;        //存儲按鍵值
22 
23     //從第一列開始,監測第1、2、3、4行,是否有按鍵按下
24     KEY_MATRIX_PORT=0xf7;    //0B1111_0111,給第一列賦值0,其余為1
25     if(KEY_MATRIX_PORT!=0xf7)    //判斷第一列是否按鍵按下
26     {
27          delay_10us(1000);        //延時10ms,濾除按下抖動區域
28         switch(KEY_MATRIX_PORT)        //返回第一列按鍵按下后的鍵值
29         {
30             case 0x77: key_value=1;break; //0B0111_0111
31             case 0xb7: key_value=5;break; //0B1011_0111
32             case 0xd7: key_value=9;break; //0B1101_0111
33             case 0xe7: key_value=13;break; //0B1110_0111
34         }
35     }
36     while(KEY_MATRIX_PORT!=0xf7);      //等待按鍵松開
37 
38      
39     //從第二列開始,監測第1、2、3、4行,是否有按鍵按下
40        KEY_MATRIX_PORT=0xfb;    //0B1111_1011,給第二列賦值0,其余為1
41     if(KEY_MATRIX_PORT!=0xfb)    //判斷第二列是否按鍵按下
42     {
43          delay_10us(1000);        //延時10ms,濾除按下抖動區域
44         switch(KEY_MATRIX_PORT)        //返回第二列按鍵按下后的鍵值
45         {
46             case 0x7b: key_value=2;break; //0B0111_1011
47             case 0xbb: key_value=6;break; //0B1011_1011
48             case 0xdb: key_value=10;break; //0B1101_1011
49             case 0xeb: key_value=14;break; //0B1110_1011
50         }
51     }
52     while(KEY_MATRIX_PORT!=0xfb);      //等待按鍵松開
53 
54     //從第三列開始,監測第1、2、3、4行,是否有按鍵按下
55     KEY_MATRIX_PORT=0xfd;    //0B1111_1101,給第三列賦值0,其余為1
56     if(KEY_MATRIX_PORT!=0xfd)    //判斷第三列是否按鍵按下
57     {
58          delay_10us(1000);        //延時10ms,濾除按下抖動區域
59         switch(KEY_MATRIX_PORT)        //返回第三列按鍵按下后的鍵值
60         {
61             case 0x7d: key_value=3;break;     //0B0111_1101
62             case 0xbd: key_value=7;break;     //0B1011_1101
63             case 0xdd: key_value=11;break;     //0B1101_1101
64             case 0xed: key_value=15;break;     //0B1110_1101
65         }
66     }
67     while(KEY_MATRIX_PORT!=0xfd);      //等待按鍵松開
68 
69 
70     //從第四列開始,監測第1、2、3、4行,是否有按鍵按下
71     KEY_MATRIX_PORT=0xfe;        //0B1111_1110,給第一列賦值0,其余為1
72     if(KEY_MATRIX_PORT!=0xfe)    //判斷第四列是否按鍵按下
73     {
74          delay_10us(1000);        //延時10ms,濾除按下抖動區域
75         switch(KEY_MATRIX_PORT)        //返回第四列按鍵按下后的鍵值
76         {
77             case 0x7e: key_value=4;break; //0B0111_0111
78             case 0xbe: key_value=8;break; //0B1011_0111
79             case 0xde: key_value=12;break; //0B1101_0111
80             case 0xee: key_value=16;break; //0B1110_0111
81         }
82     }
83     while(KEY_MATRIX_PORT!=0xfe);      //等待按鍵松開
84 
85     return key_value;
86 }
87 
88 void main()
89 {
90      u8 key=0;
91     while(1)
92     {
93          key=key_matrix_ranks_scan();
94         if(key!=0)
95             SMG_SEG_PORT=gsmg_code[key-1];
96     }
97 }    
key4x4.c

4.2 線翻轉法

行列掃描:通過高四位全部輸出低電平,低四位輸出高電平。當接受到的數據,低四位不全為高電平時,說明有按鍵按下,然后通過接受的數據值,判斷是按一列按鍵按下,然后再反過來,高四位輸出高電平,低四位輸出低電平,然后根據接收到的高四位的值判斷是哪一行有按鍵按下,這樣就能夠確定是哪一個按鍵按下了。

 1 #include "reg52.h"
 2 
 3 typedef unsigned int     u16;
 4 typedef unsigned char    u8;
 5 
 6 #define KEY_MATRIX_PORT     P1          //矩陣按鍵控制端口
 7 #define SMG_SEG_PORT        P0        //數碼管段選控制端口
 8 
 9 u8 gsmg_code[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
10                 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  //0-F的字形碼,共陰型數碼管
11 
12 //延時函數,ten_us=1時,大約延時10us
13 void delay_10us(u16 ten_us)
14 {
15      while(ten_us--);
16 }
17 
18 //矩陣按鍵掃描函數,采用線翻轉掃描方法
19 u8 key_matrix_flip_scan(void)
20 {
21       static u8 key_value=0;        //存儲按鍵值
22     KEY_MATRIX_PORT=0x0f;         //給所有行賦值0,列全為1,即0b0000_1111
23     if(KEY_MATRIX_PORT!=0x0f)      //判斷按鍵是否按下
24     {
25          delay_10us(1000);         //消抖
26         if(KEY_MATRIX_PORT!=0x0f)
27         {
28              //測試列
29             KEY_MATRIX_PORT=0x0f;         //0b0000_1111
30             switch(KEY_MATRIX_PORT)
31             {
32                 case 0x07: key_value=1;break;  //監測到第1列有按鍵按下
33                 case 0x0b: key_value=2;break;  //監測到第2列有按鍵按下
34                 case 0x0d: key_value=3;break;  //監測到第3列有按鍵按下
35                 case 0x0e: key_value=4;break;  //監測到第4列有按鍵按下
36             }
37 
38             //測試行
39             KEY_MATRIX_PORT=0xf0;         //1111_0000
40             switch(KEY_MATRIX_PORT)
41             {
42                 case 0x70: key_value=key_value;break;          //監測到第1行有按鍵按下
43                 case 0xb0: key_value=key_value+4;break;      //監測到第2行有按鍵按下
44                 case 0xd0: key_value=key_value+8;break;      //監測到第3行有按鍵按下
45                 case 0xe0: key_value=key_value+12;break;      //監測到第4行有按鍵按下
46             }
47             while(KEY_MATRIX_PORT!=0xf0);
48         }
49     }
50     else 
51         key_value=0;
52     return key_value;
53 }
54 
55 void main()
56 {
57      u8 key=0;
58     while(1)
59     {
60          key=key_matrix_flip_scan();
61         if(key!=0)
62             SMG_SEG_PORT=gsmg_code[key-1];
63     }
64 }
key4x4_flip.c

5 實驗現象:當按下S1-S16鍵,數碼管對應顯示0-F。

參考資料

(1)(79條消息) 51單片機(V51)———獨立按鍵、4x4矩陣按鍵_正弦定理的博客-CSDN博客

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM