基于51单片机的独立按键和矩阵按键用法

Posted action0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于51单片机的独立按键和矩阵按键用法相关的知识,希望对你有一定的参考价值。

------------恢复内容开始------------

主要实现如图所示的功能

技术图片

 

 

 将主函数以外的函数全部放在qiyu.h文件中

  1 //qiyu.h
  2 #define KEY_PORT      P1
  3 #define led           P2
  4 #define unchar unsigned char
  5 #define uint unsigned int
  6 
  7 sbit Buz = P1^5;
  8 sbit LED  = P2^0;
  9 sbit K1 = P3^0;
 10 sbit K2 = P3^1;
 11 sbit K3 = P3^2;
 12 sbit K4 = P3^3;
 13 
 14 char tzsta,msta,val=0;
 15 int seccnt,temp,m=0,j,b;
 16 
 17 
 18 void ini()//定时器
 19 { 
 20     seccnt=0;    
 21     msta=tzsta=0;
 22     TMOD=0x01;
 23     TH0=0xFF;
 24     TL0=0x9C;
 25     TR0=1;     //开启定时器0
 26     
 27 }
 28 
 29 void delay(int p)
 30 {
 31     while(p--);
 32 }
 33 void keyscan()//独立按键
 34 {
 35     if(K1==0)
 36         {
 37             delay(5);
 38             if(K1==0)
 39             {
 40                 msta=1;
 41             }
 42         }
 43         if(K2==0)
 44         {
 45             delay(5);
 46             if(K2==0)
 47             {
 48                 msta=2;
 49             }
 50         }
 51       if(K3==0)
 52         {
 53             delay(5);
 54           if(K3==0)
 55             {
 56                 msta=3;
 57             }
 58         }
 59         if(K4==0)
 60         {
 61             delay(5);
 62             if(K4==0)
 63             {
 64                 msta=4;
 65             }
 66         }
 67 }
 68 
 69 char KeyScan1()//矩阵按键
 70 {
 71     KEY_PORT = 0x0f;        // P1.0-1.3输出高电平,P1.4-P1.7输出低电平
 72     if (KEY_PORT != 0x0f)    // 读取KEY_PORT看是否有按键按下
 73     {
 74         delay(10);        // 延时消抖
 75         if (KEY_PORT != 0x0f)        // 确认确实有按键按下
 76         {
 77             // 先确定按键发生在第几列
 78             switch (KEY_PORT)
 79             {
 80                 case 0x07 :    val = 1;     break;
 81                 case 0x0b :    val = 2;    break;
 82                 case 0x0d : val = 3;    break;
 83                 case 0x0e :    val = 4;    break;
 84                 default      :             break;
 85             }
 86 
 87             // 再确定按键发生在第几行
 88             KEY_PORT = 0xf0;
 89             switch (KEY_PORT)
 90             {
 91                 case 0x70:    val = val + 0;    break;
 92                 case 0xb0:    val = val + 4;    break;
 93                 case 0xd0:     val = val + 8;    break;
 94                 case 0xe0:    val = val + 12;    break;
 95             }
 96             return val;    
 97         }        
 98     }
 99     return 0;    
100 }
101 
102 void fmq(int a)//蜂鸣器功能
103 {
104     while(a)
105     {
106         Buz=0;
107         delay(5);
108         Buz=1;
109         delay(5);
110         a--;
111     }
112 }

 

执行独立按键的程序放在dulianjian.h的文件中

 

 1 //dulianjian.h
 2 void work0()//蜂鸣器和灯
 3 {
 4     if(m<=500)
 5     {
 6         Buz = !Buz;
 7     }
 8     if(m>5000)
 9     {
10         led=0xff;
11     }
12     if(m>=10000)
13     {
14         LED = 0;
15         m = 0;
16     }
17 }
18 //-----------------------
19 void work1()
20 {
21     static int s=50000;
22     
23     if(m%500==0)
24     {    
25         LED=0;
26         fmq(500);
27         delay(s=s-1000);
28         LED=1;
29     }
30 }
31 //----------------------
32 void work2()//停止
33 {    
34     LED=1;
35     Buz=0;
36 }
37 void work3()
38 {    
39     
40 }

 

 将矩阵按键的执行代码放在juzhenganjian.h中,同时借用math.h的pow函数来解决移位现象

也可借助https://www.cnblogs.com/action0/p/12642089.html中的思路来写,可大范围的简化代码。

要注意的是,借用第二个方法,要符合端口输入的方式。至于这个,有空再写。

 1 //juzhenganjian.h
  2 
  3 
  4 void work4()//按键1--1个空格
  5 {
  6     if(m>200)
  7     {
  8         led=0xff;
  9         temp=~led;
 10     }
 11     if(m>=32000)
 12     {
 13         for(b=0;b<7;b+=2)//奇数补充
 14         {
 15             temp+=pow(2,b);
 16             led=~temp;
 17             delay(40000);
 18         }
 19         
 20         
 21         m=0;
 22     }
 23     
 24 }
 25 
 26 void work5()//2--2个空格
 27 {
 28     if(m>200)
 29     {
 30         led=0xff;
 31         temp=~led;
 32     }
 33     if(m>=32000)
 34     {
 35         for(b=0;b<8;b+=3)//奇数补充
 36         {
 37             temp+=pow(2,b);
 38             led=~temp;
 39             delay(40000);
 40         }
 41         for(b=1;b<=7;b+=3)//o数补充
 42         {
 43             temp+=pow(2,b);
 44             led=~temp;
 45             delay(40000);
 46         }
 47         for(b=2;b<7;b+=3)//奇数补充
 48         {
 49             temp+=pow(2,b);
 50             led=~temp;
 51             delay(40000);
 52         }
 53         
 54         m=0;
 55     }
 56 }
 57 
 58 void work6()//3--3个空格
 59 {
 60     if(m>200)
 61     {
 62         led=0xff;
 63         temp=~led;
 64     }                                    
 65     if(m>=32000)
 66     {
 67         for(b=0;b<7;b+=4)
 68         {
 69             temp+=pow(2,b);
 70             led=~temp;
 71             delay(40000);
 72         }   
 73         m=0;
 74     }
 75     
 76 }
 77 
 78 void work7()//4--衍生物
 79 {
 80     if(m<500)
 81     {
 82         led=0xff;
 83         led=~temp;
 84     }
 85     if(m%1000==0)
 86     {
 87         temp+=pow(4,j);
 88         led=~temp;
 89     }
 90     if(m>=10000)
 91     {
 92         j++;
 93         m=0;
 94     }
 95 }
 96 
 97 void work8()//5--4个空格
 98 {
 99     if(m>200)
100     {
101         led=0xff;
102         temp=~led;
103     }
104     if(m>=32000)
105     {
106         for(b=0;b<7;b+=5)
107         {
108             temp+=pow(2,b);
109             led=~temp;
110             delay(40000);
111         }
112         
113         for(b=2;b<8;b+=5)
114         {
115             temp+=pow(2,b);
116             led=~temp;
117             delay(40000);
118         }
119         for(b=4;b<8;b+=5)
120         {
121             temp+=pow(2,b);
122             led=~temp;
123             delay(40000);
124         }
125         for(b=1;b<8;b+=5)
126         {
127             temp+=pow(2,b);
128             led=~temp;
129             delay(40000);
130         }
131         for(b=3;b<8;b+=5)
132         {
133             temp+=pow(2,b);
134             led=~temp;
135             delay(40000);
136         }
137         m=0;
138     }
139 }
140 
141 void work9()//6--5个空格
142 {
143     if(m>200)
144     {
145         led=0xff;
146         temp=~led;
147     }
148     if(m>=32000)
149     {
150         for(b=0;b<7;b+=6)
151         {
152             temp+=pow(2,b);
153             led=~temp;
154             delay(40000);
155         }
156         
157         for(b=4;b<8;b+=6)
158         {
159             temp+=pow(2,b);
160             led=~temp;
161             delay(40000);
162         }
163         for(b=2;b<8;b+=6)
164         {
165             temp+=pow(2,b);
166             led=~temp;
167             delay(40000);
168         }
169         m=0;
170     }
171 }
172 void work10()//7--6个空格
173 {
174     if(m>200)
175     {
176         led=0xff;
177         temp=~led;
178     }
179     if(m>=32000)
180     {
181         for(b=0;b<=7;b+=7)
182         {
183             temp+=pow(2,b);
184             led=~temp;
185             delay(40000);
186         }
187         for(b=6;b>0;b--)
188         {
189             temp+=pow(2,b);
190             led=~temp;
191             delay(40000);
192         }
193         m=0;
194     }
195 }
196 
197 void work11()//8--衍生物
198 {
199     led=0XFF;
200       for(j=7;j>0;j--)
201         {
202         led=led-pow(2,j);
203           delay(10000);
204          }
205 }
206 
207 void work12()//9--7个空格
208 {
209     led=0xfe;
210 }
211 
212 void work13()//10--8个空格
213 {
214     if(m>200)
215     {
216         led=0xff;
217         temp=~led;
218     }
219     if(m>=32000)
220     {
221         for(b=0;b<=7;b++)
222         {
223             temp+=pow(2,b);
224             led=~temp;
225             delay(40000);
226         }
227         m=0;
228     }
229 }
230 
231 void work14()//11--9个空格
232 {
233     if(m>200)
234     {
235         led=0xff;
236         temp=~led;
237     }
238     if(m>=32000)
239     {
240         for(b=7;b>=0;b--)
241         {
242             temp+=pow(2,b);
243             led=~temp;
244             delay(40000);
245         }
246         m=0;
247     }
248 }
249 
250 void work15()//12----10个空格时:衍生物
251 {
252     if(m>200)
253     {
254         led=0xff;
255         temp=~led;
256     }
257     if(m>=32000)
258     {
259         for(b=0;b<7;b+=3)
260         {
261             temp+=pow(2,b);
262             led=~temp;
263             delay(40000);
264         }
265         
266         for(b=1;b<8;b+=3)
267         {
268             temp+=pow(2,b);
269             led=~temp;
270             delay(40000);
271         }
272         for(b=2;b<8;b+=3)
273         {
274             temp+=pow(2,b);
275             led=~temp;
276             delay(40000);
277         }
278         m=0;
279     }
280 }
281 
282 void work16()//13:衍生物
283 {
284     if(m>200)
285     {
286         led=0xff;
287         temp=~led;
288     }
289     if(m>=32000)
290     {
291         for(b=0;b<7;b+=2)
292         {
293             temp+=pow(2,b);
294             led=~temp;
295             delay(40000);
296         }
297         m=0;
298     }
299 }
300 
301 void work17()//14
302 {
303     led=0x00;
304 }
305 
306 void work18()//15
307 {
308     
309 }
310 
311 void work19()//16
312 {
313     
314 }

 随后放进main.c的代码中引用它们

//main.c
#include <reg52.h>
#include <intrins.h>
#include <math.h>
#include "qiyu.h"
#include "dulianjian.h"
#include "juzhenganjian.h"


void main()
{     
    ini();//初始化

  while(1)//闭环
        {                
            while(TF0==0);//启动主循环        
              TL0=0x9C;
            TH0=0xFF;
                TF0=0;
            keyscan();    //    键扫描
            KeyScan1();
            m = m+1;
      switch(msta)
                {
                  case 1: work0(); //工作状态0                         
                         break;
                  case 2: work1();// 工作状态1
                         break;
                  case 3: work2(); //工作状态2
                          break; 
                  case 4: work3();
                          break;
                  default: break;
                 }
      switch(val)
                {
                  case 1: work4(); //工作状态0                         
                         break;
                  case 2: work5();// 工作状态1
                         break;
                  case 3: work6(); //工作状态2
                          break; 
                  case 4: work7();
                          break;
                  case 5: work8();
                          break;
                  case 6: work9();
                          break;
                  case 7: work10();
                          break;
                  case 8: work11();
                          break;
                  case 9: work12();
                          break;
                  case 10: work13();
                          break;
                  case 11: work14();
                          break;
                  case 12: work15();
                          break;
                  case 13: work16();
                          break;
                  case 14: work17();
                          break;
                  case 15: work18();
                          break;
                  case 16: work19();
                          break;
                  default: break;
                 }
         }
}

 

------------恢复内容结束------------

以上是关于基于51单片机的独立按键和矩阵按键用法的主要内容,如果未能解决你的问题,请参考以下文章

51单片机实现矩阵键盘行扫描

3.3 51单片机-独立按键

单片机独立按键与矩阵按键

Proteus仿真4X4矩阵按键扫描组成的简易加法器

基于51单片机的电子秒表

基于51单片机的电子秒表