但凡做和51单片机有关的东西,我们组都会用到按键,迷之有缘。独立按键的原理很简单,没有按键按下时,全部为高电平,按下时接触地变为地电平,检测是否有低电平来检测按下动作。
矩阵键盘稍微复杂一点,分别检测行,检测列,以此来确定按键位置。
注意的是,按下时会有抖动,因为写程序时,需要消抖。常用的方式是延时函数消抖。
1 /*
2 独立按键扫描基本程序 @L2 2016/08/03
3 */
4 #include
5 #define GPIO_KEY P1 //按键与P1口相连
6 void Delay10ms(unsigned int c);
7 unsigned char Key_Scan();
8
9 void main(void)
10 {
11 unsigned char keyNum;
12 while (1)
13 {
14 keyNum = Key_Scan(); //扫描键盘
15
16 switch (keyNum)
17 {
18 case(0xFE) : //返回按键K1的数据
19 break;
20 case(0xFD) : //返回按键K2的数据
21 break;
22 case(0xFB) : //返回按键K3的数据
23 break;
24 case(0xF7) : //返回按键K4的数据
25 break;
26 case(0xEF) : //返回按键K5的数据
27 break;
28 case(0xDF) : //返回按键K6的数据
29 break;
30 case(0xBF) : //返回按键K7的数据
31 break;
32 case(0x7F) : //返回按键K8的数据
33 break;
34 default:
35 break;
36 }
37
38
39 }
40 }
41
42
43 unsigned char Key_Scan()
44 {
45 unsigned char keyValue = 0 , i; //保存键值
46
47 //--检测按键--//
48 if (GPIO_KEY != 0xFF) //检测按键是否按下 若只连接P10~P13四个按键,则改为(GPIO_KEY | 0xF0)!= 0xFF;等等
49 {
50 Delay10ms(1); //消除抖动
51
52 if (GPIO_KEY != 0xFF) //再次检测按键是否按下
53 {
54 keyValue = GPIO_KEY;
55 i = 0;
56 while ((i《50) && (GPIO_KEY != 0xFF)) //检测按键是否松开
57 {
58 Delay10ms(1);
59 i++;
60 }
61 }
62 }
63
64 return keyValue;
65 }
66
67
68
69 void Delay10ms(unsigned int c)
70 {
71 unsigned char a, b;
72 for (;c》0;c--)
73 {
74 for (b=38;b》0;b--)
75 {
76 for (a=130;a》0;a--);
77 }
78
79 }
80 }
检测原理类似,检测该按键对应IO口是否为低电平
1 /*
2 矩阵键盘4X4,数码管显示键值 @L2 2016/08/03
3 */
4 #include
5 #define GPIO_DIG P1
6 #define GPIO_KEY P0
7
8 unsigned char code DIG_CODE[17]={
9 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
10 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
11
12 unsigned char KeyValue;
13 void Delay10ms(unsigned int c);
14 void KeyDown();
15
16 void main(void)
17 {
18 while(1)
19 {
20 KeyDown();
21 GPIO_DIG = ~DIG_CODE[KeyValue];
22 }
23 }
24
25 void KeyDown(void)
26 {
27 char a = 0;
28 GPIO_KEY=0x0f; // XXXX XXXX 四行四列
29 if(GPIO_KEY!=0x0f) //读取按键是否按下
30 {
31 Delay10ms(1); //消抖
32 if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
33 {
34
35 //测试行
36 GPIO_KEY=0XF0;
37 switch(GPIO_KEY)
38 {
39 case(0X70): KeyValue=0;break; //0111 第一列有按下
40 case(0XB0): KeyValue=4;break; //1011 第二列有按下
41 case(0XD0): KeyValue=8;break; //1101 第三列有按下
42 case(0XE0): KeyValue=12;break; //1110 第四列有按下
43 }
44 //测试行
45 GPIO_KEY=0X0F; //给列IO口置低电平
46 switch(GPIO_KEY)
47 {
48 case(0X07): KeyValue=KeyValue;break; // 0111 第一行有按下
49 case(0X0B): KeyValue=KeyValue+1;break; // 1011 第二行有按下
50 case(0X0D): KeyValue=KeyValue+2;break; // 1101 第三行有按下
51 case(0X0E): KeyValue=KeyValue+3;break; // 1110 第四行有按下
52 }
53 while((a《50) && (GPIO_KEY!=0xf0)) //检测按键松手检测
54 {
55 Delay10ms(1);
56 a++;
57 }
58 }
59 }
60 }
61
62
63 void Delay10ms(unsigned int c)
64 {
65 unsigned char a, b;
66 for (;c》0;c--)
67 {
68 for (b=38;b》0;b--)
69 {
70 for (a=130;a》0;a--);
71 }
72 }
73 }
来源;21ic
评论
查看更多