开场白:
上一节讲了按键的加速匀速触发。这节开始讲矩阵键盘的单个触发。
具体内容,请看源代码讲解。
(1)硬件平台:基于朱兆祺51单片机学习板。。
(2)实现功能:16个按键中,每按一个按键都能触发一次蜂鸣器发出“滴”的一声。
(3)源代码讲解如下:
- #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^0; //第一行输入  
- sbit key_sr2=P0^1; //第二行输入  
- sbit key_sr3=P0^2; //第三行输入  
- sbit key_sr4=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=P2^7; //蜂鸣器的驱动IO口  
-   
- 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()//按键扫描函数 放在定时中断里  
- {    
- /* 注释一: 
- *  矩阵按键扫描的详细过程: 
- *  先输出某一列低电平,其它三列输出高电平,这个时候再分别判断输入的四行, 
- *  如果发现哪一行是低电平,就说明对应的某个按键被触发。依次分别输出另外三列 
- *  中的某一列为低电平,再分别判断输入的四行,就可以检测完16个按键。内部详细的 
- *  去抖动处理方法跟我前面讲的独立按键去抖动方法是一样的。 
- */  
-   
-   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&&key_sr4==1)  
-           {    
-              ucKeyStep++;  //如果没有按键按下,切换到下一个运行步骤  
-              ucKeyLock=0;  //按键自锁标志清零  
-              uiKeyTimeCnt=0; //按键去抖动延时计数器清零,此行非常巧妙          
-   
-           }  
-                   else if(ucKeyLock==0)  //有按键按下,且是第一次触发  
-                   {  
-                      if(key_sr1==0&&key_sr2==1&&key_sr3==1&&key_sr4==1)  
-                          {  
-                             uiKeyTimeCnt++;  //去抖动延时计数器  
-                                 if(uiKeyTimeCnt>const_key_time)  
-                                 {  
-                                    uiKeyTimeCnt=0;  
-                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
-                                    ucKeySec=1;  //触发1号键 对应朱兆祺学习板的S1键  
-                                 }  
-                            
-                          }  
-                      else if(key_sr1==1&&key_sr2==0&&key_sr3==1&&key_sr4==1)  
-                          {  
-                             uiKeyTimeCnt++;  //去抖动延时计数器  
-                                 if(uiKeyTimeCnt>const_key_time)  
-                                 {  
-                                    uiKeyTimeCnt=0;  
-                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
-                                    ucKeySec=5;  //触发5号键 对应朱兆祺学习板的S5键  
-                                 }  
-                            
-                          }  
-                      else if(key_sr1==1&&key_sr2==1&&key_sr3==0&&key_sr4==1)  
-                          {  
-                             uiKeyTimeCnt++;  //去抖动延时计数器  
-                                 if(uiKeyTimeCnt>const_key_time)  
-                                 {  
-                                    uiKeyTimeCnt=0;  
-                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
-                                    ucKeySec=9;  //触发9号键 对应朱兆祺学习板的S9键  
-                                 }  
-                            
-                          }  
-                      else if(key_sr1==1&&key_sr2==1&&key_sr3==1&&key_sr4==0)  
-                          {  
-                             uiKeyTimeCnt++;  //去抖动延时计数器  
-                                 if(uiKeyTimeCnt>const_key_time)  
-                                 {  
-                                    uiKeyTimeCnt=0;  
-                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
-                                    ucKeySec=13;  //触发13号键 对应朱兆祺学习板的S13键  
-                                 }  
-                            
-                          }  
-                     
-                   }  
-               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&&key_sr4==1)  
-           {    
-              ucKeyStep++;  //如果没有按键按下,切换到下一个运行步骤  
-              ucKeyLock=0;  //按键自锁标志清零  
-              uiKeyTimeCnt=0; //按键去抖动延时计数器清零,此行非常巧妙          
-   
-           }  
-                   else if(ucKeyLock==0)  //有按键按下,且是第一次触发  
-                   {  
-                      if(key_sr1==0&&key_sr2==1&&key_sr3==1&&key_sr4==1)  
-                          {  
-                             uiKeyTimeCnt++;  //去抖动延时计数器  
-                                 if(uiKeyTimeCnt>const_key_time)  
-                                 {  
-                                    uiKeyTimeCnt=0;  
-                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
-                                    ucKeySec=2;  //触发2号键 对应朱兆祺学习板的S2键  
-                                 }  
-                            
-                          }  
-                      else if(key_sr1==1&&key_sr2==0&&key_sr3==1&&key_sr4==1)  
-                          {  
-                             uiKeyTimeCnt++;  //去抖动延时计数器  
-                                 if(uiKeyTimeCnt>const_key_time)  
-                                 {  
-                                    uiKeyTimeCnt=0;  
-                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
-                                    ucKeySec=6;  //触发6号键 对应朱兆祺学习板的S6键  
-                                 }  
-                            
-                          }  
-                      else if(key_sr1==1&&key_sr2==1&&key_sr3==0&&key_sr4==1)  
-                          {  
-                             uiKeyTimeCnt++;  //去抖动延时计数器  
-                                 if(uiKeyTimeCnt>const_key_time)  
-                                 {  
-                                    uiKeyTimeCnt=0;  
-                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
-                                    ucKeySec=10;  //触发10号键 对应朱兆祺学习板的S9键  
-                                 }  
-                            
-                          }  
-                      else if(key_sr1==1&&key_sr2==1&&key_sr3==1&&key_sr4==0)  
-                          {  
-                             uiKeyTimeCnt++;  //去抖动延时计数器  
-                                 if(uiKeyTimeCnt>const_key_time)  
-                                 {  
-                                    uiKeyTimeCnt=0;  
-                                    ucKeyLock=1;//自锁按键置位,避免一直触发,只有松开按键,此标志位才会被清零  
-                                    ucKeySec=14;  //触发14号键 对应朱兆祺学习板的S13键  
-                                 }  
-                            
-                          }  
-                     
-                   }  
-               break;  
-   
-      case 7:   //按键扫描输出第三列低电平  
-           key_dr1=1;        
-           key_dr2=1;  
-           key_dr3=0;      
-           key_dr4=1;  
-   
-           uiKeyTimeCnt=0;  //延时计数器清零  
-           ucKeyStep++;     //切换到下一个运行步骤  
-               break;  
-  
(下半部分http://www.eeskill.com/group/topic_scan/id/489)