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

QQ登錄

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

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

關(guān)于單片機(jī)按鍵長(zhǎng)按過(guò)程中觸發(fā)短按的問(wèn)題?萌新求各位指導(dǎo)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:540927 發(fā)表于 2020-8-29 11:15 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
我的程序在按鍵長(zhǎng)按過(guò)程中會(huì)觸發(fā)短按,一般一次長(zhǎng)按在開(kāi)始和結(jié)束時(shí)各觸發(fā)一次短按,不知道怎么改程序才合適,求各位指導(dǎo)

捕獲.PNG (12.82 KB, 下載次數(shù): 122)

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

使用道具 舉報(bào)

沙發(fā)
ID:816093 發(fā)表于 2020-8-29 12:15 | 只看該作者
應(yīng)該是按下的時(shí)候 按鍵的機(jī)械抖動(dòng) 造成側(cè)毛刺信號(hào) 所以觸發(fā)了短按檢測(cè) 在按下和結(jié)束的時(shí)候加延時(shí)再檢測(cè)試一下
回復(fù)

使用道具 舉報(bào)

板凳
ID:236035 發(fā)表于 2020-8-29 13:31 | 只看該作者
if(exKeyValueFlag != 0)
{
        if(i<1000)
        {
                i++;
                if(i > 1500)
                {
                        longkeyflag = 1;
                        i = 0;
                }
        }
}
else
{
        if(i>50)
        {
                shortkeyflag = 1;
                i = 0;
        }
        else
                i = 0;
}
回復(fù)

使用道具 舉報(bào)

地板
ID:236035 發(fā)表于 2020-8-29 13:32 | 只看該作者
1 上面的回復(fù)是純手打,因?yàn)闃侵魑坏某绦驘o(wú)法復(fù)制
2 有問(wèn)題先百度下,有很多經(jīng)典例程,如果實(shí)在解決不了,再發(fā)貼提問(wèn) 。
回復(fù)

使用道具 舉報(bào)

5#
ID:540927 發(fā)表于 2020-8-29 14:14 | 只看該作者
meitao 發(fā)表于 2020-8-29 12:15
應(yīng)該是按下的時(shí)候 按鍵的機(jī)械抖動(dòng) 造成側(cè)毛刺信號(hào) 所以觸發(fā)了短按檢測(cè) 在按下和結(jié)束的時(shí)候加延時(shí)再檢測(cè)試一 ...

感謝您的回復(fù),消抖已經(jīng)處理過(guò)了,我只粘貼出來(lái)計(jì)數(shù)部分
回復(fù)

使用道具 舉報(bào)

6#
ID:540927 發(fā)表于 2020-8-29 14:18 | 只看該作者
ly1972001 發(fā)表于 2020-8-29 13:32
1 上面的回復(fù)是純手打,因?yàn)闃侵魑坏某绦驘o(wú)法復(fù)制
2 有問(wèn)題先百度下,有很多經(jīng)典例程,如果實(shí)在解決不了, ...

辛苦了,感謝您的程序和建議
回復(fù)

使用道具 舉報(bào)

7#
ID:540927 發(fā)表于 2020-8-29 14:33 | 只看該作者
ly1972001 發(fā)表于 2020-8-29 13:31
if(exKeyValueFlag != 0)
{
        if(i 1500)

謝謝您的代碼,參考了您的代碼,抬起手的時(shí)候不觸發(fā)短按了,但是剛開(kāi)始的時(shí)候還是觸發(fā)了短按
回復(fù)

使用道具 舉報(bào)

8#
ID:540927 發(fā)表于 2020-8-29 15:08 | 只看該作者
ly1972001 發(fā)表于 2020-8-29 13:31
if(exKeyValueFlag != 0)
{
        if(i 1500)


這是修改后的程序

捕獲.PNG (11.19 KB, 下載次數(shù): 146)

捕獲.PNG
回復(fù)

使用道具 舉報(bào)

9#
ID:89515 發(fā)表于 2020-8-30 11:43 來(lái)自手機(jī) | 只看該作者
山水間 發(fā)表于 2020-8-29 15:08
這是修改后的程序

按鍵按下
{
}
回復(fù)

使用道具 舉報(bào)

10#
ID:89515 發(fā)表于 2020-8-30 12:11 來(lái)自手機(jī) | 只看該作者
山水間 發(fā)表于 2020-8-29 15:08
這是修改后的程序

按鍵按下
{
1:確定按下實(shí)現(xiàn)短按鍵功能退出
2:按鍵是否彈起?
     彈起退出進(jìn)入3
按鍵沒(méi)彈起,延時(shí)變量加,
      延時(shí)變量是否達(dá)到設(shè)定值?
達(dá)到,實(shí)現(xiàn)長(zhǎng)按鍵功能退出進(jìn)入3
未達(dá)到,退出返回2
3:清除變量退出返回1
}
無(wú)論你要做什么按鍵邏輯上首先要保證按鍵按下
吧,你的程序就算勉強(qiáng)實(shí)現(xiàn),邏輯也有很大的問(wèn)題。
回復(fù)

使用道具 舉報(bào)

11#
ID:89515 發(fā)表于 2020-8-30 12:14 來(lái)自手機(jī) | 只看該作者
山水間 發(fā)表于 2020-8-29 15:08
這是修改后的程序


1:確定按下實(shí)現(xiàn)短按鍵功能退出
2:按鍵是否彈起?
     彈起退出進(jìn)入3
按鍵沒(méi)彈起,延時(shí)變量加,
      延時(shí)變量是否達(dá)到設(shè)定值?
達(dá)到,實(shí)現(xiàn)長(zhǎng)按鍵功能退出進(jìn)入3
未達(dá)到,退出返回2
3:清除變量退出返回1

無(wú)論你要做什么按鍵邏輯上首先要保證按鍵按下
過(guò)吧,你的程序就算勉強(qiáng)實(shí)現(xiàn),邏輯也有很大的問(wèn)題。
回復(fù)

使用道具 舉報(bào)

12#
ID:89515 發(fā)表于 2020-8-30 12:17 來(lái)自手機(jī) | 只看該作者
這種程序用狀態(tài)機(jī)最簡(jiǎn)單,單個(gè)按鍵所有的按鍵功能都可以在里面實(shí)現(xiàn)
回復(fù)

使用道具 舉報(bào)

13#
ID:808485 發(fā)表于 2020-8-31 14:39 | 只看該作者
一般區(qū)分長(zhǎng)短,是在抬起的時(shí)候判斷,
如果還未抬起的情況下要做出判斷,那長(zhǎng)按過(guò)程肯定會(huì)經(jīng)過(guò)短按的時(shí)間,這個(gè)邏輯應(yīng)該容易理解,就像走路100步,會(huì)先走過(guò)30步。
對(duì)于單鍵多用,建議用單擊/雙擊的方法,像鼠標(biāo)那樣。
回復(fù)

使用道具 舉報(bào)

14#
ID:540927 發(fā)表于 2020-8-31 14:52 | 只看該作者
本帖最后由 山水間 于 2020-8-31 15:27 編輯
mengzhixinheng 發(fā)表于 2020-8-30 12:17
這種程序用狀態(tài)機(jī)最簡(jiǎn)單,單個(gè)按鍵所有的按鍵功能都可以在里面實(shí)現(xiàn)

感謝您的回復(fù),現(xiàn)在我用狀態(tài)機(jī)了,可惜連短按都無(wú)法實(shí)現(xiàn)
void key()
{
        static CHAR keystate = keystate0;
        INT16U keytime = 0;
        CHAR keypress;
        keypress = exKeyValueFlag;            //讀取按鍵
        switch(keystate)
        {
                case keystate0:
                        if(keypress != 0)
                        {
                                keystate =keystate1;
                        }
                        break;
                        
                case keystate1:                      //計(jì)時(shí)狀態(tài)
                        if(keypress != 0)
                        {
                                keytime++;
                                keystate = keystate2;
                        }
                       
                        break;
                        
                case keystate2:                      //按鍵判斷狀態(tài)
                        if(keypress == 0)
                        {
                                if((keytime >= 10)&&(keytime <= 1000))
                                {
                                        keytime = 0;
                                        shortkeyflag = 1;
                                        keystate = keystate0;
                                }
                                else if(keytime >= 3000)
                                {
                                        keytime = 0;
                                        longkeyflag =1;
                                        keystate = keystate0;
                                }
                        }
                        else
                        {
                                keystate = keystate1;
                        }
                break;     
        }
}
回復(fù)

使用道具 舉報(bào)

15#
ID:540927 發(fā)表于 2020-8-31 14:53 | 只看該作者
gbchang 發(fā)表于 2020-8-31 14:39
一般區(qū)分長(zhǎng)短,是在抬起的時(shí)候判斷,
如果還未抬起的情況下要做出判斷,那長(zhǎng)按過(guò)程肯定會(huì)經(jīng)過(guò)短按的時(shí)間, ...

好的,謝謝您的回復(fù),我試著這么做
回復(fù)

使用道具 舉報(bào)

16#
ID:511890 發(fā)表于 2020-9-1 00:23 | 只看該作者
有很多問(wèn)題。if語(yǔ)句的用法問(wèn)題。if語(yǔ)句每一個(gè)分支都必須是唯一的。你的if語(yǔ)句第一個(gè)i<10000,和第二個(gè)i>50,當(dāng)i=51---9999的時(shí)候,兩個(gè)if分支是同事觸發(fā)的。
然后是按鍵事件問(wèn)題,一般這個(gè)情況都是在按鍵抬起(exKeyValueFlag == 0)時(shí)進(jìn)行事件處理。

修改程序如下:
if(exKeyValueFlag != 0)
{
    if(i<10000) {
           i++;
    }
    else{
         i=10000;//i達(dá)到最大值時(shí)定住,防止溢出
     }
}
else   //當(dāng)按鍵抬起時(shí)做判斷
{
        if(i > 1500) {
                        longkeyflag = 1;
                }
        else{                           //這里也可以按照你的意思:if(i>50 && i<200)
               shortkeyflag = 1;
        }
        }
     i = 0;//i初始化
}
--------------------------------------
前天發(fā)的好像不見(jiàn)了。再發(fā)以下。
有很多問(wèn)題。if語(yǔ)句的用法問(wèn)題。if語(yǔ)句每一個(gè)分支都必須是唯一的。你的if語(yǔ)句第一個(gè)i<10000,和第二個(gè)i>50,當(dāng)i=51---9999的時(shí)候,兩個(gè)if分支是同事觸發(fā)的。
然后是按鍵事件問(wèn)題,一般這個(gè)情況都是在按鍵抬起(exKeyValueFlag == 0)時(shí)進(jìn)行事件處理。


if(exKeyValueFlag != 0)
{
    if(i<10000) {
           i++;
    }
    else{
         i=10000;//i達(dá)到最大值時(shí)定住,防止溢出
     }
  //if(i > 1500) {
  //                      longkeyflag = 1;
   //             }

}
else   //當(dāng)按鍵抬起時(shí)做判斷
{
        if(i > 1500) {
                        longkeyflag = 1;
                }
        else{                           //這里也可以按照你的意思:if(i>50 && i<200)
               shortkeyflag = 1;
        }
        }
     i = 0;//i初始化
}

一般這種情況都是按鍵抬起時(shí)再做事件。當(dāng)然,也可以分成兩部分,長(zhǎng)按的放在按鍵按下時(shí)處理,也就是我注釋掉的那三行。

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

17#
ID:469932 發(fā)表于 2020-9-1 08:24 | 只看該作者
很簡(jiǎn)單的問(wèn)題繞了這么遠(yuǎn),你不會(huì)在短按鍵時(shí)加1個(gè)標(biāo)志位,在長(zhǎng)按鍵中約束這個(gè)標(biāo)志位?
比如if(SW長(zhǎng)==0){.........FLAG1=0;//短按鍵失控......}
if(SW短 == 0  && FLAG == 1)這時(shí)的短按鍵無(wú)論如何不會(huì)觸發(fā)......你品,你細(xì)品!
回復(fù)

使用道具 舉報(bào)

18#
ID:540927 發(fā)表于 2020-9-1 11:41 | 只看該作者
幻劍心 發(fā)表于 2020-9-1 00:23
前天發(fā)的好像不見(jiàn)了。再發(fā)以下。
有很多問(wèn)題。if語(yǔ)句的用法問(wèn)題。if語(yǔ)句每一個(gè)分支都必須是唯一的。你的if ...

感謝您的回復(fù),您的這個(gè)方案我嘗試了,不過(guò)長(zhǎng)按不能觸發(fā),在長(zhǎng)按的過(guò)程中短按也觸發(fā)了,出發(fā)的時(shí)候按鍵還沒(méi)有抬起,這與程序不符,可能是我用的彈簧按鍵有點(diǎn)特殊吧
回復(fù)

使用道具 舉報(bào)

19#
ID:540927 發(fā)表于 2020-9-1 11:44 | 只看該作者
Sawardeakar 發(fā)表于 2020-9-1 08:24
很簡(jiǎn)單的問(wèn)題繞了這么遠(yuǎn),你不會(huì)在短按鍵時(shí)加1個(gè)標(biāo)志位,在長(zhǎng)按鍵中約束這個(gè)標(biāo)志位?
比如if(SW長(zhǎng)==0){... ...

感謝您的建言,加個(gè)標(biāo)志位我也有考慮過(guò),不過(guò)關(guān)鍵是要在什么地方把標(biāo)志位置1
回復(fù)

使用道具 舉報(bào)

20#
ID:540927 發(fā)表于 2020-9-1 11:48 | 只看該作者
gbchang 發(fā)表于 2020-8-31 14:39
一般區(qū)分長(zhǎng)短,是在抬起的時(shí)候判斷,
如果還未抬起的情況下要做出判斷,那長(zhǎng)按過(guò)程肯定會(huì)經(jīng)過(guò)短按的時(shí)間, ...

我的短按就是在抬起時(shí)才判斷的,但是實(shí)際執(zhí)行過(guò)程中長(zhǎng)按下去還沒(méi)抬起就觸發(fā)了短按
回復(fù)

使用道具 舉報(bào)

21#
ID:474670 發(fā)表于 2020-9-1 14:27 | 只看該作者
山水間 發(fā)表于 2020-9-1 11:44
感謝您的建言,加個(gè)標(biāo)志位我也有考慮過(guò),不過(guò)關(guān)鍵是要在什么地方把標(biāo)志位置1

有句話叫經(jīng)驗(yàn)不夠,汗水來(lái)湊!別人將思路很明確的告訴你了,就是不知道去動(dòng)動(dòng)手,一味在那里干站著干問(wèn)!很明顯不要短按鍵誤動(dòng)作就放FLAG=0,要短按鍵動(dòng)作就放FLAG=1;比如你手機(jī)。短按是開(kāi)關(guān)機(jī)畫(huà)面,按時(shí)間長(zhǎng)一點(diǎn)就是重啟與真正關(guān)機(jī)(這個(gè)時(shí)候的長(zhǎng)按鍵與短按鍵都有效)
回復(fù)

使用道具 舉報(bào)

22#
ID:89515 發(fā)表于 2020-9-1 15:34 來(lái)自手機(jī) | 只看該作者
gbchang 發(fā)表于 2020-8-31 14:39
一般區(qū)分長(zhǎng)短,是在抬起的時(shí)候判斷,
如果還未抬起的情況下要做出判斷,那長(zhǎng)按過(guò)程肯定會(huì)經(jīng)過(guò)短按的時(shí)間, ...

你說(shuō)的是常規(guī)方法,一直按下自然要經(jīng)過(guò)短按鍵
但是如果用狀態(tài)機(jī)把長(zhǎng)按鍵放在下一個(gè)狀態(tài)。與短按鍵不會(huì)互相影響,因?yàn)闊o(wú)論怎么做,每次按下傳回的鍵值只能有一個(gè)。還有長(zhǎng)按鍵,連續(xù)按鍵都是在按下?tīng)顟B(tài)去判斷的,怎么可能彈起再判斷,不符合邏輯。你想我按下按鍵,當(dāng)延時(shí)到了就返回長(zhǎng)按鍵鍵值實(shí)現(xiàn)功能,然后我松開(kāi)按鍵這是正常的過(guò)程。如果抬起判斷,你知道是什么后果嗎?很簡(jiǎn)單,長(zhǎng)按鍵的時(shí)間只能靠人為去感知,可能按短了實(shí)現(xiàn)不了,也可能按長(zhǎng)了,功能倒是實(shí)現(xiàn)了,但你這樣做了就知道很不爽的。
回復(fù)

使用道具 舉報(bào)

23#
ID:89515 發(fā)表于 2020-9-1 15:52 來(lái)自手機(jī) | 只看該作者
山水間 發(fā)表于 2020-8-31 14:52
感謝您的回復(fù),現(xiàn)在我用狀態(tài)機(jī)了,可惜連短按都無(wú)法實(shí)現(xiàn)
void key()
{

函數(shù)內(nèi)靜態(tài)變量別賦值,要賦值就用全局變量,
怕變量多凌亂就就用結(jié)構(gòu)體把相關(guān)的放一起。這個(gè)用狀態(tài)機(jī)絕對(duì)很好,它可以讓你避開(kāi)一些互鎖標(biāo)志,過(guò)程很清晰,也不用管消抖,把按鍵程序?qū)懞昧,做個(gè)20ms的時(shí)基,往里面一放就好了。你要用的只是返回的不同鍵值,與你實(shí)現(xiàn)的功能不要有太多的耦合。如果還是很久都搞不好,就做個(gè)簡(jiǎn)單的按鍵仿真,先把方法學(xué)會(huì)。
回復(fù)

使用道具 舉報(bào)

24#
ID:89515 發(fā)表于 2020-9-1 16:06 來(lái)自手機(jī) | 只看該作者
山水間 發(fā)表于 2020-8-31 14:52
感謝您的回復(fù),現(xiàn)在我用狀態(tài)機(jī)了,可惜連短按都無(wú)法實(shí)現(xiàn)
void key()
{

函數(shù)內(nèi)靜態(tài)變量別賦常值,不然它怎么變化。如果不行,就做個(gè)仿真,把一個(gè)按鍵搞會(huì),在嵌入你的程序。如果還不會(huì)再問(wèn)吧!
回復(fù)

使用道具 舉報(bào)

25#
ID:540927 發(fā)表于 2020-9-1 16:24 | 只看該作者
站著說(shuō)話不腰疼 發(fā)表于 2020-9-1 14:27
有句話叫經(jīng)驗(yàn)不夠,汗水來(lái)湊!別人將思路很明確的告訴你了,就是不知道去動(dòng)動(dòng)手,一味在那里干站著干問(wèn)! ...

感謝您的建議,我會(huì)認(rèn)真思考的
回復(fù)

使用道具 舉報(bào)

26#
ID:540927 發(fā)表于 2020-9-1 16:27 | 只看該作者
mengzhixinheng 發(fā)表于 2020-9-1 16:06
函數(shù)內(nèi)靜態(tài)變量別賦常值,不然它怎么變化。如果不行,就做個(gè)仿真,把一個(gè)按鍵搞會(huì),在嵌入你的程序。如果 ...

好的,謝謝您如此詳細(xì)又耐心的指導(dǎo),我試著掌握狀態(tài)機(jī)的用法
回復(fù)

使用道具 舉報(bào)

27#
ID:540927 發(fā)表于 2020-9-2 10:31 | 只看該作者
感謝所有回復(fù)提出寶貴建議的人,我的問(wèn)題已經(jīng)解決,真的謝謝大家
回復(fù)

使用道具 舉報(bào)

28#
ID:130230 發(fā)表于 2020-9-2 23:50 | 只看該作者
我再論壇里面發(fā)過(guò)一個(gè)狀態(tài)機(jī)掃描按鍵的實(shí)例,你可以看一下。拿來(lái)即用的程序。
回復(fù)

使用道具 舉報(bào)

29#
ID:540927 發(fā)表于 2020-9-3 10:32 | 只看該作者
jizhongbiao 發(fā)表于 2020-9-2 23:50
我再論壇里面發(fā)過(guò)一個(gè)狀態(tài)機(jī)掃描按鍵的實(shí)例,你可以看一下。拿來(lái)即用的程序。

好的,謝謝您的建議
回復(fù)

使用道具 舉報(bào)

30#
ID:475858 發(fā)表于 2022-9-14 14:01 | 只看該作者
站著說(shuō)話不腰疼 發(fā)表于 2020-9-1 14:27
有句話叫經(jīng)驗(yàn)不夠,汗水來(lái)湊!別人將思路很明確的告訴你了,就是不知道去動(dòng)動(dòng)手,一味在那里干站著干問(wèn)! ...

這樣操作的話,短按一直不起作用了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表