zoukankan      html  css  js  c++  java
  • 矩阵键盘的单个出发---代码简单,但是代码量较大,下一例将给出压缩后的代码

    /***12个按键,每一个按键都会让蜂鸣器发出“嘀”的一声***/
    #include "REG52.H"
    #define const_voice_short 40
    #define const_key_time 20
    void initial_myself();
    void initial_peripheral();
    void delay_long(unsigned int uiDelaylong);
    void T0_time();
    void key_service();
    void key_scan();
     
    sbit key_sr1=P0^1; //第一行输入
    sbit key_sr2=P0^2; //第二行输入
    sbit key_sr3=P0^3; //第三行输入
    sbit key_dr1=P0^4; //第一列输出
    sbit key_dr2=P0^5; //第二列输出
    sbit key_dr3=P0^6; //第三列输出
    sbit key_dr4=P0^7; //第四列输出
    sbit beep_dr=P1^5;
    unsigned char ucKeyStep=1; //按键扫描步骤变量
    unsigned char ucKeySec=0; //被触发的按键编号
    unsigned int uiKeyTimeCnt=0; //按键去抖动延时计数器
    unsigned char ucKeyLock=0; //按键触发后自锁的变量标志
    unsigned int uiVoiceCnt=0; //蜂鸣器鸣叫的时间计数器
    void main()
    {
     initial_myself();
     delay_long(100);
     initial_peripheral();
     while(1)
     {
      key_service();
     }
    }
    void key_scan()  //按键扫描函数,放到定时中断里
    {
     /*
      按键扫描的详细过程:
      先输出某一列低电平,其他三列输出高电平,这个时候再分别判断输入的三行,
      如果发现哪一行是低电平,就说明对应的某个按键被触发。
      依次分别输出另外三列中的某一列为低电平,再分别判断输入的三行,就可以检测完12个按键。
     */
     switch(ucKeyStep)
     {
      case 1:  //按键扫描,输出的第一列为低电平
       key_dr1=0;
       key_dr2=1;
       key_dr3=1;
       key_dr4=1;
       
       uiKeyTimeCnt=0;  //延时计数器清零
       ucKeyStep++;  //切换到下一个运行步骤
       break;
       
      case 2:  //此处的小延时用来等待刚才列输出信号稳定,再判断输入信号。不是去抖动延时
       uiKeyTimeCnt++;
       if(uiKeyTimeCnt>1)
       {
        uiKeyTimeCnt=0;
        ucKeyStep++; //切换到下一个运行步骤
       }
       break;
       
      case 3:
       if(key_sr1==1&&key_sr2==1&&key_sr3==1)
       {
        ucKeyStep++; //如果没有按键按下,切换到下一个运行步骤
        ucKeyLock=0; //按键自锁标志清零
        uiKeyTimeCnt=0; //按键去抖动延时清零,此行非常巧妙
       }
       else if(ucKeyLock==0) //如果有按键按下,且是第一次触发
       {
        if(key_sr1==0&&key_sr2==1&&key_sr3==1)
        {
         uiKeyTimeCnt++; //去抖动延时
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1; //自锁标志置位,以免一直触发,只有松开按键,此标志位才会被清零
          ucKeySec=1;  //触发1号键
         }
        }
        else if(key_sr1==1&&key_sr2==0&&key_sr3==1)
        {
         uiKeyTimeCnt++; //去抖动延时
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1; //自锁标志置位,以免一直触发,只有松开按键,此标志位才会被清零
          ucKeySec=5;  //触发5号键
         }
        }
        else if(key_sr1==1&&key_sr2==1&&key_sr3==0)
        {
         uiKeyTimeCnt++; //去抖动延时
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1; //自锁标志置位,以免一直触发,只有松开按键,此标志位才会被清零
          ucKeySec=9;  //触发9号键
         }
        }
       }
       break;
       
      case 4:  //按键扫描输出第二列低电平
       key_dr1=1;
       key_dr2=0;
       key_dr3=1;
       key_dr4=1;
       
       uiKeyTimeCnt=0;
       ucKeyStep++;
       break;
       
      case 5:
       uiKeyTimeCnt++;
       if(uiKeyTimeCnt>1)
       {
        uiKeyTimeCnt=0;
        ucKeyStep++;
       }
       break;
       
      case 6:
       if(key_sr1==1&&key_sr2==1&&key_sr3==1)
       {
        ucKeyStep++;
        ucKeyLock=0;
        uiKeyTimeCnt=0;
       }
       else if(ucKeyLock==0)
       {
        if(key_sr1==0&&key_sr2==1&&key_sr3==1)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=2;
         }
        }
        else if(key_sr1==1&&key_sr2==0&&key_sr3==1)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=6;
         }
        }
        if(key_sr1==1&&key_sr2==1&&key_sr3==0)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=10;
         }
        }
       }
       break;
      case 7:  //按键扫描输出第三列低电平
       key_dr1=1;
       key_dr2=1;
       key_dr3=0;
       key_dr4=1;
       
       uiKeyTimeCnt=0; 
       ucKeyStep++;
       break;
      
      case 8:
       uiKeyTimeCnt++;
       if(uiKeyTimeCnt>1)
       {
        uiKeyTimeCnt=0;
        ucKeyStep++;
       }
       break;
      
      case 9:
       if(key_sr1==1&&key_sr2==1&&key_sr3==1)
       {
        ucKeyStep++;
        ucKeyLock=0;
        uiKeyTimeCnt=0;
       }
       else if(ucKeyLock==0)
       {
        if(key_sr1==0&&key_sr2==1&&key_sr3==1)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=3;
         }
        }
        else if(key_sr1==1&&key_sr2==0&&key_sr3==1)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=7;
         }
        }
        else if(key_sr1==1&&key_sr2==1&&key_sr3==0)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=11;
         }
        }
       }
       break;
      case 10: //按键扫描输出第四列低电平
       key_dr1=1;
       key_dr2=1;
       key_dr3=1;
       key_dr4=0;
       
       uiKeyTimeCnt=0;
       ucKeyStep++;
       break;
       
      case 11:
       uiKeyTimeCnt++;
       if(uiKeyTimeCnt>1)
       {
        uiKeyTimeCnt=0;
        ucKeyStep++;
       }
       break;
       
      case 12:
       if(key_sr1==1&&key_sr2==1&&key_sr3==1)
       {
        ucKeyStep=1; //如果没有按键按下,返回到第一步,重新开始扫描
        ucKeyLock=0; //按键自锁标志清零
        uiKeyTimeCnt=0;
       }
       else if(ucKeyLock==0)
       {
        if(key_sr1==0&&key_sr2==1&&key_sr3==1)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=4;
         }
        }
        else if(key_sr1==1&&key_sr2==0&&key_sr3==1)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=8;
         }
        }
        else if(key_sr1==1&&key_sr2==1&&key_sr3==0)
        {
         uiKeyTimeCnt++;
         if(uiKeyTimeCnt>const_key_time)
         {
          uiKeyTimeCnt=0;
          ucKeyLock=1;
          ucKeySec=12;
         }
        }
       }
       break;
     }
    }
    void key_service() //第三区,按键服务应用程序
    {
     switch(ucKeySec)
     {
      case 1:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 2:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 3:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 4:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 5:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 6:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 7:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 8:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 9:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 10:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 11:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
      case 12:
       uiVoiceCnt=const_voice_short;
       ucKeySec=0;
       break;
       
     }
    }
    void T0_time() interrupt 1
    {
     TF0=0;
     TR0=0;
     
     key_scan();
     
     if(uiVoiceCnt!=0)
     {
      uiVoiceCnt--;
      beep_dr=0;
     }
     else
     {
      ;
      beep_dr=1;
     }
     TH0=0xf8;
     TL0=0x2f;
     TR0=1;
    }
    void delay_long(unsigned int uiDelayLong)
    {
     unsigned int i;
     unsigned int j;
     for(i=0;i<uiDelayLong;i++)
      for(j=0;j<500;j++)
       ;
    }
    void initial_myself() //第一区,初始化单片机
    {
     beep_dr=1;
     TMOD=0x01; //设定 定时器0 工作方式 1
     
     TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
     TL0=0x2f;
    }
    void initial_peripheral() //第二区,初始化外围
    {
     EA=1;
     ET0=1;
     TR0=1;
    }
     
  • 相关阅读:
    MPS和MRP之间有什么样的关系呢
    java中静态代码块详解
    SQL server 分组后每组取出任意一行
    人是否能成功,其实可能很早就能看出来
    国内外产品经理的区别
    Yarn 和 NPM 国内快速镜像(淘宝镜像)
    vue-cli 使用less 遇到的问题 || vue-cli 使用less
    布隆过滤器
    PHP性能优化
    Redis-高并发代言词,为什么做分布式要Redis?
  • 原文地址:https://www.cnblogs.com/TheFly/p/11988032.html
Copyright © 2011-2022 走看看