找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6308|回復: 0
收起左側

51單片機矩陣鍵盤掃描原理分析與程序

[復制鏈接]
ID:1020288 發(fā)表于 2022-4-26 10:04 | 顯示全部樓層 |閱讀模式
1、矩陣式鍵盤掃描原理
在矩陣式鍵盤中,行、列線分別連接到按鍵開關的兩端,行線通過上拉電阻接到+5V上。當無鍵按下時,行線處于高電平狀態(tài);當有鍵按下時,行、列線將導通,此時,行線電平將由與此行線相連的列線電平?jīng)Q定。這一點是識別矩陣按鍵是否被按下的關鍵。然而,矩陣鍵盤中的行線、列線和多個鍵相連,各按鍵按下與否均影響該鍵所在行線和列線的電平,各按鍵間將相互影響,因此,必須將行線、列線信號配合起來作適當處理,才能確定閉合鍵的位置。
掃描方式是利用CPU完成其他工作的空余調(diào)用鍵盤掃描子程序來響應鍵盤輸入的要求。在執(zhí)行鍵功能程序時,CPU不再響應鍵輸入要求,直到CPU重新掃描鍵盤為止。鍵盤掃描程序一般應包括以下內(nèi)容:
   (1)判別有無鍵按下。
   (2)鍵盤掃描取得閉合鍵的行、列值。
   (3)用計算法或查表法得到鍵值。
   (4)判斷閉合鍵是否釋放,如沒釋放則繼續(xù)等待。
   (5)將閉合鍵鍵號保存,同時轉去執(zhí)行該閉合鍵的功能。
    本實驗的掃描原理是:先置某列線為0,(比如C1=0[P40 == 0],其他為1),然后判斷行線那個為0,即若P4.4為0,則按下的鍵為S17,若P4.5為0,則按下的鍵為S13,若P4.6為0,則按下的鍵為S9,若P4.7為0,則按下的鍵為S5;以此類推,可以得到其他各列線上的鍵。
2、去抖概念:
按鍵是機械器件,按下或者松開時有固定的機械抖動,抖動圖如圖3.28所示。
按鍵01.png
圖3.28 按鍵被按下時的電壓變化
圖3.28看出按鍵按下和松開的瞬間出現(xiàn)機械抖動,這個抖動時間雖然很短,一般10~15ms,不同按鍵抖動不同,但對應單片機來說,很輕松就能檢測到,單片機是us 級別。但這個結果并不是我們需要的,實際上只進行一次按鍵操作,但有可能執(zhí)行了多次按鍵結果,這就是抖動造成的,所以大多數(shù)產(chǎn)品實際使用中都使用了按鍵去抖功能。
按鍵去抖分為硬件去抖和軟件去抖,硬件去抖最簡單的就是按鍵 2 端并聯(lián)電容,容量根據(jù)實驗而定。軟件去抖使用方便不增加硬件成本,容易調(diào)試,所以現(xiàn)在大都使用軟件去抖。
軟件去抖原理:
(1) 檢測到按鍵按下后進行 10~15ms 延時,用于跳過這個抖動區(qū)域
(2) 延時后再檢測按鍵狀態(tài),如果沒有按下表明是抖動或者干擾造成,如果仍舊按下,可以
認為是真正的按下。并進行對應的操作。
(3) 同樣按鍵釋放后也要進行去抖延時,延時后檢測按鍵是否真正釋放。
程序樣例中沒有使用按鍵釋放去抖程序,用戶可以參考按下去抖程序自行添加。多數(shù)時候按鍵需要在釋放時才起作用,像電腦鼠標一樣,這個時候需要檢測按鍵是否釋放,如果沒有釋放則一直等待。
3、主控系統(tǒng)板矩陣鍵盤的硬件連接
按鍵00.png

例如:LED1為指示燈,常量;
按鍵由S17---->>>S8按下顯示0-F數(shù)碼

單片機代碼:
1. /*****
2. STC15單片機開發(fā)系統(tǒng)演示程序         
3. LED1為指示燈,常量;
4. 按鍵又S17---->>>S8按下顯示0-F,順序暫時沒調(diào)
5. MCU:STC15W4K56S4 ,晶體頻率:11.0592MHz                           
6. ****/  
7. #include <stc15.h>  
8. #include <intrins.h>  
9. //行端口定義  
10. sbit R1=P4^4;                  
11. sbit R2=P4^5;  
12. sbit R3=P4^6;  
13. sbit R4=P4^7;  
14. //列端口定義  
15. sbit C1=P4^0;                  
16. sbit C2=P4^1;  
17. sbit C3=P4^2;  
18. sbit C4=P4^3;  
19. //共陰極0-f  
20. unsigned char code SMG_DuanMa[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};   //通過code將斷碼值設置為表格的形式  
21. unsigned char num =0;  
22. void Delay(unsigned char t)  
23. {  
24.     while(t--);  
25.     while(t--);  
26.     while(t--);  
27. }  
28. void Delay100ms()       //@11.0592MHz  
29. {  
30.     unsigned char i, j, k;  
31.   
32.     _nop_();  
33.     _nop_();  
34.     i = 5;  
35.     j = 52;  
36.     k = 195;  
37.     do  
38.     {  
39.         do  
40.         {  
41.             while (--k);  
42.         } while (--j);  
43.     } while (--i);  
44. }  
45.   
46. void HC138_Y(unsigned char n) //138譯碼器控制使能端口  
47. {  
48.     switch(n)  
49.     {  
50.         case 1:  //數(shù)碼管---位碼--控制輸出Y1  
51.             P0 = ((P0&0xF8)|0x04);  
52.         break;  
53.         case 2:  //數(shù)碼管---斷碼--控制輸出Y2  
54.             P0 = ((P0&0xF8)|0x02);  
55.         break;  
56.         case 3:  //LED燈--控制輸出Y3--控制輸出Y3  
57.             P0 = ((P0&0xF8)|0x06);  
58.         break;  
59.         case 4:   //ULN2003--電機--繼電器--控制輸出Y4  
60.             P0 = ((P0&0xF8)|0x01);  
61.         break;  
62.     }  
63. }  
64. void SMG_Display(unsigned char value)//數(shù)碼管第一位顯示數(shù)值  
65. {  
66.     HC138_Y(1);  
67.     P2 = 0xFE;  
68.     P0 &= 0xF8;  
69.     Delay100ms();  
70.     HC138_Y(2);  
71.     P2 = value;  
72.     P0 &= 0xF8;  
73.     Delay100ms();  
74. }  
75. void Key(void)//矩陣鍵盤掃描函數(shù),逐行逐列掃描  
76. {  
77.     /***掃描第一列***/  
78.     //再進行逐行掃描  
79.     C1 = 0;  
80.     R1 = R2 = R3 = R4 = 1;  
81.     C2 = C3 = C4 = 1;  
82.     if(R1 == 0)  
83.     {  
84.       Delay100ms();  //消抖
85.         while(R1 == 0);  
86.         num = 0;  
87.     }  
88.     else if(R2 == 0)  
89.     {  
90.       Delay100ms();  
91.         while(R2 == 0);  
92.         num = 4;  
93.     }  
94.     else if(R3 == 0)  
95.     {  
96.       Delay100ms();   
97.         while(R3 == 0);  
98.         num = 8;  
99.     }  
100.     else if(R4 == 0)  
101.     {  
102.       Delay100ms();  
103.         while(R4 == 0);  
104.         num = 12;  
105.     }  
106.     /***掃描第二列***/  
107.     C2 = 0;  
108.     R1 = R2 = R3 = R4 = 1;  
109.     C1 = C3 = C4 = 1;  
110.     if(R1 == 0)  
111.     {  
112.       Delay100ms();  
113.         while(R1 == 0);  
114.         num = 1;  
115.     }  
116.     else if(R2 == 0)  
117.     {  
118.       Delay100ms();  
119.         while(R2 == 0);  
120.         num = 5;  
121.     }  
122.     else if(R3 == 0)  
123.     {  
124.       Delay100ms();   
125.         while(R3 == 0);  
126.         num = 9;  
127.     }  
128.     else if(R4 == 0)  
129.     {  
130.       Delay100ms();  
131.         while(R4 == 0);  
132.         num = 13;  
133.     }  
134.         /***掃描第三列***/  
135.     C3 = 0;  
136.     R1 = R2 = R3 = R4 = 1;  
137.     C1 = C2 = C4 = 1;  
138.     if(R1 == 0)  
139.     {  
140.       Delay100ms();  
141.         while(R1 == 0);  
142.         num = 2;  
143.     }  
144.     else if(R2 == 0)  
145.     {  
146.       Delay100ms();  
147.         while(R2 == 0);  
148.         num = 6;  
149.     }  
150.     else if(R3 == 0)  
151.     {  
152.       Delay100ms();   
153.         while(R3 == 0);  
154.         num = 10;  
155.     }  
156.     else if(R4 == 0)  
157.     {  
158.       Delay100ms();  
159.         while(R4 == 0);  
160.         num = 14;  
161.     }  
162.         /***掃描第四列***/  
163.     C4 = 0;  
164.     R1 = R2 = R3 = R4 = 1;  
165.     C1 = C2 = C3 = 1;  
166.     if(R1 == 0)  
167.     {  
168.       Delay100ms();  
169.         while(R1 == 0);  
170.         num = 3;  
171.     }  
172.     else if(R2 == 0)  
173.     {  
174.       Delay100ms();  
175.         while(R2 == 0);  
176.         num = 7;  
177.     }  
178.     else if(R3 == 0)  
179.     {  
180.       Delay100ms();   
181.         while(R3 == 0);  
182.         num = 11;  
183.     }  
184.     else if(R4 == 0)  
185.     {  
186.       Delay100ms();  
187.         while(R4 == 0);  
188.         num = 15;  
189.     }  
190. }  
191.   
192. void main()  
193. {  
194.     P0M1=0;P0M0=0;  
195.     P1M1=0;P1M0=0;  
196.     P2M1=0;P2M0=0;  
197.     P3M1=0;P3M0=0;  
198.   P4M1=0;P4M0=0; //按鍵用到P4端口,記得設置P4端口模式  
199.     while(1)  
200.     {     
201.         Key();  
202.         if(num>=0)  
203.         {  
204.             HC138_Y(1);  
205.             P2 = 0xFE;  
206.             P0 &= 0xF8;  
207.             Delay100ms();  
208.               
209.             HC138_Y(2);  
210.             P2 = SMG_DuanMa[num];  
211.             P0 &= 0xF8;  
212.             Delay100ms();  
213.         }  
214.         Delay100ms();  
215.         HC138_Y(3);  
216.         P2 = 0x01;  
217.         Delay100ms();  
218.     }  
}

評分

參與人數(shù) 1黑幣 +30 收起 理由
admin + 30 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表