• 基于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;
                     }
             }
    }

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

  • 相关阅读:
    DELPHI 画报表 画表头 stringgrid控件
    蜂巢 Thinking in Agile 我们需要怎样的软件过程(1)
    小博一周年了 将开源进行到底
    Windows Mobile下实现图片的3D效果
    蜂巢 Thinking in Agile 我们需要怎样的软件过程(2)
    Windows 中各种 dll 的导出功能
    以下代码中的两个sizeof用法有问题吗?
    sizeof和strlen
    以下反向遍历array数组的方法有什么错误?
    找错题
  • 原文地址:https://www.cnblogs.com/action0/p/12668897.html
Copyright © 2020-2023  润新知