amoBBS 阿莫电子论坛

 找回密码
 注册
搜索
bottom↓
查看: 37785|回复: 233

4*4按键,状态机思想:定时扫描+多键组合+连_发功能(具有实际应用意义)

  [复制链接]
发表于 2008-5-16 22:45:24 | 显示全部楼层 |阅读模式
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;
}
发表于 2008-5-16 23:54:52 | 显示全部楼层
先收下看看,谢谢楼主
发表于 2008-5-17 09:41:26 | 显示全部楼层
记号
 楼主| 发表于 2008-5-17 15:06:06 | 显示全部楼层
咋就没人讨论下呢?是太简单了吗?希望能听到些批评指点的声音...................
发表于 2008-5-17 21:04:51 | 显示全部楼层
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;         

编程能力需要提高,比如在上面的代码中,每个ELAE中,怎么都使用BREAK?

给个优化的参考:

#defien K1_1 0B11101110
#defien K1_2 0b11101101
......
......
#define K_pre 0b01110111

case 2:                                                // 确认按键,同状态1比较
   key_value2 = key_board_scan();                                                         
   if (key_value2 == key_value1)                                                  // 再次扫描,
   {         
       key_time = 0;
       if (key_value2 != K_pre)                          // 是否为引导键F,是则转状态5
       {
           key_return = key_value2;                      // 与状态1的相同,确认按键
           key_state = 3;                                // 转入等待按键释放状态
       }
       else
       {
           key_state = 5;
       }
   }                 
   else
   {
        key_state = 0;                 // 两次列电平不同返回状态0,(消抖处理)
   }
   break;  

==========================
主程序中:

key_temp = read_keyboard();
switch (key_temp)
{
   case K1_1:
       // K1_1的键处理
       break;
   case K1_2:
       ......

}
 楼主| 发表于 2008-5-17 21:53:40 | 显示全部楼层
谢谢,老师,在体会之中............
发表于 2008-5-18 02:59:07 | 显示全部楼层
状态8没有必要,可以取消掉.
发表于 2008-5-21 12:45:42 | 显示全部楼层
我是来学多键组合的,留个记号在这里方便回来查找
发表于 2008-5-30 08:59:25 | 显示全部楼层
多键组合
发表于 2008-5-31 21:55:59 | 显示全部楼层
记号
发表于 2008-5-31 22:50:00 | 显示全部楼层
可不可以把按键编码那里的代码用查表的方式来解决呢?
我是这么做的:

//按键值表
const uchar key_value[] PROGMEM ={
0x0f,0xff,0xff,0xff,0x01,0xff,0x04,0x07,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0xff,0xff,0xff,0x02,0xff,0x05,0x08,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x0e,0xff,0xff,0xff,0x03,0xff,0x06,0x09,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x0d,0xff,0xff,0xff,0x0c,0xff,0x0b,0x0a
};

//按键检测,返回值为0xff表示无效按键
uchar key (void)
{
   uchar key_x,key_y;

   keyline_PORT=0x0f;               //置为高4位输出0,低4位上拉输入
   keyline_DDR=0xf0;
   nop;nop;
   
   key_x=keyline_PIN;
   if ((key_x&0x0f)!=0x0f)
    {
          delay_ms (10);                 //延时10MS
          
          key_x=keyline_PIN;
          if ((key_x&0x0f)!=0x0f)
            key_x&=0x0f;                //保存低4位有效值
          else
            return 0xff;
          
          keyline_PORT=0xf0;            //置为高4位上拉输入,低4位输出0
      keyline_DDR=0x0f;
      nop;nop;
          
          key_y=keyline_PIN;
          if ((key_y&0xf0)!=0xf0)
           {
             key_y&=0xf0;                //保存高4位有效值
                 //key_x|=key_y;
              return (pgm_read_byte (key_value+(key_x|key_y)-0x77));
           }
          else
            return 0xff;
        }
   else
     return 0xff;
}
 楼主| 发表于 2008-6-4 16:56:57 | 显示全部楼层
楼上
这也是一种思路,学习学习;

pgm_read_byte (key_value+(key_x|key_y)-0x77));
什么意思啊?你的键值表也太长了吧?呵呵

楼上你是不是省了几个大括号啊?这个方法不能实现连_发和组合功能吧?
发表于 2008-6-5 22:04:38 | 显示全部楼层
学习了
发表于 2008-6-5 23:19:48 | 显示全部楼层
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;
}

uchar read_keypad( void )
{//10ms 读一次
  static uchar preKey = 0, curKey, keytimes = 0;
  uchar keyCode = noKey;

  curKey = key_board_scan();

  if ( curKey != noKey )
    { //可能有键按下

      if ( preKey == curKey )
        { //同一按键消抖
          keytimes++;

          if ( ( keytimes % 5 ) == 0 )
            { //50ms 短按或加速键 时间自已把握
             // keyCode = shortpush|preKey;
            }

        /*  if ( keytimes > 100 )
            {
              keytimes = ( 101 ); //锁定 长按
             // keyCode = longpush|preKey;
             //keyCode =
            }*/
            
            return keycode;
        }


      else if ( preKey != curKey )
        { //不同按键按下
          {
            keytimes = 0;
            preKey = curKey;
            
          }
        }

    }

       else
       { //键已释放,或无键按下
        keytimes = 0;
        return keyCode;
       }


}


/*
实现短按键 长按键或加速键
能不能实现长按与加速功能呢
*/
发表于 2008-6-5 23:21:54 | 显示全部楼层
键值获得与处理就不写了,以上按键可以实现加速键功能,不知道能不能一起实现长按功能,希各高手指点
发表于 2008-6-6 05:20:28 | 显示全部楼层
学习
 楼主| 发表于 2008-6-9 15:45:06 | 显示全部楼层
F键就是包括了长按的功能啊
发表于 2008-6-14 11:37:13 | 显示全部楼层
看了思路,程序还没仔细看。
提点建议:将“F引导键”作无效键,“F引导键+其他键”作有效键,等同单按键,“状态5的500MS”可以去掉。简化后如下:

* 状态0:检测是否有键按下;   
* 状态1:消抖处理   
* 状态2:确认按键(F引导键+其他键、单按键),同状态1比较  
* 状态3:计数1,(按3S,连_发判断);按键放开,转状态0
* 状态4:计数2,连_发功能  
* 状态5:返键值,转状态3
发表于 2008-7-20 11:13:46 | 显示全部楼层
作记号,以后查询
 楼主| 发表于 2008-7-30 15:14:40 | 显示全部楼层
我用到一个实际的产品,也是组合按键的,没有使用引导键,不论哪个先按都能及时反映出来,同时每个按键都具备单独的功能,反映都非常灵敏,真不知是采用了什么思路
发表于 2008-7-30 15:49:37 | 显示全部楼层
猜测如下:
1.检测是否有键按下;   
2.消抖处理:延时稍长(如0.2s),判断键值有无变化? 无变化,得到键值(单按键,多按键)
3.判断按键是否变化? 有变化,转步骤1。
 楼主| 发表于 2008-7-30 16:02:05 | 显示全部楼层
那它的状态是怎么变化的呢?
发表于 2008-7-30 16:30:44 | 显示全部楼层
主要是按键扫描程序的结束条件由“判断按键放开”,变为“判断按键变化”。
另外,修正在20楼的描述:

1.检测是否有键按下;     
2.消抖处理:延时,判断键值有无变化? 无变化,得到键值(单按键,多按键);
3.判断按键是否变化? 变化为无效键,返回键值,转步骤1;变化为新按键,不返回键值,转步骤1重新判断;
(补:无键和不用的键,都当成无效键)
发表于 2008-7-31 08:48:47 | 显示全部楼层
看看
发表于 2008-7-31 08:48:47 | 显示全部楼层
看看
发表于 2008-9-11 21:54:12 | 显示全部楼层
jihao
发表于 2008-9-11 22:36:15 | 显示全部楼层
MARK 以后要仔细看一下。
发表于 2008-9-11 22:38:26 | 显示全部楼层
记号一下
发表于 2008-9-11 22:42:08 | 显示全部楼层
up
发表于 2008-9-11 23:46:52 | 显示全部楼层
消抖后,那就不能使用快速“双击”功能啦
发表于 2008-9-12 01:09:27 | 显示全部楼层
楼上的,当然可以实现快速“双击”。

你先测试你的最快的“快速双击”操作,两次击键之间的时间最少是多少毫秒?
发表于 2008-9-12 09:57:18 | 显示全部楼层
不错。
发表于 2008-9-12 09:58:28 | 显示全部楼层
小时候玩跑表,最快的连击速度经测试不小于180ms
发表于 2008-9-25 11:46:17 | 显示全部楼层
记号一下 
发表于 2008-10-6 23:37:31 | 显示全部楼层
support
发表于 2008-10-7 09:19:12 | 显示全部楼层
记号  慢慢看
发表于 2008-10-7 09:35:38 | 显示全部楼层
很好,经常能用得到
发表于 2008-10-14 11:13:56 | 显示全部楼层
备用啊
发表于 2008-11-17 20:09:29 | 显示全部楼层
mark
发表于 2008-11-26 14:35:23 | 显示全部楼层
标记
发表于 2008-12-25 16:36:01 | 显示全部楼层
看了一下楼主的程序,没有太明白,在read_keyboard()中定义了局部变量key_time=0,那么在每次调用该函数时,key_time==0,怎么会出现++key_time>=50等情况出现呢?是不是应将key_time定义成全局变量呢?小弟拙见
发表于 2008-12-25 18:44:12 | 显示全部楼层
明白了,因为是静态局部变量
发表于 2009-1-11 20:34:15 | 显示全部楼层
mark
发表于 2009-3-9 09:40:52 | 显示全部楼层
定时10ms扫描按键?
发表于 2009-3-13 10:24:04 | 显示全部楼层
MARK
发表于 2009-4-24 17:24:44 | 显示全部楼层
AMRK
发表于 2009-4-24 17:33:26 | 显示全部楼层
不错
MARK!
发表于 2009-7-2 18:15:15 | 显示全部楼层
好帖,先领会。
发表于 2009-7-4 01:58:51 | 显示全部楼层
学习!有空研究下
发表于 2009-7-4 14:34:18 | 显示全部楼层
学习一下。做个记号
发表于 2009-7-12 22:50:37 | 显示全部楼层
学习一下。。
发表于 2009-7-12 22:54:27 | 显示全部楼层
jh
发表于 2009-7-12 22:58:40 | 显示全部楼层
这个讨论有意思
发表于 2009-7-29 18:23:26 | 显示全部楼层
楼主的编程功底的确要加强,不过思路基本上到位了。
需求不一样,在保证最高效率的前提下,方法可以不一样。
大部分情况下,状态机是比价好的思路,优点是比较清晰。
发表于 2009-7-29 19:03:09 | 显示全部楼层
MARK
发表于 2009-7-29 23:10:29 | 显示全部楼层
MARK 按键 状态机
发表于 2009-7-30 22:07:18 | 显示全部楼层
mark
发表于 2009-7-30 22:15:56 | 显示全部楼层
学习下
发表于 2009-8-1 18:04:05 | 显示全部楼层
mark
发表于 2009-8-2 00:45:15 | 显示全部楼层
mark
经常用到
发表于 2009-8-2 21:07:12 | 显示全部楼层
看看  学习中
发表于 2009-8-14 18:53:25 | 显示全部楼层
mark
发表于 2009-8-14 20:50:17 | 显示全部楼层
mark
发表于 2009-8-15 11:11:37 | 显示全部楼层
mark
发表于 2009-9-18 11:30:49 | 显示全部楼层
mark
发表于 2009-9-26 09:35:20 | 显示全部楼层
学习了
发表于 2009-10-4 11:55:45 | 显示全部楼层
MARK
发表于 2009-10-4 16:09:34 | 显示全部楼层
有了参考资料!
发表于 2009-10-9 09:53:44 | 显示全部楼层
大家讨论的很棒

不过对赋值这块  总感觉 太繁琐了。
想改进下  
不过 想了半天  无果

谁能提供个简化的思路不
发表于 2009-10-11 17:04:38 | 显示全部楼层
简化思路:
1、有键按下,消抖,送通码(键值)
2、无键按下,消抖,送断码
3、在调用程序里处理通码和断码,可以实现连_发功能
发表于 2009-10-11 17:41:29 | 显示全部楼层
mark
发表于 2009-10-13 19:52:52 | 显示全部楼层
马尔克,谢谢
发表于 2009-10-13 20:02:00 | 显示全部楼层
4*4扫描还搞这么复杂?
键扫提供基本信息:按下、弹起、组合键、REPEAT键,还有可能象手机那样的按法,都不用写这么复杂。
发表于 2009-10-24 11:08:25 | 显示全部楼层
MARK
发表于 2009-12-14 13:40:31 | 显示全部楼层
记录一下 学习
发表于 2009-12-14 13:44:45 | 显示全部楼层
记号一个
发表于 2009-12-23 01:16:10 | 显示全部楼层
mark
发表于 2009-12-23 01:41:48 | 显示全部楼层
mark
发表于 2009-12-26 09:17:42 | 显示全部楼层
先标记一下,明天再看
发表于 2010-1-13 09:49:28 | 显示全部楼层
mark
发表于 2010-1-13 10:31:22 | 显示全部楼层
mark
发表于 2010-1-13 10:39:11 | 显示全部楼层
先记号,有空在看
发表于 2010-2-6 13:17:20 | 显示全部楼层
mark
发表于 2010-2-6 13:55:23 | 显示全部楼层
回复【楼主位】raosibin
-----------------------------------------------------------------------

发表于 2010-3-13 23:41:56 | 显示全部楼层
mark
发表于 2010-3-18 21:14:57 | 显示全部楼层
mark
发表于 2010-3-19 16:47:53 | 显示全部楼层
回复【楼主位】raosibin
-----------------------------------------------------------------------

mark
发表于 2010-3-19 19:30:13 | 显示全部楼层
mark
发表于 2010-3-25 11:22:48 | 显示全部楼层
学习一下
发表于 2010-3-27 12:00:37 | 显示全部楼层
回复【4楼】machao
-----------------------------------------------------------------------

谢谢马老师
发表于 2010-3-27 15:54:24 | 显示全部楼层
mark
发表于 2010-3-27 17:14:36 | 显示全部楼层
dddddddddddddddddddddddddddddd
发表于 2010-6-16 14:59:19 | 显示全部楼层
好资料,值得研究
发表于 2010-6-23 08:11:15 | 显示全部楼层
mark
发表于 2010-6-23 16:49:46 | 显示全部楼层
Study
发表于 2010-7-15 10:34:00 | 显示全部楼层
这是个好东西,收藏1
发表于 2010-7-15 11:51:16 | 显示全部楼层
看下
发表于 2010-7-29 17:44:37 | 显示全部楼层
这个程序是不是没有松手检测?
发表于 2010-7-29 18:53:13 | 显示全部楼层
mark
发表于 2010-8-11 15:02:36 | 显示全部楼层
多键组合为社么需要有引导键?单按键和组合按键返回的键值不同,直接检测键值,那个键先按下都无所谓
友情提示:标题不合格、重复发帖,将会被封锁ID。详情请参考:论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|阿莫电子论坛(原ourAVR/ourDEV) ( 公安备案:44190002001997(交互式论坛) 工信部备案:粤ICP备09047143号 )

GMT+8, 2019-9-15 18:53

阿莫电子论坛, 原"中国电子开发网"

© 2004-2018 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表