⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 4x4按键,状态机思想.c

📁 该段程序是4*4键盘扫描程序,功能比较全,根据实际情况可在次基础上进行修改;
💻 C
字号:
1、该段程序是4*4键盘扫描程序,功能比较全,根据实际情况可在次基础上进行修改; 
2、已调试通过,但没有优化; 

/********************************************************************* 
文件:scankey.c 
用途:通用4*4按键接口驱动程序 
注意: 
创建:2008.5.15 
修改:2008.5.15 
设计:raosibin 
版本:ver1.3 
功能说明:每隔10MS调用一次 ,实现了组合按键功能;连发功能     
**********************************************************************/ 
#include "..\config.h" 

/********************************************************************* 
       COL0 COL1 COL2 COL3 
* ROW4   0    1    2    3 
* ROW5   4    5    6    7 
* ROW6   8    9    A    B 
* ROW7   C    D    E    F 
*  
* 普通按键: 
* 2~E:数字按键 
*  
* 连发按键: 
* 0: 
* 1: 
*    
* 组合按键 
* F  : 引导键 
* F+0: 
* F+1: 
* 状态机思路 
* F为组合引导键 
* 每10MS扫描一次键盘   

* 状态0:检测是否有键按下;   
* 状态1:消抖处理   
* 状态2:确认按键,同状态1比较,除F引导键外相同则返回键值, 
*       F引导键未按下转状态3;F引导键按下转状态5;   
* 状态3:计数1,(按3S,连发判断);   
* 状态4:计数2,连发功能  

* 状态5:500MS内检测是否有F引导键+其他键按下;有转状态6,没有转状态8  
* 状态6:消抖处理  
* 状态7:同状态6比较,确认组合按键,返回组合键值,转状态3  
* 状态8:消抖处理  
* 状态9:先导键为单按键,返键值,转状态3.  
**********************************************************************/ 
//按键初始化 
void key_board_int1(void) 
{ 
 KEY_DDR_ROW   |=  KEY_ROW_ALL;                                                              //行输出, 
 KEY_PORT_ROW  &=~ KEY_ROW_ALL; 
 KEY_DDR_COL   &=~ KEY_COL_ALL;                                                              //列输入,并使能内部上拉 
 KEY_PORT_COL  |=  KEY_COL_ALL; 
} 

void key_board_int2(void)                                                                             //翻转初始化 
{ 
 KEY_DDR_ROW   &=~ KEY_ROW_ALL;                                                              //行输入,并使能内部上拉 
 KEY_PORT_ROW  |=  KEY_ROW_ALL; 
 KEY_DDR_COL   |=  KEY_COL_ALL;                                                              //列输出; 
 KEY_PORT_COL  &=~ KEY_COL_ALL; 
} 

unsigned char key_board_scan(void) 
{ 
        unsigned key_value_buf; 
        key_board_int1(); 
        KEY_PORT_ROW &=~ KEY_ROW_ALL;                                                        // 必须送2次!!! 
        key_value_buf = (~KEY_ROW_ALL) & KEY_PIN_COL;                                           // 读列电平 
                                     
        key_board_int2();                                                                          // 翻转扫描 
        KEY_PORT_COL  &=~ KEY_COL_ALL; 
        key_value_buf |= (~KEY_COL_ALL) & KEY_PIN_ROW;                                              // 读行电平,并同翻转前的结果或 
        return key_value_buf; 
} 

char read_keyboard() 
{         
static char key_state = 0,  key_value1,key_value2,key_value3,key_value4,key_value5; 
static char key_value6,key_value7,key_value8,key_value9; 
static unsigned int key_time = 0; 
char key_return = No_key; 

        switch (key_state) 
        { 
                case 0:                                                                         // 判断是否有键按下 
                        if (key_board_scan() != No_key) 
                        { 
                                key_state = 1;                                           // 有按键 
                                break;                                                 // 转消抖确认状态 
                        } 
                        break; 
                         
                case 1:                                                                         // 消抖处理 
                        if (++key_time >= 1)                                                  // 改变判断条件可改变键盘灵敏度 
                                {            
                            key_value1 = key_board_scan(); 
                            if (key_value1 != No_key) 
                                    { 
                                            key_state = 2; 
                                            break; 
                                    } 
                            key_state = 0; 
                            break; 
                    } 
                    break; 
                     
             case 2:                                                                              // 确认按键,同状态1比较 
                  key_value2 = key_board_scan();                                                          
                if (key_value2 == key_value1)                                                  // 再次扫描, 
                        {         
                                if (key_value2 != 0b01110111)                          // 是否为引导键F,是则转状态5 
                                  { 
                                    switch (key_value2)                                       // 与状态1的相同,确认按键 
                                    {                                             // 键盘编码,返回编码值  
                                            case 0b11101110: 
                                                    key_return = K1_1;                // 0; 
                                                    break; 
                                            case 0b11101101: 
                                                    key_return = K1_2;                // 1 
                                                    break; 
                                             case 0b11101011: 
                                                    key_return = K1_3; 
                                                    break; 
                                             case 0b11100111: 
                                                    key_return = K1_4; 
                                                    break; 
                                             case 0b11011110: 
                                                    key_return = K2_1; 
                                                    break; 
                                            case 0b11011101: 
                                                    key_return = K2_2; 
                                                    break; 
                                             case 0b11011011: 
                                                    key_return = K2_3; 
                                                    break; 
                                             case 0b11010111: 
                                                    key_return = K2_4; 
                                                    break; 
                                            case 0b10111110: 
                                                    key_return = K3_1; 
                                                    break; 
                                             case 0b10111101: 
                                                    key_return = K3_2; 
                                                    break; 
                                             case 0b10111011: 
                                                    key_return = K3_3; 
                                                    break; 
                                            case 0b10110111: 
                                                    key_return = K3_4; 
                                                    break; 
                        case 0b01111110: 
                                                    key_return = K4_1; 
                                                    break; 
                                             case 0b01111101: 
                                                    key_return = K4_2; 
                                                    break; 
                                             case 0b01111011: 
                                                    key_return = K4_3; 
                                                    break; 
                       default: 
                       break; 
                                     } 
                                     key_state = 3;                                                // 转入等待按键释放状态 
                                     key_time = 0;                                                       // 清0按键时间计数器 
                                         break; 
                              } 
                                else 
                                { 
                            key_state = 5; 
                                key_time = 0; 
                            break; 
                                } 
                }                 
                        else 
                                key_state = 0;                                                // 两次列电平不同返回状态0,(消抖处理) 
                    break;         
                                                         
        case 3:                                                                                   // 计数1,(按3S,连发判断)                   
                key_value3 = key_board_scan();                 
                if ( key_value3 == No_key) 
                        key_state=0;                                                    // 按键已释放,转换到按键初始态 
                        else if ((key_value3 == 0b11100111)||(key_value3 == 0b11011110))          // 改变此判断条件,可以确定 
                          {                                                                       // 哪些键具备加速功能,3,4加速 
                            if (++key_time >= 300)                                               // 按键时间计数 
                              { 
                                    key_state = 4;                                                  // 按下时间>3s,状态转换到计时2 
                                    key_time = 0;                                                 // 清按键计数器 
                                    key_return = KJ;                                             // 输出“18” 
                              } 
                        break; 
                          } 
                break; 
                         
        case 4:                                                                                         // 计数2,连发功能            
           key_value4 = key_board_scan();                    
           if ( key_value4 == No_key) 
                        key_state=0;                                                     // 按键已释放,转换到按键初始态 
                        else if (++key_time >= 20)                                                // 按键时间计数 
                        { 
                                key_time = 0;                                                 // 清按键计数器 
                                key_return = KJ;                                             // 输出“18” 
                                break; 
                        } 
          break; 
           
        case 5:                                                               // 检测是否有F引导键+其他键按下;有转状态6,没有转状态8 
    key_value5 = key_board_scan();            
    if (key_value5 == key_value2) 
            { 
              if (++key_time >= 50)                                               // 500MS到了吗?未到,状态5,不断扫描,到了,状态8 
                      { 
                              key_state = 8; 
                              key_time = 0; 
                              break; 
                      } 
                        break; 
            } 
        else 
                { 
            key_state = 6; 
                break; 
                } 
                break; 
        case 6:                                                               // 消抖处理 
                key_value6 = key_board_scan(); 
                key_state = 7; 
                break; 
        case 7:                                                              // 同状态6比较,确认组合按键,返回组合键值,转状态3 
                key_value7 = key_board_scan(); 
                if (key_value7 == key_value6) 
                        { 
                          switch (key_value7) 
                          { 
                                  case 0b01100110: 
                                    key_return = KF_0;                   // 组合按键F+0 
                                    break; 
                        case 0b01100101: 
                              key_return = KF_1;                           // 组合按键F+1 
                                    break;                 
                    } 
                    key_state = 3; 
      } 
                break; 
        case 8:                                                            //  消抖处理 
                key_value8 = key_board_scan(); 
                key_state = 9; 
                break;         
        case 9:                                                             // 同状态8比较,确认单按键,返键值,转状态3 
                key_value9 = key_board_scan(); 
            if (key_value9 == key_value8) 
            { 
                    key_return = K4_4; 
                    key_state = 3; 
                    break; 
            } 
            key_state = 0; 
                  break; 
  default: 
    break; 
} 
return key_return; 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -