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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

單片機(jī)狀態(tài)機(jī)按鍵例程如何加入多個(gè)按鍵檢測(cè)長(zhǎng)按短按和連發(fā)?

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:686513 發(fā)表于 2022-12-13 09:08 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
看了uid:130230的狀態(tài)機(jī)按鍵掃描,感覺(jué)應(yīng)該可以實(shí)現(xiàn)我想要的功能:多按鍵檢測(cè)長(zhǎng)按,短按和連按(按下不放連加或連減),之前看到的例程多為短按和長(zhǎng)按組合,或短按和連按組合,沒(méi)有看到過(guò)長(zhǎng)按和連按如何識(shí)別,一直很糾結(jié)。
之前發(fā)過(guò)比較簡(jiǎn)單有效的狀態(tài)機(jī)按鍵檢測(cè)的例程,但那個(gè)例程里沒(méi)有加入長(zhǎng)按檢測(cè),如果哪位高手有興趣,也可以在我之前的貼子里修改,不勝感激!
http://www.zg4o1577.cn/bbs/dpj-225323-1.html

下面這個(gè)例程是uid:130230高手寫(xiě)的,原例程只有一個(gè)按鍵,現(xiàn)在我把我需要的按鍵放進(jìn)去了,還加了一些注釋?zhuān)恢览斫獾膶?duì)不對(duì)?還請(qǐng)各位大神們多多指點(diǎ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個(gè)按鍵為1個(gè)字節(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,    //無(wú)按鍵
        SINGLE_CLICK ,     //單擊
        DOUBLE_CLICK,      //雙擊
        LONG_PRESS,        //長(zhǎng)按
              LIANFA_CLICK,       //連發(fā)
        NUM_KEY,           
}KEY_VALUE_EN;

//按鍵狀態(tài)
typedef enum
{
        KEY_IDLE = 0,          //空閑
        KEY_FILTER,            //去抖
        KEY_FIRST,             //第一次按下
        KEY_CHECK_FREE,        //抬起檢測(cè)(長(zhǎng)按)
        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};       //任務(wù)鍵狀態(tài)


/***********************************************
功能:按鍵掃描
作者:jzb2019年12月27日
備注:50ms運(yùn)行一次這個(gè)函數(shù),理論上可以擴(kuò)展到n連擊
        最大響應(yīng)延時(shí)500ms(單擊時(shí))
***********************************************/
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;//長(zhǎng)按
                                                                                       
                                                                                        Switch_KeyState(KEY_CHECK_FREE);//抬起檢測(cè)
                                                                                }
                                                                 }
             else
                {
                                                                 if(gstKey1.CntDly == 0)
                                                                                {
                                                                                 Switch_KeyState(KEY_IDLE);//如果沒(méi)有計(jì)數(shù)則證明是毛刺濾掉
                                                                                }
                                                                        else
                                                                                {
                                                                                                                Switch_KeyState(KEY_FIRST);//轉(zhuǎn)到第一次按下?tīng)顟B(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)//沒(méi)有計(jì)數(shù)證明是沒(méi)有釋放按鍵的動(dòng)作
                                                                                          {
                                                                                            
                                                                                           }
                                                                                        else//這個(gè)分支里面已經(jīng)是第二次按下了
                                                                                                {
                                                                                                        gstKey1.KeyValue = DOUBLE_CLICK;
                                                                                                
                                                                                                        Switch_KeyState(KEY_CHECK_FREE);//抬起檢測(cè)
                                                                                                }
                                                                                        }
                }
                break;
                                                               
           case KEY_CHECK_FREE:
                                                         {
                                                                 if(key == 0xff)
                                                                                {        
                                                                                        Switch_KeyState(KEY_IDLE);
                                                                                }
                                                         }
                                             break;
                                                         
                                         default :
                                                        {
                                                                Switch_KeyState(KEY_IDLE);
                                                        }
                                                        break;        
        }
}


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



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

使用道具 舉報(bào)

沙發(fā)
ID:96682 發(fā)表于 2022-12-13 10:38 | 只看該作者
長(zhǎng)按和連按一個(gè)意思,有必要細(xì)分么?如音量分成 100 短按減 1 長(zhǎng)按減 10 以秒來(lái)劃定加減數(shù)值變化就行了
單鍵復(fù)用還是簡(jiǎn)單些實(shí)用,不然會(huì)造成操作者困惑按鍵處在何種狀態(tài)
回復(fù)

使用道具 舉報(bào)

板凳
ID:686513 發(fā)表于 2022-12-13 11:31 | 只看該作者
wc86110 發(fā)表于 2022-12-13 10:38
長(zhǎng)按和連按一個(gè)意思,有必要細(xì)分么?如音量分成 100 短按減 1 長(zhǎng)按減 10 以秒來(lái)劃定加減數(shù)值變化就行了
單 ...

比如我有五個(gè)按鍵,一個(gè)加,一個(gè)減 一個(gè)單位切換 一個(gè)開(kāi)關(guān)LED燈,一個(gè)讓電機(jī)啟停;加減要短按+連按,單位切換要短按+長(zhǎng)按,LED要短按+長(zhǎng)按,電機(jī)要短按,在按鍵掃描中是不是要短按,長(zhǎng)按和連按都要區(qū)分開(kāi)來(lái),才能控制?
回復(fù)

使用道具 舉報(bào)

地板
ID:161164 發(fā)表于 2022-12-13 13:49 | 只看該作者
zhth1979 發(fā)表于 2022-12-13 11:31
比如我有五個(gè)按鍵,一個(gè)加,一個(gè)減 一個(gè)單位切換 一個(gè)開(kāi)關(guān)LED燈,一個(gè)讓電機(jī)啟停;加減要短按+連按,單位 ...

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


回復(fù)

使用道具 舉報(bào)

5#
ID:69038 發(fā)表于 2022-12-15 09:42 | 只看該作者
wc86110 發(fā)表于 2022-12-13 10:38
長(zhǎng)按和連按一個(gè)意思,有必要細(xì)分么?如音量分成 100 短按減 1 長(zhǎng)按減 10 以秒來(lái)劃定加減數(shù)值變化就行了
單 ...

長(zhǎng)按和連按一個(gè)意思?表示不解。
按下、保持按下、放開(kāi), 是一個(gè)按鍵的完整過(guò)程,
比如單位時(shí)間內(nèi):(有效按鍵時(shí))
“長(zhǎng)按”主要檢測(cè)“保持按下”的時(shí)長(zhǎng),
“連按”則是檢測(cè)“按下”和“放開(kāi)”的次數(shù)。
回復(fù)

使用道具 舉報(bào)

6#
ID:686513 發(fā)表于 2022-12-30 09:21 | 只看該作者
zhuls 發(fā)表于 2022-12-15 09:42
長(zhǎng)按和連按一個(gè)意思?表示不解。
按下、保持按下、放開(kāi), 是一個(gè)按鍵的完整過(guò)程,
比如單位時(shí)間內(nèi):( ...

比較贊同您的理解,長(zhǎng)按和連按(網(wǎng)上也有叫連發(fā)),連按如果是在長(zhǎng)按的基礎(chǔ)上判斷,是不是不好區(qū)分出來(lái)?
回復(fù)

使用道具 舉報(bào)

7#
ID:996773 發(fā)表于 2022-12-30 10:31 | 只看該作者
連擊的話(huà)各個(gè)人手速和頻率不一樣,連擊很容易被識(shí)別成單擊誤操作,代碼時(shí)間間隔比較難做到高識(shí)別率,我覺(jué)得一個(gè)按鈕做單擊和長(zhǎng)按區(qū)分就可以了,不要為了少一個(gè)按鈕反而增加操作設(shè)備復(fù)雜程度
回復(fù)

使用道具 舉報(bào)

8#
ID:161164 發(fā)表于 2022-12-30 10:57 | 只看該作者

回復(fù)

使用道具 舉報(bào)

9#
ID:651494 發(fā)表于 2022-12-30 11:05 | 只看該作者
按鍵的算法有問(wèn)題,一個(gè)簡(jiǎn)單地短按,長(zhǎng)按,組合鍵,連發(fā),不需要這么繁雜的想法,應(yīng)該把這個(gè)做法徹底拋棄!附上一個(gè)程序給樓主參考

key.rar

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

回復(fù)

使用道具 舉報(bào)

10#
ID:686513 發(fā)表于 2023-1-7 08:18 | 只看該作者
feeling1791 發(fā)表于 2022-12-30 11:05
按鍵的算法有問(wèn)題,一個(gè)簡(jiǎn)單地短按,長(zhǎng)按,組合鍵,連發(fā),不需要這么繁雜的想法,應(yīng)該把這個(gè)做法徹底拋棄! ...

按說(shuō)用狀態(tài)機(jī)檢測(cè)按鍵很方便的,在這個(gè)掃描程序里同時(shí)檢測(cè)短按,長(zhǎng)按和連發(fā)確實(shí)不好實(shí)現(xiàn),可能自己愚笨,現(xiàn)在改用別的方法了。
回復(fù)

使用道具 舉報(bào)

11#
ID:329625 發(fā)表于 2024-7-2 09:07 來(lái)自手機(jī) | 只看該作者
長(zhǎng)按需要加入上時(shí)刻和當(dāng)前狀態(tài)判斷  短按的話(huà)加個(gè)松手檢測(cè) 連發(fā)的話(huà) 去掉松手檢測(cè)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕在线精品 | 天堂av资源 | 羞羞的视频免费在线观看 | 国产精品视频免费看 | 欧美a在线观看 | 成人精品视频在线观看 | 综合久久综合久久 | 黄网站免费观看 | 成人精品在线观看 | 亚洲高清视频一区二区 | 羞羞视频在线观看网站 | 国产成人精品视频在线观看 | 91人人视频在线观看 | 欧美精品一区二区三区在线播放 | 久久精品亚洲国产奇米99 | www操操| 亚洲一区综合 | 国产在线www | 久草.com| av在线视 | 欧美精品一区二区三区四区五区 | www.久草.com | 亚洲国产一区二区三区在线观看 | 国产成人91视频 | 亚洲色图综合网 | 亚洲精品中文字幕在线 | 亚洲精品欧美 | 四虎最新视频 | 中文字幕第一页在线 | 久久av网| 中文字幕二区三区 | 欧美一区2区三区3区公司 | 91网站在线观看视频 | 久久精品一区 | 亚洲36d大奶网 | 亚洲综合成人网 | 日日精品| 日本不卡一区 | 日韩欧美在线一区二区 | 大乳boobs巨大吃奶挤奶 | 国产精品美女一区二区 |