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

標題: 單片機狀態(tài)機按鍵例程如何加入多個按鍵檢測長按短按和連發(fā)? [打印本頁]

作者: zhth1979    時間: 2022-12-13 09:08
標題: 單片機狀態(tài)機按鍵例程如何加入多個按鍵檢測長按短按和連發(fā)?
看了uid:130230的狀態(tài)機按鍵掃描,感覺應該可以實現(xiàn)我想要的功能:多按鍵檢測長按,短按和連按(按下不放連加或連減),之前看到的例程多為短按和長按組合,或短按和連按組合,沒有看到過長按和連按如何識別,一直很糾結。
之前發(fā)過比較簡單有效的狀態(tài)機按鍵檢測的例程,但那個例程里沒有加入長按檢測,如果哪位高手有興趣,也可以在我之前的貼子里修改,不勝感激!
http://m.zg4o1577.cn/bbs/dpj-225323-1.html

下面這個例程是uid:130230高手寫的,原例程只有一個按鍵,現(xiàn)在我把我需要的按鍵放進去了,還加了一些注釋,不知道理解的對不對?還請各位大神們多多指點,先謝謝了!
  .h文件
#ifndef __key_H__
#define __key_H__

#include "xx.h"

#define PD 0x22|(P1&0x51)|(P2<<1&0x80)|(P3<<2&0x0c)   //P1.0/P3.0 p3.1/P4.2 p4.3組合5個按鍵為1個字節(jié)數(shù)據(jù)
//             |0101 0001   |0100 0000 |0000 0011
//   0010 0010 |0101 0001   |1000 0000 |0000 1100       1100 1101 移位后或:1111 1111  PD = 0xff;



sbit up   = P2^6;   //0111 1111  7f
sbit unit = P1^0;   //1111 1110  fe
sbit down = P3^0;   //1111 1011  fb
sbit md   = P1^6;   //1011 1111  bf
sbit k5   = P3^1;   //1111 0111  f7
sbit k6   = P1^4;   //1110 1111  ef

sbit md1  = P1^5;

//按鍵值
typedef enum
{
        NONE_CLICK = 0,    //無按鍵
        SINGLE_CLICK ,     //單擊
        DOUBLE_CLICK,      //雙擊
        LONG_PRESS,        //長按
              LIANFA_CLICK,       //連發(fā)
        NUM_KEY,           
}KEY_VALUE_EN;

//按鍵狀態(tài)
typedef enum
{
        KEY_IDLE = 0,          //空閑
        KEY_FILTER,            //去抖
        KEY_FIRST,             //第一次按下
        KEY_CHECK_FREE,        //抬起檢測(長按)
        NUM_KEY_STAUS,                        
}KEY_STATUS_EN;


//按鍵掃描狀態(tài)
typedef struct
{
        unsigned char Statu;
        unsigned char CntDly;
        unsigned char KeyValue;

}TASK_KEY_STATU_ST;


void Task_Keyscan(void);
void Switch_KeyState(unsigned char state);

#endif


.c文件
#include "key.h"


TASK_KEY_STATU_ST gstKey1 = {0};       //任務鍵狀態(tài)


/***********************************************
功能:按鍵掃描
作者:jzb2019年12月27日
備注:50ms運行一次這個函數(shù),理論上可以擴展到n連擊
        最大響應延時500ms(單擊時)
***********************************************/
void Task_Keyscan(void)
{
        unsigned char key;
  key=PD&0xFF;
        
  switch (gstKey1.Statu)
      {
        case KEY_IDLE:                      //按鍵空閑
                                         {
                                                if(key!= 0xFF)
                                                        {
                Switch_KeyState(KEY_FILTER);//按鍵按下了去抖
              }
            }
            break;
                                         
         case KEY_FILTER:
            {
                                                 if(key!= 0xFF)
                                                                {
                                                                        gstKey1.CntDly++;
                                                                        if(gstKey1.CntDly >= 60)
                                                                                {
                                                                                        gstKey1.KeyValue = LONG_PRESS;//長按
                                                                                       
                                                                                        Switch_KeyState(KEY_CHECK_FREE);//抬起檢測
                                                                                }
                                                                 }
             else
                {
                                                                 if(gstKey1.CntDly == 0)
                                                                                {
                                                                                 Switch_KeyState(KEY_IDLE);//如果沒有計數(shù)則證明是毛刺濾掉
                                                                                }
                                                                        else
                                                                                {
                                                                                                                Switch_KeyState(KEY_FIRST);//轉到第一次按下狀態(tài)
                                                                                }
                 }
               }
               break;
                                                         
                                        case KEY_FIRST:
                                                        {
                                                                if(key == 0xff)//釋放了
                                                                        {        
                                                                                gstKey1.CntDly++;
                                                                                if(gstKey1.CntDly > 10)//500ms
                                                                                        {
                                                                                                gstKey1.KeyValue = SINGLE_CLICK;          //單擊
                                                                                       
                                                                                                Switch_KeyState(KEY_IDLE);//回到空閑
                                                                                        }
                                                                        }
                  else//按下了
                     {
                                                                                        if(gstKey1.CntDly == 0)//沒有計數(shù)證明是沒有釋放按鍵的動作
                                                                                          {
                                                                                            
                                                                                           }
                                                                                        else//這個分支里面已經(jīng)是第二次按下了
                                                                                                {
                                                                                                        gstKey1.KeyValue = DOUBLE_CLICK;
                                                                                                
                                                                                                        Switch_KeyState(KEY_CHECK_FREE);//抬起檢測
                                                                                                }
                                                                                        }
                }
                break;
                                                               
           case KEY_CHECK_FREE:
                                                         {
                                                                 if(key == 0xff)
                                                                                {        
                                                                                        Switch_KeyState(KEY_IDLE);
                                                                                }
                                                         }
                                             break;
                                                         
                                         default :
                                                        {
                                                                Switch_KeyState(KEY_IDLE);
                                                        }
                                                        break;        
        }
}


/****************************************************************************
功能:執(zhí)行切換狀態(tài)的動作,同時清掉當前狀態(tài)內的計數(shù)
入口:要切換的狀態(tài)
作者:jzb 2019年12月27日
備注:暫時先不考慮通用的問題,直接操作全局變量如果擴展按鍵再說
*****************************************************************************/
void Switch_KeyState(unsigned char state)
{
        gstKey1.CntDly = 0;
        gstKey1.Statu = state;
}




作者: wc86110    時間: 2022-12-13 10:38
長按和連按一個意思,有必要細分么?如音量分成 100 短按減 1 長按減 10 以秒來劃定加減數(shù)值變化就行了
單鍵復用還是簡單些實用,不然會造成操作者困惑按鍵處在何種狀態(tài)

作者: zhth1979    時間: 2022-12-13 11:31
wc86110 發(fā)表于 2022-12-13 10:38
長按和連按一個意思,有必要細分么?如音量分成 100 短按減 1 長按減 10 以秒來劃定加減數(shù)值變化就行了
單 ...

比如我有五個按鍵,一個加,一個減 一個單位切換 一個開關LED燈,一個讓電機啟停;加減要短按+連按,單位切換要短按+長按,LED要短按+長按,電機要短按,在按鍵掃描中是不是要短按,長按和連按都要區(qū)分開來,才能控制?
作者: lkc8210    時間: 2022-12-13 13:49
zhth1979 發(fā)表于 2022-12-13 11:31
比如我有五個按鍵,一個加,一個減 一個單位切換 一個開關LED燈,一個讓電機啟停;加減要短按+連按,單位 ...

按鍵掃描不用區(qū)分
得出的鍵值就要區(qū)分處理
短按和長按的鍵值用完要清零
連按的鍵值用完不用清零,放開才清零



作者: zhuls    時間: 2022-12-15 09:42
wc86110 發(fā)表于 2022-12-13 10:38
長按和連按一個意思,有必要細分么?如音量分成 100 短按減 1 長按減 10 以秒來劃定加減數(shù)值變化就行了
單 ...

長按和連按一個意思?表示不解。
按下、保持按下、放開, 是一個按鍵的完整過程,
比如單位時間內:(有效按鍵時)
“長按”主要檢測“保持按下”的時長,
“連按”則是檢測“按下”和“放開”的次數(shù)。

作者: zhth1979    時間: 2022-12-30 09:21
zhuls 發(fā)表于 2022-12-15 09:42
長按和連按一個意思?表示不解。
按下、保持按下、放開, 是一個按鍵的完整過程,
比如單位時間內:( ...

比較贊同您的理解,長按和連按(網(wǎng)上也有叫連發(fā)),連按如果是在長按的基礎上判斷,是不是不好區(qū)分出來?
作者: hi等你    時間: 2022-12-30 10:31
連擊的話各個人手速和頻率不一樣,連擊很容易被識別成單擊誤操作,代碼時間間隔比較難做到高識別率,我覺得一個按鈕做單擊和長按區(qū)分就可以了,不要為了少一個按鈕反而增加操作設備復雜程度
作者: lkc8210    時間: 2022-12-30 10:57


作者: feeling1791    時間: 2022-12-30 11:05
按鍵的算法有問題,一個簡單地短按,長按,組合鍵,連發(fā),不需要這么繁雜的想法,應該把這個做法徹底拋棄!附上一個程序給樓主參考

key.rar

4.26 KB, 下載次數(shù): 35


作者: zhth1979    時間: 2023-1-7 08:18
feeling1791 發(fā)表于 2022-12-30 11:05
按鍵的算法有問題,一個簡單地短按,長按,組合鍵,連發(fā),不需要這么繁雜的想法,應該把這個做法徹底拋棄! ...

按說用狀態(tài)機檢測按鍵很方便的,在這個掃描程序里同時檢測短按,長按和連發(fā)確實不好實現(xiàn),可能自己愚笨,現(xiàn)在改用別的方法了。
作者: 17337161031    時間: 2024-7-2 09:07
長按需要加入上時刻和當前狀態(tài)判斷  短按的話加個松手檢測 連發(fā)的話 去掉松手檢測




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 欧美日韩激情视频 | 国产欧美日韩在线观看 | 亚洲特级片 | 最近日本中文字幕 | 日韩影院在线观看 | 欧美在线观看视频 | 久久99精品久久久久久国产越南 | 欧美二三区 | 中国毛片视频 | 国产在线观看免费 | 中文字幕在线免费观看视频 | 成人午夜影院 | 三上悠亚一区二区 | 免费毛片在线播放 | 国产在线色| 欧美综合久久 | 亚洲综合在线播放 | 黄色一级影片 | 亚洲一区二区在线免费观看 | 欧美日韩在线不卡 | 成人在线免费视频观看 | 91亚洲视频 | 日韩黄色一级视频 | 成人午夜激情视频 | 福利视频一区二区 | 日韩精品一级 | 丁香激情五月 | 22精品一区二区三区 | 夜夜骚av | 亚洲九九夜夜 | 一区二区三区网站 | 国产在线视频一区 | 手机看片1024日韩 | 日本中文在线观看 | 欧美一级二级三级 | 中文字幕一区二区在线播放 | 黄色大片视频 | 午夜免费福利视频 | 在线观看日韩欧美 | 国产黄色一区二区 | 简单av网|