现在的位置: 首页C语言基础>正文
[转]4×4行矩阵键盘识别方法的总结
2012年08月19日 C语言基础 暂无评论
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
//*********************************************************
//****************C51按键识别函数集源文件 *****************
//*********************************************************
//  作者:Ryudo  桂林电子科技大学 ryudo@yeah.net
//  开发开始时间:2006年8月15日
//  说明:   涉及到的所有的延时函数配合C51延时函数包使用 默认晶振频率12MHZ
//  版本信息:Ver 1.0
//*********************************************************
//    扫描方法一: 06.8.15 添加     4X4矩阵按键逐行扫描(一次)识别法函数
//
//    硬件连接  :  
//                      ______________________VCC
//                      |      |     |     |
//                      |      |     |     |
//                      |      |     |     |
//                      R      R     R     R
//                      |      |     |     |
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.7   -------/--|---/--|--/--|--/--|    每个按键对应的识别码是:0x88,0x84,0x82,0x81
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.6   -------/--|---/--|--/--|--/--|                            0x48,0x44,0x42,0x41
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.5   -------/--|---/--|--/--|--/--|                            0x28,0x24,0x22,0x21
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.4   -------/--|---/--|--/--|--/--|                            0x18,0x14,0x12,0x11
//                      |      |     |     |
//                      |      |     |     |
//    P X.3   ----------|      |     |     |
//                             |     |     |
//                             |     |     |
//    P X.2   ----------|------|     |     |
//                                   |     |
//                                   |     |               
//    P X.1   ----------|------|-----|     |
//                                         |
//                                         |
//    P X.0   ----------|------|-----|-----|
//
//************************************************************
//     扫描方法二: 06.8.15 添加    4X4矩阵键盘线翻转识别法函数
//     硬件连接  :      
//                      |      |     |     | 
//                    / |    / |   / |   / |
//    P X.7   -------/--|---/--|--/--|--/--|     每个按键对应的识别码是:0x77,0x7b,0x7d,0x7e
//                      |      |     |     |                            
//                    / |    / |   / |   / |      
//    P X.6   -------/--|---/--|--/--|--/--|        0xb7,0xbb,0xbd,0xbe       
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.5   -------/--|---/--|--/--|--/--|        0xd7,0xdb,0xdd,0xde
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.4   -------/--|---/--|--/--|--/--|        0xe7,0xeb,0xed,0xee
//                      |      |     |     |
//                      |      |     |     |
//    P X.3   ----------|      |     |     |
//                             |     |     |
//                             |     |     |
//    P X.2   ----------|------|     |     |
//                                   |     |
//                                   |     |               
//    P X.1   ----------|------|-----|     |
//                                         |
//                                         |
//    P X.0   ----------|------|-----|-----|
//
 
//*****************************************************************
//     扫描方法三: 06.8.16 添加    4X4矩阵键盘行扫描识别法函数(只返回4个识别码)
//     硬件连接  :    
//                      |      |     |     | 
//                    / |    / |   / |   / |
//    P X.7   -------/--|---/--|--/--|--/--|          通用识别码:    0x07,0x0b,0x0d,0x0e
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.6   -------/--|---/--|--/--|--/--|        0x07,0x0b,0x0d,0x0e
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.5   -------/--|---/--|--/--|--/--|        0x07,0x0b,0x0d,0x0e
//                      |      |     |     |
//                    / |    / |   / |   / |
//    P X.4   -------/--|---/--|--/--|--/--|        0x07,0x0b,0x0d,0x0e
//                      |      |     |     |
//                      |      |     |     |
//    P X.3   ----------|      |     |     |
//                             |     |     |
//                             |     |     |
//    P X.2   ----------|------|     |     |
//                                   |     |
//                                   |     |               
//    P X.1   ----------|------|-----|     |
//                                         |
//                                         |
//    P X.0   ----------|------|-----|-----|
//
 
//*****************************************************************
 
#include<reg51.h>
#include<delay.h>
 
//********************************************************
// 扫描方法一:  4X4矩阵按键逐行扫描(一次)识别法函数
// 函数假设硬件接在P1口,及"说明"中X=1
// 返回的是识别码,调用函数根据识别码动作
// 说明:算法稍烦,进阶使用   
 
unsigned char uc_Line_Scan_Send16(void)   
{
 unsigned char uc_Temp_1,uc_Temp_2;
    P1=0x0f;                               //先将所有行线拉低
 if(P1&0x0f!=0x0f)                      //如果列线有变化
 {                               
  Delay_12M_50ms();                  //延迟一段时间。
   if(P1&0x0f!=0x0f)            //如果此时此刻列线还有变化,说明确实有按键按下
   {
    uc_Temp_1=0x7f;               //用变量保存下第一次发送的扫描码0111,1111
     while(uc_Temp_1&0x08!=0)      //如果四个行线被完整扫描一次还没有完成,就进入循环,继续扫描下一行
     {
      P1=uc_Temp_1;         //给P1口赋扫描码,每次只拉低一行
       if(P1&0x0f!=0x0f)               //如果判断为真,则说明找到了按键按下的行   
         {
          uc_Temp_2=(P1&0x0f)|0xf0;            //计算识别码的算法,灵活性很大。         
                               return  ((~uc_Temp_1)+(~uc_Temp_2));    //返回识别码,识别码是根据上一条语句的算法计算好的,每个识别码对应一个按键,一共有16个识别码。
                              }
       else          //否则依次将第二,第三,第四行拉低
         {                    
        uc_Temp_1>>=1;       
        uc_Temp_1|=0x80;  
         }                          
     }                   
   }
 }
}    
//
//******************************************************************************************************
// 扫描方法二: 4X4矩阵键盘线翻转识别法函数
// 函数假设硬件接在P1口,及"说明"中X=1
// 返回的是识别码,调用函数根据识别码动作
// 说明  :算法简单易懂,初级使用
 
unsigned char  uc_Line_Turn(void)
{
 unsigned char uc_Temp_1,uc_Temp_2;
 P1=0xff;                    //P1口置高电平,准备输入
 P1=0x0f;     //P1口高4位作为输出,输出0,低四位作为输入     
 if(P1&0x0f!=0x0f)           //如果按键有反应
 {
  Delay_12M_50ms();       //延时去抖
  if(P1&0x0f!=0x0f)       //如果为真,则确实有按键按下
  {
   uc_Temp_1=P1;  //把这时P1口状态保存在一个变量中            
   P1=0xf0;   //把P1口高四位置输入,低四位作为输出,注意:这就是'线翻转' (即输入输出翻转)的本质所在      
   uc_Temp_2=P1;       //把这时P1口状态保存在一个变量中
   return  uc_Temp_1|uc_Temp_2; //'或'操作,返回识别码                  
  }
 }
}
//
//*******************************************************************************************************
// 扫描方法三:4X4矩阵键盘行扫描识别法函数(4个识别码)
// 函数假设硬件接在P1口,及"说明"中X=1
// 说明:个人不推荐使用这种方法,代码比较长,占用大量CPU时间,按键有时反应不够灵敏
//                   
 
void Line_Scan_Send4(void)
{
 P1=0xff;          //P1口置高,低四位准备接收输入
 P1_7=0;           //把P1口低四位作为输入,高四位作为输出,先扫描第一行,P1^7发送0。之前要把高四位进行位定义,这里只是作说明用。下同。
 if(P1&0x0f!=0x0f) //如果检测到按键有反应
 {
  Delay_12M_50ms(); //延迟去抖
  if(P1&0x0f!=0x0f) //此时确定有按键按下
  {
   switch(P1&0x0f)
   {
    case 0x07:
      /*动作 */;   //这里的动作根据实际要求添加,也可以作为返回值使用。
    break;  
    case 0x0b:
      /*动作 */;
    break;
    case 0x0d:
      /*动作 */;
    break;
    case 0x0e:
      /*动作 */;
    break;
    default:break;        //不动作  
   }
   while(P1&0x0f!=0x0f);   //等待按键跳起 
  }
 }
///////////////////////////////////////
 P1=0xff;          //P1口置高,低四位准备接收输入
 P1_6=0;          
 if(P1&0x0f!=0x0f) //如果检测到按键有反应
 {
  Delay_12M_50ms(); //延迟去抖
  if(P1&0x0f!=0x0f) //此时确定有按键按下
  {
   switch(P1&0x0f)
   {
    case 0x07:
      /*动作 */;   //这里的动作根据实际要求添加,也可以作为返回值使用。
    break;  
    case 0x0b:
      /*动作 */;
    break;
    case 0x0d:
      /*动作 */;
    break;
    case 0x0e:
      /*动作 */;
    break;
    default:break;        //不动作  
   }
   while(P1&0x0f!=0x0f);   //等待按键跳起 
  }
 }
///////////////////////////////////////
 P1=0xff;          //P1口置高,低四位准备接收输入
 P1_5=0;          
 if(P1&0x0f!=0x0f) //如果检测到按键有反应
 {
  Delay_12M_50ms(); //延迟去抖
  if(P1&0x0f!=0x0f) //此时确定有按键按下
  {
   switch(P1&0x0f)
   {
    case 0x07:
      /*动作 */;   //这里的动作根据实际要求添加,也可以作为返回值使用。
    break;  
    case 0x0b:
      /*动作 */;
    break;
    case 0x0d:
      /*动作 */;
    break;
    case 0x0e:
      /*动作 */;
    break;
    default:break;        //不动作  
   }
   while(P1&0x0f!=0x0f);   //等待按键跳起 
  }
 }
///////////////////////////////////////
 P1=0xff;          //P1口置高,低四位准备接收输入
 P1_4=0;          
 if(P1&0x0f!=0x0f) //如果检测到按键有反应
 {
  Delay_12M_50ms(); //延迟去抖
  if(P1&0x0f!=0x0f) //此时确定有按键按下
  {
   switch(P1&0x0f)
   {
    case 0x07:
      /*动作 */;   //这里的动作根据实际要求添加,也可以作为返回值使用。
    break;  
    case 0x0b:
      /*动作 */;
    break;
    case 0x0d:
      /*动作 */;
    break;
    case 0x0e:
      /*动作 */;
    break;
    default:break;        //不动作  
   }
   while(P1&0x0f!=0x0f);   //等待按键跳起 
  }
 }
}
//
//********************************************************************************************************


给我留言

留言无头像?


无觅相关文章插件,快速提升流量