1、矩陣式鍵盤掃描原理 在矩陣式鍵盤中,行、列線分別連接到按鍵開關的兩端,行線通過上拉電阻接到+5V上。當無鍵按下時,行線處于高電平狀態;當有鍵按下時,行、列線將導通,此時,行線電平將由與此行線相連的列線電平決定。這一點是識別矩陣按鍵是否被按下的關鍵。然而,矩陣鍵盤中的行線、列線和多個鍵相連,各按鍵按下與否均影響該鍵所在行線和列線的電平,各按鍵間將相互影響,因此,必須將行線、列線信號配合起來作適當處理,才能確定閉合鍵的位置。 掃描方式是利用CPU完成其他工作的空余調用鍵盤掃描子程序來響應鍵盤輸入的要求。在執行鍵功能程序時,CPU不再響應鍵輸入要求,直到CPU重新掃描鍵盤為止。鍵盤掃描程序一般應包括以下內容: (1)判別有無鍵按下。 (2)鍵盤掃描取得閉合鍵的行、列值。 (3)用計算法或查表法得到鍵值。 (4)判斷閉合鍵是否釋放,如沒釋放則繼續等待。 (5)將閉合鍵鍵號保存,同時轉去執行該閉合鍵的功能。 本實驗的掃描原理是:先置某列線為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 (5.54 KB, 下載次數: 45)
下載附件
2022-4-26 10:02 上傳
圖3.28 按鍵被按下時的電壓變化 圖3.28看出按鍵按下和松開的瞬間出現機械抖動,這個抖動時間雖然很短,一般10~15ms,不同按鍵抖動不同,但對應單片機來說,很輕松就能檢測到,單片機是us 級別。但這個結果并不是我們需要的,實際上只進行一次按鍵操作,但有可能執行了多次按鍵結果,這就是抖動造成的,所以大多數產品實際使用中都使用了按鍵去抖功能。 按鍵去抖分為硬件去抖和軟件去抖,硬件去抖最簡單的就是按鍵 2 端并聯電容,容量根據實驗而定。軟件去抖使用方便不增加硬件成本,容易調試,所以現在大都使用軟件去抖。 軟件去抖原理: (1) 檢測到按鍵按下后進行 10~15ms 延時,用于跳過這個抖動區域 (2) 延時后再檢測按鍵狀態,如果沒有按下表明是抖動或者干擾造成,如果仍舊按下,可以 認為是真正的按下。并進行對應的操作。 (3) 同樣按鍵釋放后也要進行去抖延時,延時后檢測按鍵是否真正釋放。 程序樣例中沒有使用按鍵釋放去抖程序,用戶可以參考按下去抖程序自行添加。多數時候按鍵需要在釋放時才起作用,像電腦鼠標一樣,這個時候需要檢測按鍵是否釋放,如果沒有釋放則一直等待。 3、主控系統板矩陣鍵盤的硬件連接
按鍵00.png (88.39 KB, 下載次數: 39)
下載附件
2022-4-26 10:02 上傳
例如:LED1為指示燈,常量;
按鍵由S17---->>>S8按下顯示0-F數碼
單片機代碼:
1. /*****
2. STC15單片機開發系統演示程序
3. LED1為指示燈,常量;
4. 按鍵又S17---->>>S8按下顯示0-F,順序暫時沒調
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: //數碼管---位碼--控制輸出Y1
51. P0 = ((P0&0xF8)|0x04);
52. break;
53. case 2: //數碼管---斷碼--控制輸出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)//數碼管第一位顯示數值
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)//矩陣鍵盤掃描函數,逐行逐列掃描
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. }
}
|