4*4矩阵按键扫描程序

下面的程序是本人自己编写的4*4矩阵按键扫描程序,已经成熟应用在具体项目上。需改进处请各位指出。

-----------------------------------------------file "key.h"------------------------------------------------

#ifndef KEY_H
#define KEY_H

/*----------------key definition--------------*/

#define  NO_KEY           0x00

#define  PLAY_KEY         0x01         /*  vcd   key   */
#define  STOP_KEY         0x02
#define  NEXT_KEY         0x03
#define  PREV_KEY         0x04
#define  REPEAT_KEY       0x05
#define  PROGRAM_KEY      0x06
#define  REMAIN_KEY       0x07
#define  VOCAL_ASSIST_KEY 0x08
#define  VOLUME_UP_KEY    0x09
#define  VOLUME_DOWN_KEY  0x0a
#define  TV_MODE_KEY      0x0b
#define  EJECT_KEY        0x0c
#define  FB_KEY           0x0d
#define  FF_KEY           0x0e

#define  POWER_KEY        0x20         /* common key  */
#define  CLOCK_KEY        0x21
#define  SLEEP_KEY        0x22
#define  FUNCTION_KEY     0x23
#define  TONE_KEY         0x24
#define  EQ_KEY           0x25
#define  SBASS_KEY        0x26
#define  RADIO_KEY        0x27
#define  TAPE_KEY         0x28
#define  AUX_KEY          0x29
#define  VCD_KEY          0x30

#define  MEM_KEY          0x31        /*  radio key  */
#define  MEM_MINUS_KEY    0x32
#define  MEM_PLUS_KEY     0x33
#define  AM_STEP_KEY      0x34
#define  BAND_KEY         0x35
#define  SEARCH_UP_KEY    0x36
#define  SEARCH_DOWN_KEY  0x37
#define  AUTO_SEARCH_UP_KEY     0x38
#define  AUTO_SEARCH_DOWN_KEY   0x39

/*---------------end key definition-----------*/

#define  KEY_IDLE_STATE     0
#define  KEY_SHAKE_STATE    1
#define  KEY_COMPLEX_STATE  2
#define  KEY_REPEAT_STATE   3
#define  KEY_WAIT_UP        4


extern unsigned char shake_cancel_timer;
extern unsigned char complex_key_timer;
extern unsigned char repeat_key_timer;
extern unsigned char current_key;
extern unsigned char current_state;

extern void scan_key();
extern void process_panel_key();
extern unsigned char is_repeat_key(unsigned char);

#endif

------------------------------------------------file "key.c"-----------------------------------------------

#include "key.h"
#include "display.h"

unsigned char current_state;    /* RADIO /  VCD  /TAPE /AUX */
unsigned char current_key;
unsigned char key;

unsigned char is_repeat_key(unsigned char);
void scan_key();
void process_panel_key();

/*====================================================================================================
                                    扫描面板按键程序
====================================================================================================*/
void scan_key()
{
   set_row1;
   set_row2;
   set_row3;
   set_row4;
   key = NO_KEY;

   clear_col1;
   set_col2;
   set_col3;
   set_col4;
   if (check_row1_low)     
    {
             key = SEARCH_DOWN_KEY;    
    }  
   if (check_row2_low)    
    {
            key = SEARCH_UP_KEY;  

    }
   if (check_row3_low)   
    {
             key = BAND_KEY;     
    }
   if (check_row4_low)   
    {
             key = EJECT_KEY;    
    }

    set_col1;
    clear_col2;
    set_col3;
    set_col4;
    if (check_row1_low)   
    {
              key = MEM_MINUS_KEY;   
    }  
   if (check_row2_low)  
    {
             key = MEM_PLUS_KEY;
    }
   if (check_row3_low)   
    {  
             key = MEM_KEY;
    }
   if (check_row4_low)  
    {
              key = AM_STEP_KEY;
   }

   set_col1;
   set_col2;
   clear_col3;
   set_col4;
   if (check_row1_low) 
    {
            key = SLEEP_KEY;   
    }  
   if (check_row2_low) 
    {
            key = SBASS_KEY; 
    }
   if (check_row3_low)  
    {
             key = CLOCK_KEY;  
    }
   if (check_row4_low)   
    {
            key = VOLUME_DOWN_KEY;        
     }

   set_col1;
   set_col2;
   set_col3;
   clear_col4;
   if (check_row1_low)  
    {
              key = POWER_KEY;
   }  
   if (check_row2_low)  
    {
              key = FUNCTION_KEY;
    }
   if (check_row3_low)  
    {  
               key = TONE_KEY;  
   }
   if (check_row4_low)   
    {
               key = VOLUME_UP_KEY;
    }
}

/*====================================================================================
                                   处理面板按键程序
=====================================================================================*/
unsigned char shake_cancel_timer;
unsigned char complex_key_timer;
unsigned char repeat_key_timer;
unsigned char scan_key_state;
unsigned char key_bak;
unsigned char repeat_key;


void process_panel_key()
{
     scan_key();
     switch (scan_key_state)
     {
           case KEY_IDLE_STATE:   //按键空闲状态
                             if (key!=NO_KEY)  //如果有按键按下,则进入按键消抖状态。
                              {
                                     key_bak = key;          
                                     shake_cancel_timer = 1;  //消抖时间设定为20ms
                                     scan_key_state = KEY_SHAKE_STATE;
                              }else            //如果没有按键按下,继续为空闲检测状态。
                              {
                                      scan_key_state = KEY_IDLE_STATE;
                              }
                         break;
          case KEY_SHAKE_STATE: //按键去抖状态
                          if (!shake_cancel_timer)
                          {
                                   if (key == key_bak)     //消抖后,如果按键未变,进入复合检测状态。
                                   {
                                            scan_key_state = KEY_COMPLEX_STATE;
                                            complex_key_timer = 100;  //复合判断时间为200ms 小于200ms为原功能,大于200ms为复合功能。
                                    }else                  //确认为按键抖动。
                                    {
                                              scan_key_state = KEY_IDLE_STATE;
                                    }
                         }
                          break;
         case KEY_COMPLEX_STATE: //按键复合处理状态
                            if (!complex_key_timer)
                           {
                                      if (key == key_bak)  //复合检测时间到,按键仍按下。
                                      {
                                                      if (key == SEARCH_UP_KEY)       //执行next的复合功能。
                                                        {
                                                                   current_key = AUTO_SEARCH_UP_KEY;
                                                        }else if (key == SEARCH_DOWN_KEY) //执行prev的复合功能。
                                                        {
                                                                   current_key = AUTO_SEARCH_DOWN_KEY;
                                                        }else                     //执行没有复合功能的按键。
                                                        {
                                                                   current_key = key;
                                                        }

                                                      if (is_repeat_key(key))   //检测为可重复按键时,进入重复状态。
                                                      {
                                                                 repeat_key = current_key;
                                                                 scan_key_state = KEY_REPEAT_STATE;
                                                                 repeat_key_timer = 20; // 按键重复时间为200ms,如果连续按键,每200ms执行重复按键操作。
                                                      }else                    //检测为不可重复按键时,进入按键抬起等待状态。
                                                      {
                                                                 scan_key_state = KEY_WAIT_UP;
                                                      }
                                       }else       //按键已经抬起,执行未复合功能。
                                       {
                                                     current_key = key_bak;
                                                     scan_key_state = KEY_IDLE_STATE;
                                       }
                            }else         
                             {
                                         if (key != key_bak)          //按键抬起,执行未复合功能。
                                         {
                                                   current_key = key_bak;
                                                   scan_key_state = KEY_IDLE_STATE;
                                         }
                             }
                           break;
             case KEY_REPEAT_STATE:    //按键重复处理状态
                            if (key == key_bak)
                            {
                                     if (!repeat_key_timer)    //按键重复时间到,再次执行按键功能。
                                     {
                                             repeat_key_timer = 20; // 按键重复时间为200ms,如果连续按键,每200ms执行重复按键操作。
                                             current_key = repeat_key;
                                     }
                            }else                     //按键抬起,回到按键空闲检测状态。
                           {
                                     scan_key_state = KEY_IDLE_STATE;
                           }
                           break;
           case KEY_WAIT_UP:             //按键等待抬起状态
                          if (key!= key_bak)
                           {
                                     scan_key_state = KEY_IDLE_STATE;   //按键抬起,返回按键空闲检测状态。
                           }
                          break;
           }
}
/*-----------------------------------------------------------------------------------------------------------------*/
unsigned char is_repeat_key(unsigned char r_key)    //重复按键检测通行函数。
{
   if ((r_key == VOLUME_UP_KEY)||(r_key == VOLUME_DOWN_KEY)||(r_key == SEARCH_UP_KEY)||(r_key == SEARCH_DOWN_KEY))
   {
       return 1;
   }else
   {
       return 0;
   }
}
/*----------------------------------------------------------------------------------------------------------------*/

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值