打印

这个键盘扫描程序看了很多遍,不得要领,那位给我解释下

[复制链接]
2753|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xqhe|  楼主 | 2007-5-3 10:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Simple keypad library, for a 3-column x 4-row keypad.

   Key arrangement is:   ---------
                          1  2  3
                          4  5  6
                          7  8  9
                          *  0  #
                         ---------

   Supports two function keys ('*' and '#').

……………… 

static char Last_valid_key_G = KEYPAD_NO_NEW_DATA;//静态全局变量

………………

void KEYPAD_Update(void)                         //键盘更新函数
   {
   char Key, FnKey;

   // Scan keypad here...
   if (KEYPAD_Scan(&Key, &FnKey) == 0)           //调用键盘扫描
      {
      // No new key data - just return
      return;
      }

………………
………………

bit KEYPAD_Scan(char* const pKey, char* const pFuncKey)
   {
   static data char Old_Key;

   char Key = KEYPAD_NO_NEW_DATA;
   char Fn_key = (char) 0x00;

   C1 = 0; // Scanning column 1
      if (R1 == 0) Key = '1';
      if (R2 == 0) Key = '4';
      if (R3 == 0) Key = '7';
      if (R4 == 0) Fn_key = '*';
   C1 = 1;

   C2 = 0; // Scanning column 2
      if (R1 == 0) Key = '2';
      if (R2 == 0) Key = '5';
      if (R3 == 0) Key = '8';
      if (R4 == 0) Key = '0';
   C2 = 1;

   C3 = 0; // Scanning column 3
      if (R1 == 0) Key = '3';
      if (R2 == 0) Key = '6';
      if (R3 == 0) Key = '9';
      if (R4 == 0) Fn_key = '#';
   C3 = 1;

   if (Key == KEYPAD_NO_NEW_DATA)
      {
      // No key pressed (or just a function key)
      Old_Key = KEYPAD_NO_NEW_DATA;
      Last_valid_key_G = KEYPAD_NO_NEW_DATA;

      return 0;  // No new data
      }
   
   // A key has been pressed: debounce by checking twice
   if (Key == Old_Key)                       //这步!初始化时
      {                                      //Key==Old_Key是理应的
                                             //当有KEY按下后
                                             //Key!=Old_Key
                                             //但!=Old_Key又如何
                                             //进入IF语句???
      // A valid (debounced) key press has been detected
                                            //这里小了延时语句??
      
      // Must be a new key to be valid - no 'auto repeat'
      if (Key != Last_valid_key_G)
         { 
         // New key!
         *pKey = Key;
         Last_valid_key_G = Key;

         // Is the function key pressed too?
         if (Fn_key)
            {
            // Function key *is* pressed with another key
            *pFuncKey = Fn_key;
            }
         else
            {
            *pFuncKey = (char) 0x00;
            }

         return 1;
         }
      }

   // No new data
   Old_Key = Key;   //当某KEY被一直按下时,由于不支持重           
   return 0;        //复,虽然检测到Key != KEYPAD_NO_NEW_DATA
   }                //但由于Key == Old_Key,仍然进入IF语句,再由
                    //Key != Last_valid_key_G 决定不是新键,
                    //return 0;


   个人认为,第一次有KEY按下后,要求Key != Old_Key进入IF语句:
 但在长按情况下,却要求Key == Old_Key进入IF语句。。。如何解释???

相关帖子

沙发
xwj| | 2007-5-3 11:09 | 只看该作者

哪里要求“要求Key != Old_Key”了???


   if (Key == Old_Key)                       //这步!初始化时
      {                                      //Key==Old_Key是理应的
--谁告诉你是应当的???
                                             //当有KEY按下后
                                             //Key!=Old_Key
                                             //但!=Old_Key又如何
                                             //进入IF语句???
--哪里要求“要求Key != Old_Key”了???
--你对它的行为理解抖不对,分析结果怎么会对呢?
 
键消抖本来就是个(准)状态机,不同条件下进入执行的结果是不同的,会根据之前标志、状态选择不同操作
直接分析的话你的大脑要保存它的所有静态变量并按它的语句运行
如果跟踪不过来,那就动笔记录,
但更好更快的方法是用仿真软件单步跟踪
 

使用特权

评论回复
板凳
xwj| | 2007-5-3 11:11 | 只看该作者

补充:第一次不会进入,第二次相同才会进入,这就是消抖

使用特权

评论回复
地板
xqhe|  楼主 | 2007-5-3 11:48 | 只看该作者

回复

    谢谢,的确是我不理解这种消抖的方法。原只懂检测,延时N时间,再检测……;太笨了。只是哪个功能键没消抖,不知这样在实际上,会不会有稳定性问题的存在?

使用特权

评论回复
5
ayb_ice| | 2007-5-4 08:35 | 只看该作者

一看就写的不咋地...

使用特权

评论回复
6
oyggj| | 2007-5-9 23:07 | 只看该作者

呵呵,

那你写一个很牛的按键检测

使用特权

评论回复
7
ayb_ice| | 2007-5-10 07:46 | 只看该作者

随便说说

 if (R1 == 0) Key = '2';
      if (R2 == 0) Key = '5';
      if (R3 == 0) Key = '8';
      if (R4 == 0) Key = '0';
如果R1=0则Key = '2'...
但如果R1,R2,R3,R4其中几个都为0怎样,合理吗....
所以 一看就写的不咋地,没有必要继续看...

使用特权

评论回复
8
ATmega8515| | 2007-5-10 10:35 | 只看该作者

求助:怎么用LMP指令读取FLASH去某地址高8位或低8位一字节数

求助:LMP指令如何读取FLASH去某地址高8位或低8位一字节数据? 

使用特权

评论回复
9
ayb_ice| | 2007-5-10 11:11 | 只看该作者

LMP是啥指令...

使用特权

评论回复
10
未来是梦| | 2007-5-10 14:45 | 只看该作者

很经典,记得看过一本书,里面也有这个例程。

这是出自《时间触发嵌入式系统设计模式:使用8051系列微控制器开发可靠应用》的例程,作者Michael J.Pont

使用特权

评论回复
11
xqhe|  楼主 | 2007-5-10 19:45 | 只看该作者

回上楼

    呵呵,这样都记得.的确是哦
 
7楼: 随便说说 

 if (R1 == 0) Key = '2';
      if (R2 == 0) Key = '5';
      if (R3 == 0) Key = '8';
      if (R4 == 0) Key = '0';
如果R1=0则Key = '2'...
但如果R1,R2,R3,R4其中几个都为0怎样,合理吗....
所以 一看就写的不咋地,没有必要继续看...
 
 

bit KEYPAD_Scan(char* const pKey, char* const pFuncKey)
   {
   static data char Old_Key;

   char Key = KEYPAD_NO_NEW_DATA;
   char Fn_key = (char) 0x00;

     char i;    //添加的
     C1 = 0; // Scanning column 1
      if (R1 == 0) {Key = '1';i++;}
      if (R2 == 0) {Key = '4';i++;}
      if (R3 == 0) {Key = '7';i++;}
      if (R4 == 0) Fn_key = '*';
   C1 = 1;

   C2 = 0; // Scanning column 2
      if (R1 == 0) {Key = '2';i++;}
      if (R2 == 0) {Key = '5';i++;}
      if (R3 == 0) {Key = '8';i++;}
      if (R4 == 0) {Key = '0';i++;}
   C2 = 1;

   C3 = 0; // Scanning column 3
      if (R1 == 0) {Key = '3';i++;}
      if (R2 == 0) {Key = '6';i++;}
      if (R3 == 0) {Key = '9';i++;}
      if (R4 == 0) Fn_key = '#';
   C3 = 1;

   if (Key == KEYPAD_NO_NEW_DATA)
      {
      // No key pressed (or just a function key)
      Old_Key = KEYPAD_NO_NEW_DATA;
      Last_valid_key_G = KEYPAD_NO_NEW_DATA;

      return 0;  // No new data
      }
   
   // A key has been pressed: debounce by checking twice
  
if(i==1) //添加的
{
  if (Key == Old_Key) 
{                                                                                                      
      // A valid (debounced) key press has been detected
                                           
      
      // Must be a new key to be valid - no 'auto repeat'
      if (Key != Last_valid_key_G)
         { 
         // New key!
         *pKey = Key;
         Last_valid_key_G = Key;

         // Is the function key pressed too?
         if (Fn_key)
            {
            // Function key *is* pressed with another key
            *pFuncKey = Fn_key;
            }
         else
            {
            *pFuncKey = (char) 0x00;
            }

         return 1;
         }
      }
 }//end if(i==1)
   // No new data
   Old_Key = Key;             
return0;                                                        return 0;
}

这样就可以禁止两个以上的数字键被按下了,,,,不同的要求偏写不同的程序就可以了,没必要什么都做的十全十美的,在特定的场合OK就行了!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

46

帖子

0

粉丝