十天学会单片机Day2键盘检测(独立键盘、矩阵键盘)

时间:2024-03-02 11:57:12

1.键盘的分类

  编码键盘:键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘

  非编码键盘:靠软件编程来识别的称为非编码键盘。独立键盘、矩阵键盘

2.按键消抖

 

            

  如图,理想波形与实现波形之间是有区别的。实际波形在按下和释放的瞬间都有抖动现象,抖动事件的长短与按键的机械特性有关,一般为5~10ms。通常我们手动按下键然后立即释放,这个动作中稳定闭合时间超过20ms。因此检测键盘是否按下时,需加上去抖动操作。

一般有两种消抖方式:

   硬件消抖:如图。或有专门去抖动的芯片。

   软件消抖:通常用delay函数,将抖动的时间延时。

 

3.独立键盘

 1 //独立键盘检测 + 数码管显示所按值
 2 #include <reg52.h>
 3 void delay_ms(unsigned int n);
 4 sbit Key1 = P3^4;
 5 sbit Led1 = P1^0;
 6 
 7 int main()
 8 {
 9     Key1 = 1;
10     Led1 = 1;
11     while(1)
12     {    
13         if(Key1 == 0) {
14             delay_ms(20);        //消抖
15             if(Key1 == 0) {
16                 Led1 =! Led1;
17                 while(!Key1);    //等待按键释放
18             }
19         }
20     }
21     return 0;
22 }
23 
24 void delay_ms(unsigned int n)   //误差 -0.651041666667us
25 {
26     unsigned char a,b;
27     unsigned int i;
28     for(i = 0; i < n; i++) {
29         for(b=4;b>0;b--)
30             for(a=113;a>0;a--);
31     }
32 }

 

4.矩阵键盘

  

矩阵键盘模块示意图(根据模块电路即与I/O口相连情况简化)

(这里用的方法,自认为比郭天祥书上的方法好、更简单)

假设按下的键为1.

  P3=0xf0  //1111 0000

  temp = P3 //1110 0000  (1按下)确认所在列P3.4

  P3 = 0x0f  //0000 1111

  temp2 = P3 //0000 1110  (1按下)确认所在行P3.0

  temp = temp | temp2= 0xee // 1110 0000 | 0000 1110 = 1110 1110

每个按键的最后的temp值不同,故可以用此种方法检测。

 1 //矩阵键盘检测 + 数码管显示所按值
 2 #include <reg52.h>
 3 sbit DUAN = P2^6;
 4 sbit WE = P2^7;
 5 unsigned char DuanTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
 6                               0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
 7 unsigned char WeTable[]    = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};
 8 unsigned char num;
 9 void delay_ms(unsigned int n);
10 unsigned char key_jz();
11 void display(int num);
12 
13 int main()
14 {
15     while(1)
16     {    
17         num = key_jz();
18         display(num);
19     }
20     return 0;
21 }
22 
23 unsigned char key_jz()
24 {    
25     unsigned char temp;
26     P3=0xf0;
27     temp=P3;
28     if(temp!=0xf0)
29     {
30          delay_ms(20);
31         P3=0xf0;
32         temp=P3;
33         P3=0x0f;
34         temp|=P3;
35         switch(temp)
36         {
37              case 0xee:num=1;break;             //1
38             case 0xde:num=2;break;              //2
39             case 0xbe:num=3;break;              //3             
40             case 0x7e:num=\'A\';break;            //A
41 
42             case 0xed:num=4;break;              //4
43             case 0xdd:num=5;break;              //5
44             case 0xbd:num=6;break;              //6
45             case 0x7d:num=\'B\';break;            //B
46 
47             case 0xeb:num=7;break;              //7
48             case 0xdb:num=8;break;              //8
49             case 0xbb:num=9;break;              //9
50             case 0x7b:num=\'C\';break;            //C
51 
52             case 0xe7:num=\'*\';break;            //*
53             case 0xd7:num=0;break;              //0
54             case 0xb7:num=\'#\';break;            //#
55             case 0x77:num=\'D\';break;            //D
56                                     
57 
58         }
59 
60     }
61     return num;        
62 }
63 void display(int num)
64 {
65      //十位数
66     DUAN = 1;
67     P0 =  DuanTable[num/10];
68     DUAN = 0;
69     P0 = 0xFF;
70     WE = 1;
71     P0 = WeTable[4];
72     WE = 0;
73     P0 = 0xFF;
74     delay_ms(2);
75     
76     //个位数
77     DUAN = 1;
78     P0 =  DuanTable[num%10];
79     DUAN = 0;
80     P0 = 0xFF;
81     WE = 1;
82     P0 = WeTable[5];
83     WE = 0;
84     P0 = 0xFF;
85     delay_ms(1);
86 }
87 
88 
89 void delay_ms(unsigned int n)   //误差 -0.651041666667us
90 {
91     unsigned char a,b;
92     unsigned int i;
93     for(i = 0; i < n; i++) {
94         for(b=4;b>0;b--)
95             for(a=113;a>0;a--);
96     }
97 }

                      

               按下1时,显示1                                                   按下A时,显示A的ASCII码65