久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8438|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

簡單的KEY掃描不簡單,你還在用簡陋的例程嗎?

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:75926 發(fā)表于 2015-4-4 01:36 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
一般的開發(fā)板,給出的例程,對按鍵掃描的寫法如下:
#define KEY1  HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10)
#define KEY2  HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2)
uint8_t K1_Value;
uint8_t K2_Value;
void KEY_SCAN(void)
{
   if (KEY1 == 0)  {
      delay(200); // 延時200毫秒
      if(KEY1 == 0)  { K1_Value= 1; }
      else {K1_Value = 0;}
   }
   if (KEY2 == 0)  {
      delay(200); // 延時200毫秒
      if(KEY2 == 0)  { K2_Value= 1; }
      else {K2_Value = 0;}  
   }
}

這種寫法非常簡陋,也就是害人害己,無法在實際項目中使用,很多有名氣的教授寫的教材也是這樣的。
以下是本人原創(chuàng)的按鍵掃描,經(jīng)過反復(fù)實驗,在DX103開發(fā)板上測試能正常工作。代碼可以在項目中使用。

/**

  * @brief  KEY Scan Structure definition  
  */  
typedef struct
{
  uint16_t Shift_Cnt;                             /* 向下毫秒計數(shù),粘滯鍵掃描延遲和啟動標志,限制生成向上鍵值 */
  uint16_t Up_Cnt;                               /* 向下毫秒計數(shù), 彈起鍵掃描延遲和啟動標志 */
  uint16_t Down_Repeat;                     /* 限制500毫秒內(nèi)僅產(chǎn)生一次按下的鍵值 */
  uint16_t Up_Repeat;                          /* 限制500毫秒內(nèi)僅產(chǎn)生一次彈起的鍵值 */
  uint8_t  Flag_KEY_Down_Process;    /* KEY鍵按下處理標志 */
  uint8_t  Flag_KEY_Shift_Process;      /* KEY粘滯鍵處理標志 */
  uint8_t  Flag_KEY_Up_Process;        /* KEY鍵彈起處理標志 */
  uint8_t  Flag_KEY_Process;               /* KEY鍵后續(xù)繼續(xù)處理標志 */
  uint8_t  Value;                                     /* KEY當前鍵值 */
  uint8_t  Old_Value;                              /* KEY上一個鍵值 */
}KEY_TypeDef;

KEY_TypeDef KEY1, KEY2;
__IO uint8_t Flag_TIM2_Update = 0;  /* 定時器2更新標志 */

/* 帶參數(shù)的宏功能(預(yù)編譯展開): 掃描GPIOx GPIO_PIN_x的單個按鍵  */
#define KEYX_SCAN(KEYx,GPIOx,GPIO_PIN_x) {\
  KEYx.Value = HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_x);\
  if(KEYx.Old_Value != KEYx.Value){\
    if(KEYx.Old_Value == 1){\
      if(KEYx.Down_Repeat == 0){\
        KEYx.Flag_KEY_Down_Process = 1;\
        KEYx.Down_Repeat = 500;\
      }\
      KEYx.Shift_Cnt = 800;\
    } else {\
      if(KEYx.Down_Repeat < 300){\
        KEYx.Shift_Cnt = 0;\
        KEYx.Up_Cnt = 0;\
        if(KEYx.Up_Repeat == 0){\
          KEYx.Flag_KEY_Up_Process = 1;\
          KEYx.Up_Repeat = 500;\
        }\
      }\
    }\
    KEYx.Old_Value = KEYx.Value;\
  }\
  if(KEYx.Down_Repeat){--KEYx.Down_Repeat;}\
  if(KEYx.Up_Repeat){--KEYx.Up_Repeat;}\
  if(KEYx.Shift_Cnt){\
    --KEYx.Shift_Cnt;\
    if(KEYx.Shift_Cnt==0){\
      KEYx.Value = HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_x);\
      if(KEYx.Value == 0){\
        KEYx.Flag_KEY_Shift_Process = 1;\
        KEYx.Down_Repeat = 200;\
        KEYx.Shift_Cnt   = 200;\
      } else {\
        KEYx.Up_Cnt = 20;\
      }\
      KEYx.Old_Value = KEYx.Value;\
    }\
  }\
  if(KEYx.Up_Cnt){\
    --KEYx.Up_Cnt;\
    if(KEYx.Up_Cnt==0){\
      KEYx.Value = HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_x);\
      if(KEYx.Value == 1){\
        KEYx.Flag_KEY_Up_Process = 1;\
        KEYx.Shift_Cnt = 0;\
        KEYx.Up_Cnt = 0;\
      }\
      KEYx.Old_Value = KEYx.Value;\
    }\
  }\
}

/*
* @ KEY_SCAN
* @ Edit by wjandcf@gmail.com
* @ 2015-2-3
*/
void KEY_SCAN(void)
{
  KEYX_SCAN(KEY1, GPIOB, GPIO_PIN_10); /* 掃描大蝦103開發(fā)板上的KEY1 */
  KEYX_SCAN(KEY2, GPIOC, GPIO_PIN_2);  /* 掃描大蝦103開發(fā)板上的KEY2 */

#if 0
  /* 保留此段代碼,是為了讓大家了解按鍵掃描的基本流程 */
  /* 按鍵掃描第一部分,快速的按下和彈起鍵值掃描 */
  KEY1.Value = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10);
  if(KEY1.Old_Value != KEY1.Value){
    if(KEY1.Old_Value == 1){              /* 有鍵按下 */
      if(KEY1.Down_Repeat == 0){
        KEY1.Flag_KEY_Down_Process = 1;   /* 按鍵按下標志 */
        KEY1.Down_Repeat = 500;           /* 500毫秒內(nèi)不再產(chǎn)生鍵按下標志 */
      }
      KEY1.Shift_Cnt = 800;               /* 粘滯鍵產(chǎn)生的延遲時間,限制再產(chǎn)生向上按鍵 */
    } else {
      if(KEY1.Down_Repeat < 300){         /* (500-300)毫秒后才能產(chǎn)生向上按鍵 */
        KEY1.Shift_Cnt = 0;
        KEY1.Up_Cnt = 0;
        if(KEY1.Up_Repeat == 0){
          KEY1.Flag_KEY_Up_Process = 1;   /* 按鍵彈起標志 */
          KEY1.Up_Repeat = 500;           /* 500毫秒內(nèi)不再產(chǎn)生鍵彈起標志 */
        }
      }
    }
    KEY1.Old_Value = KEY1.Value;
  }
  /* 按鍵掃描第二部分,粘滯鍵掃描,粘滯鍵后的彈起鍵掃描 */
  if(KEY1.Down_Repeat){
    --KEY1.Down_Repeat;                   /* 按鍵按下掃描時間限制,不為零限制再次生成 */
  }
  if(KEY1.Up_Repeat){
    --KEY1.Up_Repeat;                     /* 按鍵彈起掃描時間限制,不為零限制再次生成 */
  }
  if(KEY1.Shift_Cnt){
    --KEY1.Shift_Cnt;                     /* 粘滯鍵掃描延遲 */
    if(KEY1.Shift_Cnt==0){
      KEY1.Value = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10);
      if(KEY1.Value == 0){
        KEY1.Flag_KEY_Shift_Process = 1;  /* 粘滯鍵標志 */
        KEY1.Down_Repeat = 200;           /* 粘滯鍵時,限制300毫秒內(nèi)不能生成按下鍵 */
        KEY1.Shift_Cnt   = 200;           /* 200毫秒生成一次粘滯鍵 */
      } else {
        KEY1.Up_Cnt = 20;                 /* 發(fā)現(xiàn)有按鍵彈起,延遲20毫秒再檢查按鍵是否真正彈起 */
      }
      KEY1.Old_Value = KEY1.Value;
    }
  }
  if(KEY1.Up_Cnt){                        /* 在200毫秒的粘滯鍵生成時間限制里,每隔20毫秒檢查按鍵是否彈起 */
    --KEY1.Up_Cnt;
    if(KEY1.Up_Cnt==0){
      KEY1.Value = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10);
      if(KEY1.Value == 1){
        KEY1.Flag_KEY_Up_Process = 1;     /* 按鍵彈起標志 */
        KEY1.Shift_Cnt = 0;               /* 按鍵彈起,關(guān)閉粘滯鍵掃描 */
        KEY1.Up_Cnt = 0;                  /* 按鍵彈起,關(guān)閉彈起鍵掃描 */
      }
      KEY1.Old_Value = KEY1.Value;
    }
  }
#endif
}





分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩最新网址 | 午夜精品导航 | 日一区二区三区 | wwww.xxxx免费| 亚洲一区视频在线播放 | 国产一级特黄真人毛片 | 婷婷在线视频 | 久久久久久国产精品免费免费狐狸 | 成人av在线播放 | 免费成人午夜 | 成年网站在线观看 | 七七婷婷婷婷精品国产 | 欧美性生活免费 | av中文字幕在线 | 国产高清精品一区二区三区 | 婷婷综合在线 | 欧美一级二级三级视频 | 九九精品热 | 免费成人高清在线视频 | 国产亚洲一区二区三区在线 | 欧美日韩在线免费 | 国产精品美女在线观看 | 亚洲人成在线观看 | 国产精品久久久久国产a级 欧美日韩国产免费 | 天天爽夜夜爽精品视频婷婷 | 五月激情综合 | 日韩免费福利视频 | 国产精品国产自产拍高清 | 日韩精品极品视频在线观看免费 | 亚洲视频在线播放 | 视频一区二区中文字幕日韩 | 免费视频99 | 国产视频精品视频 | 国产一区二区精品在线观看 | 久久久一区二区三区 | 精品影院 | 九九综合 | 国产在线视频网 | www国产成人免费观看视频,深夜成人网 | 日韩免费中文字幕 | 中文字幕一区二区三区精彩视频 |