[51单片机学习笔记FIVE]----独立按键

一、8个按键控制8个LED灯

 1 /*******************************************************************************
 2 实验名称:       8个独立按键控制8盏LED灯(按下哪个键,那个键对应的LED亮)
 3 实验时间:         2015/1/20
 4 *******************************************************************************/
 5 #include <reg51.h>
 6 
 7 #define LED_KEY P0   //LED灯用P0口
 8 #define IO_KEY  P1     //独立按键用P1口
 9 
10 void Delay();        //延时函数
11 unsigned char Key_Scan();     //获取按键值
12 
13 void main()
14 {
15     unsigned char Key_Value, LED_Value;
16     
17     while(1)
18     {
19         Key_Value = Key_Scan();
20         switch(Key_Value)
21         {
22             case(0xFE):         //K1按下
23                 LED_Value = 0x01;
24                 break;
25             case(0xFD):         //K2按下
26                 LED_Value = 0x02;
27                 break;
28             case(0xFB):         //K3按下
29                 LED_Value = 0x04;
30                 break;
31             case(0xF7):         //K4按下
32                 LED_Value = 0x08;
33                 break;
34             case(0xEF):         //K5按下
35                 LED_Value = 0x10;
36                 break;
37             case(0xDF):         //K6按下
38                 LED_Value = 0x20;
39                 break;
40             case(0xBF):         //K7按下
41                 LED_Value = 0x40;
42                 break;
43             case(0x7F):         //K8按下
44                 LED_Value = 0x80;
45                 break;
46             default:
47                 break;
48         }
49         
50         LED_KEY = LED_Value;  //点亮相应LED        
51     }
52 }
53 
54 unsigned char Key_Scan()
55 {
56     unsigned char Key_Value,i;
57 
58     if(IO_KEY != 0)
59     {
60         Delay();            //消除抖动
61 
62         if(IO_KEY != 0xFF)
63         {
64             Key_Value = IO_KEY;
65             i = 0;
66             if((i<50)&&(IO_KEY != 0xFF)) //判断按键是否松开
67             {
68                 Delay();
69                 i++;    
70             }
71         }
72     }
73     return Key_Value;
74 }
75 
76 void Delay()              //延迟10ms
77 {
78     unsigned char a,b,c;
79 
80     for(c=1;c>0;c--)
81     {
82         for(b=38;b>0;b--)
83         {
84             for(a=130;a>0;a--)
85             {};
86         }
87     }
88 }

独立按键原理是这样的:按键没按下的时候,相应端口是高电平状态,而当按键按下的时候,相应的端口则是低电平。所以可以根据这个现象,实现相应的功能。

还有一点应该注意的是:按键在闭合和断开时,触点会存在抖动现象。

                                                    

在实际情况下,我们需要的是稳定闭合的那部分状态。所以可以采用延时的方法来解决这个问题,具体的过程就是先看看有没有键按下,有键按下了,再延迟一段时间,再看看有没有键按下,

这时候如果还是有键按下的话那就真的是有键按下了。

而这个抖动的时间大概是10ms,所以只要用一个延时10ms的子函数就行。

上面代码的第66行那个判断按键是否松开也是必要的,虽然在这个程序中有和没有区别不大,但是在有的程序中加入要求按键松开之后才出现什么现象之类的东西的话,那这部分就显得必要了。



二、LED显示键值

 1  1 /***************************************************
 2  2 实验名称:       LED显示键值(按下哪个键,那个键对应的LED不亮)
 3  3 实验时间:       2015/1/22
 4  4 ****************************************************/
 5  5 #include <reg51.h>
 6  6 
 7  7 #define LED_KEY P0   //LED灯用P0口
 8  8 #define IO_KEY  P1     //独立按键用P1口
 9  9 
10 10 void Delay();        //延时函数
11 11 unsigned char Key_Scan();     //获取按键值
12 12 
13 13 void main()
14 14 {
15 15     unsigned char Key_Value, LED_Value;
16 16     
17 17     while(1)
18 18     {
19 19         Key_Value = Key_Scan();
20 20         if (Key_Value != 0)     //有按键按下
21 21         {
22 22             LED_Value = Key_Value;
23 23         }
24 24         
25 25         LED_KEY = LED_Value;  //点亮相应LED        
26 26     }
27 27 }
28 28 
29 29 unsigned char Key_Scan()
30 30 {
31 31     unsigned char Key_Value,i;
32 32 
33 33     if(IO_KEY != 0)
34 34     {
35 35         Delay();            //消除抖动
36 36 
37 37         if(IO_KEY != 0xFF)
38 38         {
39 39             Key_Value = IO_KEY;
40 40             i = 0;
41 41             if((i<50)&&(IO_KEY != 0xFF)) //判断按键是否松开
42 42             {
43 43                 Delay();
44 44                 i++;    
45 45             }
46 46         }
47 47     }
48 48     return Key_Value;
49 49 }
50 50 
51 51 void Delay()              //延迟10ms
52 52 {
53 53     unsigned char a,b,c;
54 54 
55 55     for(c=1;c>0;c--)
56 56     {
57 57         for(b=38;b>0;b--)
58 58         {
59 59             for(a=130;a>0;a--)
60 60             {};
61 61         }
62 62     }
63 63 }


三、按键选择花样显示

  1  /***********************************************
  2  实验名称:        按键选择花样显示
  3  实验时间:           2015/1/22
  4  ***********************************************/
  5 #include <reg51.h>
  6 #include <intrins.h>
  7 
  8 #define IO_KEY  P1
  9 #define LED_KEY P0
 10 
 11 void Delay(unsigned char c);                       //延时函数
 12 unsigned char  Key_Scan();            //按键扫描函数
 13 void Key1();                        //按下按键1的操作
 14 void Key2();                          //按下按键2的操作
 15 void Key3();                        //按下按键3的操作
 16 void Key4();                        //按下按键4的操作
 17 void Key5();                        //按下按键5的操作
 18 void Key6();                        //按下按键6的操作
 19 void Key7();                        //按下按键7的操作
 20 void Key8();                        //按下按键8的操作
 21 
 22 void main()
 23 {
 24     unsigned char Key_Value;
 25 
 26     while(1)
 27     {
 28         Key_Value = Key_Scan();
 29         switch(Key_Value)
 30         {
 31             case(0xFE):
 32                     Key1();
 33                     break;
 34             case(0xFD):
 35                     Key2();
 36                     break;
 37             case(0xFB):                                                                  
 38                     Key3();
 39                     break;
 40             case(0xF7):
 41                     Key4();
 42                     break;
 43             case(0xEF):
 44                     Key5();
 45                     break;
 46             case(0xDF):
 47                     Key6();
 48                     break;
 49             case(0xBF):
 50                     Key7();
 51                     break;
 52             case(0x7F):
 53                     Key8();
 54                     break; 
 55             default:
 56                     break; 
 57         }
 58     }
 59 }
 60 
 61                                 
 62 void Delay(unsigned char c)                       //c=1时,延迟10ms
 63 {
 64     unsigned char a,b;
 65 
 66     for(;c>0;c--)
 67     {
 68         for(b=38;b>0;b--)
 69         {
 70             for(a=130;a>0;a--)
 71             {};
 72         }
 73     }
 74 }
 75 
 76 unsigned char Key_Scan()
 77 {
 78     unsigned char Key_Value,i;
 79     if(IO_KEY != 0)
 80     {
 81         Delay(1);                                   //消除抖动
 82 
 83         if(IO_KEY != 0)
 84         {
 85             Key_Value = IO_KEY;
 86             i = 0;
 87             if((i<50)&&(IO_KEY != 0xFF))           //判断按键是否松开
 88             {
 89                 Delay(1);
 90                 i++;
 91             }                
 92         }
 93     }
 94     return Key_Value;    
 95 }
 96 
 97 //LED左移闪烁两次
 98 void Key1()
 99 {
100     unsigned char i;
101     LED_KEY = 0x01;
102     for(i=0;i<16;i++)                               //循环两次
103     {
104         LED_KEY = _crol_(LED_KEY,1);                //循环左移一位
105         Delay(15);                                    //延时                    
106     }            
107 }
108 //LED右移闪烁两次
109 void Key2()
110 {
111     unsigned char i;
112     LED_KEY= 0x80;
113     for(i=0;i<16;i++)
114     {
115         LED_KEY = _cror_(LED_KEY,1);                //循环右移一位
116         Delay(15);                                    //延时        
117     }
118 }
119 //LED交替闪烁16次,间隔亮
120 void Key3()
121 {
122     unsigned char i;
123     for(i=0;i<16;i++)
124     {
125         LED_KEY = 0xAA;
126         Delay(15);
127         LED_KEY = 0x55;
128         Delay(15);
129     }
130 }
131 //LED反交替闪烁16次,间隔亮
132 void Key4()
133 {
134     unsigned char i;
135     for(i=0;i<16;i++)
136     {
137         LED_KEY = 0x55;
138         Delay(15);
139         LED_KEY = 0xAA;
140         Delay(15);
141     }
142 }
143 //LED交替闪烁16次,相邻亮
144 void Key5()
145 {
146     unsigned char i;
147     for(i=0;i<16;i++)
148     {
149         LED_KEY = 0xCC;
150         Delay(15);
151         LED_KEY = 0x33;
152         Delay(15);
153     }
154 }
155 //LED反交替闪烁16次,相邻亮
156 void Key6()
157 {
158     unsigned char i;
159     for(i=0;i<16;i++)
160     {
161         LED_KEY = 0x33;
162         Delay(15);
163         LED_KEY = 0xCC;
164         Delay(15);
165     }
166 }
167 //Key1()--Key6(),Key8()都来一遍
168 void Key7()
169 {
170     Key1();
171     Key2();
172     Key3();
173     Key4();
174     Key5();
175     Key6();
176     Key8();
177 }
178 //全灭
179 void Key8()
180 {
181     LED_KEY = 0x00;
182 }


四、按键左右移LED灯

  1 /*******************************************************************************
  2 *实验名称                    :按键控制LED左右移
  3 *实验时间               ;   2015/1/22
  4 *******************************************************************************/
  5 #include <reg51.h>
  6 #include <intrins.h>
  7 
  8 //--定义要使用的IO口--//
  9 sbit      K1 = P1^0;       //对应按钮K1
 10 sbit     K2 = P1^1;        //对应按钮K2
 11 #define  LED_KEY P0    //LED使用P0口
 12 
 13 //--定义全局函数--//
 14 void Delay10ms(unsigned int c);   //延时10ms
 15 unsigned char Key_Scan();
 16 
 17 /*******************************************************************************
 18 * 函 数 名         : main
 19 * 函数功能           : 主函数
 20 *******************************************************************************/
 21 void main(void)
 22 {
 23     unsigned char ledValue, keyNum;
 24 
 25     ledValue = 0x01;
 26 
 27     while (1)
 28     {    
 29         keyNum = Key_Scan();  //扫描键盘
 30 
 31         if (keyNum == 1)      //如果键值返回1
 32         {
 33             ledValue = _crol_(ledValue, 1);    //左循环
 34         }
 35         else if (keyNum == 2)
 36         {
 37             ledValue = _cror_(ledValue, 1);    //右循环
 38         }
 39 
 40         LED_KEY = ledValue;  //点亮LED灯
 41     }                
 42 }
 43 
 44 /*******************************************************************************
 45 * 函 数 名                     : Key_Scan()
 46 * 函数功能                       : 扫描键盘
 47 *******************************************************************************/
 48 
 49 unsigned char Key_Scan()
 50 {
 51     unsigned char keyValue = 0 , i; //保存键值
 52 
 53     //--检测按键1--//
 54     if (K1==0)        //检测按键K1是否按下
 55     {
 56         Delay10ms(1);    //消除抖动
 57 
 58         if (K1==0)    //再次检测按键是否按下
 59         {
 60             keyValue = 1;
 61             i = 0;
 62             while ((i<50) && (K1==0))     //检测按键是否松开
 63             {
 64                 Delay10ms(1);
 65                 i++;
 66             }
 67         }
 68     }
 69 
 70     //--检测按键2--//
 71     if (K2==0)        //检测按键K1是否按下
 72     {
 73         Delay10ms(1);    //消除抖动
 74 
 75         if (K2==0)    //再次检测按键是否按下
 76         {
 77             keyValue = 2;
 78             i = 0;
 79             while ((i<50) && (K2==0))     //检测按键是否松开
 80             {
 81                 Delay10ms(1);
 82                 i++;
 83             }
 84         }
 85     }
 86 
 87     return keyValue;   //将读取到键值的值返回
 88 }
 89 
 90 /*******************************************************************************
 91 * 函 数 名                     : Delay10ms
 92 * 函数功能                     : 延时函数,延时10ms
 93 *******************************************************************************/
 94 
 95 void Delay10ms(unsigned int c)   //误差 0us
 96 {
 97     unsigned char a, b;
 98 
 99     //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
100     for (;c>0;c--)
101     {
102         for (b=38;b>0;b--)
103         {
104             for (a=130;a>0;a--);
105         }
106            
107     }       
108 }
原文地址:https://www.cnblogs.com/one-meter/p/4237169.html