第十四节:矩阵键盘的单个触发。(上)

开场白:

上一节讲了按键的加速匀速触发。这节开始讲矩阵键盘的单个触发。

具体内容,请看源代码讲解。

(1)硬件平台:基于朱兆祺51单片机学习板。。

(2)实现功能:16个按键中,每按一个按键都能触发一次蜂鸣器发出“滴”的一声。

(3)源代码讲解如下:

  1. #include "REG52.H"  
  2.   
  3. #define const_voice_short  40   //蜂鸣器短叫的持续时间  
  4.   
  5. #define const_key_time  20    //按键去抖动延时的时间  
  6.   
  7. void initial_myself();      
  8. void initial_peripheral();  
  9. void delay_long(unsigned int uiDelaylong);  
  10. void T0_time();  //定时中断函数  
  11. void key_service(); //按键服务的应用程序  
  12. void key_scan(); //按键扫描函数 放在定时中断里  
  13.   
  14. sbit key_sr1=P0^0; //第一行输入  
  15. sbit key_sr2=P0^1; //第二行输入  
  16. sbit key_sr3=P0^2; //第三行输入  
  17. sbit key_sr4=P0^3; //第四行输入  
  18.   
  19. sbit key_dr1=P0^4; //第一列输出  
  20. sbit key_dr2=P0^5; //第二列输出  
  21. sbit key_dr3=P0^6; //第三列输出  
  22. sbit key_dr4=P0^7; //第四列输出  
  23.   
  24. sbit beep_dr=P2^7; //蜂鸣器的驱动IO口  
  25.   
  26. unsigned char ucKeyStep=1;  //按键扫描步骤变量  
  27.   
  28. unsigned char ucKeySec=0;   //被触发的按键编号  
  29. unsigned int  uiKeyTimeCnt=0; //按键去抖动延时计数器  
  30. unsigned char ucKeyLock=0; //按键触发后自锁的变量标志  
  31.   
  32.   
  33. unsigned int  uiVoiceCnt=0;  //蜂鸣器鸣叫的持续时间计数器  
  34.   
  35. void main()   
  36.   {  
  37.    initial_myself();    
  38.    delay_long(100);     
  39.    initial_peripheral();   
  40.    while(1)    
  41.    {   
  42.        key_service(); //按键服务的应用程序  
  43.    }  
  44.   
  45. }  
  46.   
  47. void key_scan()//按键扫描函数 放在定时中断里  
  48. {    
  49. /* 注释一: 
  50. *  矩阵按键扫描的详细过程: 
  51. *  先输出某一列低电平,其它三列输出高电平,这个时候再分别判断输入的四行, 
  52. *  如果发现哪一行是低电平,就说明对应的某个按键被触发。依次分别输出另外三列 
  53. *  中的某一列为低电平,再分别判断输入的四行,就可以检测完16个按键。内部详细的 
  54. *  去抖动处理方法跟我前面讲的独立按键去抖动方法是一样的。 
  55. */  
  56.   
  57.   switch(ucKeyStep)  
  58.   {  
  59.      case 1:   //按键扫描输出第一列低电平  
  60.           key_dr1=0;        
  61.           key_dr2=1;  
  62.           key_dr3=1;      
  63.           key_dr4=1;  
  64.   
  65.           uiKeyTimeCnt=0;  //延时计数器清零  
  66.           ucKeyStep++;     //切换到下一个运行步骤  
  67.               break;  
  68.   
  69.      case 2:     //此处的小延时用来等待刚才列输出信号稳定,再判断输入信号。不是去抖动延时。  
  70.           uiKeyTimeCnt++;  
  71.                   if(uiKeyTimeCnt>1)  
  72.                   {  
  73.                      uiKeyTimeCnt=0;  
  74.              ucKeyStep++;     //切换到下一个运行步骤  
  75.                   }  
  76.               break;  
  77.   
  78.      case 3:  
  79.           if(key_sr1==1&&key_sr2==1&&key_sr3==1&&key_sr4==1)  
  80.           {    
  81.              ucKeyStep++;  //如果没有按键按下,切换到下一个运行步骤  
  82.              ucKeyLock=0;  //按键自锁标志清零  
  83.              uiKeyTimeCnt=0; //按键去抖动延时计数器清零,此行非常巧妙          
  84.   
  85.           }  
  86.                   else if(ucKeyLock==0)  //有按键按下,且是第一次触发  
  87.                   {  
  88.                      if(key_sr1==0&&key_sr2==1&&key_sr3==1&&key_sr4==1)  
  89.                          {  
  90.                             uiKeyTimeCnt++;  //去抖动延时计数器  
  91.                                 if(uiKeyTimeCnt>const_key_time)  
  92.                                 {  
  93.                                    uiKeyTimeCnt=0;  
  94.                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
  95.                                    ucKeySec=1;  //触发1号键 对应朱兆祺学习板的S1键  
  96.                                 }  
  97.                            
  98.                          }  
  99.                      else if(key_sr1==1&&key_sr2==0&&key_sr3==1&&key_sr4==1)  
  100.                          {  
  101.                             uiKeyTimeCnt++;  //去抖动延时计数器  
  102.                                 if(uiKeyTimeCnt>const_key_time)  
  103.                                 {  
  104.                                    uiKeyTimeCnt=0;  
  105.                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
  106.                                    ucKeySec=5;  //触发5号键 对应朱兆祺学习板的S5键  
  107.                                 }  
  108.                            
  109.                          }  
  110.                      else if(key_sr1==1&&key_sr2==1&&key_sr3==0&&key_sr4==1)  
  111.                          {  
  112.                             uiKeyTimeCnt++;  //去抖动延时计数器  
  113.                                 if(uiKeyTimeCnt>const_key_time)  
  114.                                 {  
  115.                                    uiKeyTimeCnt=0;  
  116.                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
  117.                                    ucKeySec=9;  //触发9号键 对应朱兆祺学习板的S9键  
  118.                                 }  
  119.                            
  120.                          }  
  121.                      else if(key_sr1==1&&key_sr2==1&&key_sr3==1&&key_sr4==0)  
  122.                          {  
  123.                             uiKeyTimeCnt++;  //去抖动延时计数器  
  124.                                 if(uiKeyTimeCnt>const_key_time)  
  125.                                 {  
  126.                                    uiKeyTimeCnt=0;  
  127.                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
  128.                                    ucKeySec=13;  //触发13号键 对应朱兆祺学习板的S13键  
  129.                                 }  
  130.                            
  131.                          }  
  132.                     
  133.                   }  
  134.               break;  
  135.   
  136.      case 4:   //按键扫描输出第二列低电平  
  137.           key_dr1=1;        
  138.           key_dr2=0;  
  139.           key_dr3=1;      
  140.           key_dr4=1;  
  141.   
  142.           uiKeyTimeCnt=0;  //延时计数器清零  
  143.           ucKeyStep++;     //切换到下一个运行步骤  
  144.               break;  
  145.   
  146.      case 5:     //此处的小延时用来等待刚才列输出信号稳定,再判断输入信号。不是去抖动延时。  
  147.           uiKeyTimeCnt++;  
  148.                   if(uiKeyTimeCnt>1)  
  149.                   {  
  150.                      uiKeyTimeCnt=0;  
  151.              ucKeyStep++;     //切换到下一个运行步骤  
  152.                   }  
  153.               break;  
  154.   
  155.      case 6:  
  156.           if(key_sr1==1&&key_sr2==1&&key_sr3==1&&key_sr4==1)  
  157.           {    
  158.              ucKeyStep++;  //如果没有按键按下,切换到下一个运行步骤  
  159.              ucKeyLock=0;  //按键自锁标志清零  
  160.              uiKeyTimeCnt=0; //按键去抖动延时计数器清零,此行非常巧妙          
  161.   
  162.           }  
  163.                   else if(ucKeyLock==0)  //有按键按下,且是第一次触发  
  164.                   {  
  165.                      if(key_sr1==0&&key_sr2==1&&key_sr3==1&&key_sr4==1)  
  166.                          {  
  167.                             uiKeyTimeCnt++;  //去抖动延时计数器  
  168.                                 if(uiKeyTimeCnt>const_key_time)  
  169.                                 {  
  170.                                    uiKeyTimeCnt=0;  
  171.                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
  172.                                    ucKeySec=2;  //触发2号键 对应朱兆祺学习板的S2键  
  173.                                 }  
  174.                            
  175.                          }  
  176.                      else if(key_sr1==1&&key_sr2==0&&key_sr3==1&&key_sr4==1)  
  177.                          {  
  178.                             uiKeyTimeCnt++;  //去抖动延时计数器  
  179.                                 if(uiKeyTimeCnt>const_key_time)  
  180.                                 {  
  181.                                    uiKeyTimeCnt=0;  
  182.                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
  183.                                    ucKeySec=6;  //触发6号键 对应朱兆祺学习板的S6键  
  184.                                 }  
  185.                            
  186.                          }  
  187.                      else if(key_sr1==1&&key_sr2==1&&key_sr3==0&&key_sr4==1)  
  188.                          {  
  189.                             uiKeyTimeCnt++;  //去抖动延时计数器  
  190.                                 if(uiKeyTimeCnt>const_key_time)  
  191.                                 {  
  192.                                    uiKeyTimeCnt=0;  
  193.                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
  194.                                    ucKeySec=10;  //触发10号键 对应朱兆祺学习板的S9键  
  195.                                 }  
  196.                            
  197.                          }  
  198.                      else if(key_sr1==1&&key_sr2==1&&key_sr3==1&&key_sr4==0)  
  199.                          {  
  200.                             uiKeyTimeCnt++;  //去抖动延时计数器  
  201.                                 if(uiKeyTimeCnt>const_key_time)  
  202.                                 {  
  203.                                    uiKeyTimeCnt=0;  
  204.                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
  205.                                    ucKeySec=14;  //触发14号键 对应朱兆祺学习板的S13键  
  206.                                 }  
  207.                            
  208.                          }  
  209.                     
  210.                   }  
  211.               break;  
  212.   
  213.      case 7:   //按键扫描输出第三列低电平  
  214.           key_dr1=1;        
  215.           key_dr2=1;  
  216.           key_dr3=0;      
  217.           key_dr4=1;  
  218.   
  219.           uiKeyTimeCnt=0;  //延时计数器清零  
  220.           ucKeyStep++;     //切换到下一个运行步骤  
  221.               break;  
  222.  

(下半部分http://www.eeskill.com/group/topic_scan/id/489

永不止步步 发表于11-19 21:42 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67417个|学分:363791个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号