找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5144|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机矩阵键盘扫描原理分析与程序

[复制链接]
跳转到指定楼层
楼主
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所示。

图3.28 按键被按下时的电压变化
图3.28看出按键按下和松开的瞬间出现机械抖动,这个抖动时间虽然很短,一般10~15ms,不同按键抖动不同,但对应单片机来说,很轻松就能检测到,单片机是us 级别。但这个结果并不是我们需要的,实际上只进行一次按键操作,但有可能执行了多次按键结果,这就是抖动造成的,所以大多数产品实际使用中都使用了按键去抖功能。
按键去抖分为硬件去抖和软件去抖,硬件去抖最简单的就是按键 2 端并联电容,容量根据实验而定。软件去抖使用方便不增加硬件成本,容易调试,所以现在大都使用软件去抖。
软件去抖原理:
(1) 检测到按键按下后进行 10~15ms 延时,用于跳过这个抖动区域
(2) 延时后再检测按键状态,如果没有按下表明是抖动或者干扰造成,如果仍旧按下,可以
认为是真正的按下。并进行对应的操作。
(3) 同样按键释放后也要进行去抖延时,延时后检测按键是否真正释放。
程序样例中没有使用按键释放去抖程序,用户可以参考按下去抖程序自行添加。多数时候按键需要在释放时才起作用,像电脑鼠标一样,这个时候需要检测按键是否释放,如果没有释放则一直等待。
3、主控系统板矩阵键盘的硬件连接


例如: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.     }  
}

评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表