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

QQ登錄

只需一步,快速開始

搜索
查看: 26414|回復(fù): 38
收起左側(cè)

非常穩(wěn)定可靠的單片機(jī)按鍵消抖程序,絕對(duì)不會(huì)產(chǎn)生抖動(dòng)

  [復(fù)制鏈接]
ID:114701 發(fā)表于 2018-5-22 09:15 | 顯示全部樓層 |閱讀模式
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit K1 = P1^0;
void delay1ms(uint n)  
{
    uchar  a,b,c,d;
for(d=n;d>0;d--)
    for(c=1;c>0;c--)
        for(b=222;b>0;b--)
            for(a=12;a>0;a--);
}
void main()
{
    uint i;
        if(K1==0)
        {
                delay1ms(10);  
                if(K1==0)    //
                {
                        for(i=0;i<100;i++)     //此處消抖程序非常經(jīng)典,怎么按都絕對(duì)不會(huì)產(chǎn)生抖動(dòng)。
                        {
                        if(K1==0)
                           i=0;
                        }
                在這兒添加按鍵按下后要執(zhí)行的功能。
                }
        }
}

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:313328 發(fā)表于 2018-10-29 18:32 | 顯示全部樓層
非?梢
回復(fù)

使用道具 舉報(bào)

ID:66287 發(fā)表于 2018-10-30 15:34 | 顯示全部樓層
if(K1==0)    //
                {
                        for(i=0;i<100;i++)     //此處消抖程序非常經(jīng)典,怎么按都絕對(duì)不會(huì)產(chǎn)生抖動(dòng)。
                        {
                        if(K1==0)
                           i=0;
                        }
                在這兒添加按鍵按下后要執(zhí)行的功能。
                }
比較巧妙!
回復(fù)

使用道具 舉報(bào)

ID:66287 發(fā)表于 2018-10-30 15:58 | 顯示全部樓層
說白了就是放手執(zhí)行動(dòng)作,但延時(shí)消抖有些傻傻的,期間什么也干不了。
回復(fù)

使用道具 舉報(bào)

ID:66287 發(fā)表于 2018-10-30 16:02 | 顯示全部樓層
//非常穩(wěn)定可靠的單片機(jī)按鍵消抖程序,絕對(duì)不會(huì)產(chǎn)生抖動(dòng)
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit K1 = P1^4;
sbit K2 = P1^5;
void delay1ms(uint n)  
{
    uchar  a,b,c,d;
for(d=n;d>0;d--)
    for(c=1;c>0;c--)
        for(b=222;b>0;b--)
            for(a=12;a>0;a--);
}
void main()
{
    uint i;
        if(K1==0)
        {
                delay1ms(10);  
                if(K1==0)    //
                {
                        for(i=0;i<100;i++)     //此處消抖程序非常經(jīng)典,怎么按都絕對(duì)不會(huì)產(chǎn)生抖動(dòng)。
                        {
                        if(K1==0)
                           i=0;
                        }


        P0=P0|0x01;     //左移后,最右端自動(dòng)賦值0,所以需要該語句賦值1
        P0<<=1;
                }
        }
                if(K2==0)
        {
                delay1ms(10);  
                if(K2==0)    //
                {
                        for(i=0;i<100;i++)     //此處消抖程序非常經(jīng)典,怎么按都絕對(duì)不會(huì)產(chǎn)生抖動(dòng)。
                        {
                        if(K2==0)
                           i=0;
                        }



        P0 = 0xff;
                }
        }
}


1.png
回復(fù)

使用道具 舉報(bào)

ID:399179 發(fā)表于 2018-10-30 19:11 來自手機(jī) | 顯示全部樓層
感謝樓主分享!
回復(fù)

使用道具 舉報(bào)

ID:419063 發(fā)表于 2018-11-1 13:41 | 顯示全部樓層
有點(diǎn)兒意思!
回復(fù)

使用道具 舉報(bào)

ID:84765 發(fā)表于 2018-11-5 17:26 | 顯示全部樓層
學(xué)習(xí)了!
回復(fù)

使用道具 舉報(bào)

ID:387856 發(fā)表于 2018-12-15 20:17 | 顯示全部樓層
bhjyqjs 發(fā)表于 2018-10-30 15:58
說白了就是放手執(zhí)行動(dòng)作,但延時(shí)消抖有些傻傻的,期間什么也干不了。

兄弟 你不能這么想,按照這位樓主的思路,可以搞成不用傻傻的等啊,利用定時(shí)器中斷不就行了嗎   是不是
回復(fù)

使用道具 舉報(bào)

ID:444306 發(fā)表于 2018-12-16 01:32 | 顯示全部樓層
加油!抓住每一次靈感,活的當(dāng)下才精彩!
回復(fù)

使用道具 舉報(bào)

ID:416139 發(fā)表于 2018-12-16 11:00 | 顯示全部樓層
應(yīng)該再放一個(gè)松手檢測
回復(fù)

使用道具 舉報(bào)

ID:583312 發(fā)表于 2019-7-20 09:48 | 顯示全部樓層
bhjyqjs 發(fā)表于 2018-10-30 15:34
if(K1==0)    //
                {
                        for(i=0;i

太巧秒了
回復(fù)

使用道具 舉報(bào)

ID:515684 發(fā)表于 2019-7-20 14:25 | 顯示全部樓層
還沒學(xué)到這么高級(jí),有需要時(shí)借鑒借鑒。謝謝分享。
回復(fù)

使用道具 舉報(bào)

ID:137005 發(fā)表于 2019-7-20 17:36 | 顯示全部樓層
學(xué)習(xí)學(xué)習(xí),謝謝分享!
回復(fù)

使用道具 舉報(bào)

ID:483407 發(fā)表于 2019-7-20 22:45 | 顯示全部樓層
請(qǐng)問此處的FOR循環(huán),與前面的延時(shí)10毫秒有什么區(qū)別?
回復(fù)

使用道具 舉報(bào)

ID:282726 發(fā)表于 2019-8-10 08:32 | 顯示全部樓層
前面檢測的是按下
后面檢測的松開
回復(fù)

使用道具 舉報(bào)

ID:496061 發(fā)表于 2019-8-14 16:19 | 顯示全部樓層
怎么感覺很多此一舉,小白不是很懂,在第一次按鍵按下后還是用了延時(shí)進(jìn)行了一次消抖,后面還再來一次消抖的意義在哪里?請(qǐng)各位大佬指點(diǎn)
回復(fù)

使用道具 舉報(bào)

ID:71883 發(fā)表于 2019-9-30 16:49 | 顯示全部樓層
樓主我今天試了一下加了關(guān)鍵一句按鍵無法循環(huán),無法做自鎖按鍵,再說你的按下檢測,沒有松手檢測。
回復(fù)

使用道具 舉報(bào)

ID:59909 發(fā)表于 2019-11-11 17:13 | 顯示全部樓層
bhjyqjs 發(fā)表于 2018-10-30 15:58
說白了就是放手執(zhí)行動(dòng)作,但延時(shí)消抖有些傻傻的,期間什么也干不了。

對(duì)頭!一語道破!
回復(fù)

使用道具 舉報(bào)

ID:156923 發(fā)表于 2019-11-26 09:58 | 顯示全部樓層
#include "Key.h"



u16 Key_Lock;                        //按鍵鎖定
u16 Key_Down;                        //按鍵被按下
u16 Key_Up;                          //按鍵釋放
u16 Key_Count[16];                    //消抖計(jì)數(shù)


//消抖次數(shù)
code u16 Key_Threshold[] =
{
100,            //0x0001
100,            //0x0002
1,            //0x0004
1,            //0x0008
1,            //0x0010
1,            //0x0020
1,            //0x0040
1,            //0x0080
1,            //0x0100
1,            //0x0200
1,            //0x0400
1,            //0x0800
1,            //0x1000
1,            //0x2000
1,            //0x4000
1            //0x8000
};


/*========================================================
//觸摸按鍵檢測  主程序 長調(diào)用
//
=========================================================*/
void Key_Scan()
{
    u8 i;
    u16 Loop_Bit = 1;
    u16 Key = 0;

    if(K1_IO == 0)
    {
        Key |= 0x01;
    }

    if(K2_IO == 0)
    {
        Key |= 0x02;
    }

    for(i = 0; i < 16; i++)
    {
        if((Key_Lock & Loop_Bit) == 0)         //如果按鍵未鎖定
        {
            if(Key & Loop_Bit)         //如果按鍵被按下,把相應(yīng)位置位
            {
                Key_Count[i]++;
                if(Key_Count[i] >= Key_Threshold[i])
                {
                    Key_Count[i] = 0;
                    Key_Lock |= Loop_Bit;       //鎖定按鍵
                    Key_Down |= Loop_Bit;       //觸發(fā)按鍵   
                }
            }
            else
            {
                Key_Count[i] = 0;
            }
        }
        else                                      //如果按鍵被鎖定
        {
            if((Key & Loop_Bit) == 0)  //如果按鍵被釋放,把相應(yīng)為清零
            {
                Key_Count[i]++;
                if(Key_Count[i] >= Key_Threshold[i])
                {
                    Key_Count[i] = 0;
                    Key_Lock &= ~Loop_Bit;
                    Key_Up |= Loop_Bit;  
                }
            }
            else
            {
                Key_Count[i] = 0;
            }
        }
        Loop_Bit <<= 1;
    }
}


/*
10毫秒調(diào)用一次
*/
void Key_Handle()
{  
    //組合按鍵
    if((Key_Lock & (KEY1 | KEY2)) == (KEY1 | KEY2))
    {
    }

    //任意按鍵按下
    if(Key_Down)
    {
    }

    //按鍵按下觸發(fā)--
    if(Key_Down & KEY1)
    {
        Key_Down &= ~KEY1;
    }
    //按鍵釋放觸發(fā)
    if(Key_Up & KEY1)
    {
        Key_Up &= ~KEY1;
    }


    //按鍵按下觸發(fā)--
    if(Key_Down & KEY2)
    {
        Key_Down &= ~KEY2;
    }
    //按鍵釋放觸發(fā)
    if(Key_Up & KEY2)
    {
        Key_Up &= ~KEY2;
    }

    //按鍵按下觸發(fā)--
    if(Key_Down & KEY3)
    {
        Key_Down &= ~KEY3;
    }
    //按鍵釋放觸發(fā)
    if(Key_Up & KEY3)
    {
        Key_Up &= ~KEY3;
    }

    //按鍵按下觸發(fā)--
    if(Key_Down & KEY4)
    {
        Key_Down &= ~KEY4;
    }
    //按鍵釋放觸發(fā)--
    if(Key_Up & KEY4)
    {
        Key_Up &= ~KEY4;
    }


}
回復(fù)

使用道具 舉報(bào)

ID:491577 發(fā)表于 2019-11-27 19:28 | 顯示全部樓層
消抖程序已經(jīng)淘汰了,根本就不需要消抖,把按鍵檢測程序放到間隔10ms以上的中斷中,按鍵抖動(dòng)小于10ms,間隔10ms以上的中斷意味著抖動(dòng)期間最多只會(huì)檢測到一次,無論檢測到0還是1都不影響結(jié)果。所以根本就不需要消抖,也不需要按鍵釋放。按鍵釋放程序會(huì)影響數(shù)碼管顯示,一按鍵數(shù)碼管顯示就停止了。
回復(fù)

使用道具 舉報(bào)

ID:235332 發(fā)表于 2019-12-25 15:58 | 顯示全部樓層
非常傻的一種消抖方式,建議不要用,延時(shí)消抖,期間什么都干不了
回復(fù)

使用道具 舉報(bào)

ID:395068 發(fā)表于 2019-12-28 14:03 | 顯示全部樓層
用定時(shí)器中斷消抖比較好
回復(fù)

使用道具 舉報(bào)

ID:65956 發(fā)表于 2020-1-20 14:20 | 顯示全部樓層
很有意思,很有值的學(xué)習(xí)的地方,下次項(xiàng)目可以試看看如何
回復(fù)

使用道具 舉報(bào)

ID:687607 發(fā)表于 2020-1-20 18:50 來自手機(jī) | 顯示全部樓層
來學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:142059 發(fā)表于 2020-1-22 06:58 來自手機(jī) | 顯示全部樓層
不放手是執(zhí)行不了的,你的思路很對(duì),但是還有改進(jìn)的地方
回復(fù)

使用道具 舉報(bào)

ID:604793 發(fā)表于 2020-4-15 11:12 | 顯示全部樓層
hhh402 發(fā)表于 2019-11-27 19:28
消抖程序已經(jīng)淘汰了,根本就不需要消抖,把按鍵檢測程序放到間隔10ms以上的中斷中,按鍵抖動(dòng)小于10ms,間隔 ...

會(huì)檢測錯(cuò)誤吧,假如沒有按下,中斷的時(shí)候檢測到了一次抖動(dòng)是按下的,不就錯(cuò)誤了嘛,還得用統(tǒng)計(jì)的方法吧
回復(fù)

使用道具 舉報(bào)

ID:619259 發(fā)表于 2020-4-15 16:37 | 顯示全部樓層
玩玩可以,沒多大意思。
回復(fù)

使用道具 舉報(bào)

ID:777834 發(fā)表于 2020-9-7 22:26 來自手機(jī) | 顯示全部樓層
rebios 發(fā)表于 2019-8-10 08:32
前面檢測的是按下
后面檢測的松開

怎樣檢測松開的呢,新手,不是很懂,謝謝
回復(fù)

使用道具 舉報(bào)

ID:378732 發(fā)表于 2020-9-8 17:47 | 顯示全部樓層
jianuli 發(fā)表于 2020-9-7 22:26
怎樣檢測松開的呢,新手,不是很懂,謝謝

已經(jīng)是有松手檢測了,手不松i=0   for循環(huán)出不去。手松開之后經(jīng)過i從0到100的延時(shí)出去執(zhí)行按下要執(zhí)行的任務(wù)。
回復(fù)

使用道具 舉報(bào)

ID:817950 發(fā)表于 2020-9-11 16:02 | 顯示全部樓層
太老了,初學(xué)者用延時(shí)消抖,工程中基本都是按鍵狀態(tài)機(jī)了,CPU占用資源少10-20ms調(diào)用一次就行
回復(fù)

使用道具 舉報(bào)

ID:292876 發(fā)表于 2020-9-13 14:46 來自手機(jī) | 顯示全部樓層
咋還討論按鍵次消抖呢?馬師傅按鍵消抖,吳師傅按鍵消抖,都是完美的方法,可以添加單觸發(fā),多觸發(fā),長按等
回復(fù)

使用道具 舉報(bào)

ID:164385 發(fā)表于 2020-9-14 17:55 | 顯示全部樓層
此時(shí)不能做其他事情,其應(yīng)用會(huì)有局限性。
回復(fù)

使用道具 舉報(bào)

ID:928738 發(fā)表于 2022-8-18 15:34 | 顯示全部樓層
做實(shí)驗(yàn)可以,實(shí)際應(yīng)用效果不太好
回復(fù)

使用道具 舉報(bào)

ID:1027834 發(fā)表于 2022-8-19 18:26 | 顯示全部樓層
確實(shí)很經(jīng)典,如果將延時(shí)函數(shù)改為狀態(tài)機(jī)方式進(jìn)行計(jì)時(shí)的話,我想會(huì)使得代碼效率更高。
回復(fù)

使用道具 舉報(bào)

ID:34149 發(fā)表于 2022-8-20 13:19 | 顯示全部樓層
不放手試一試有啥結(jié)果沒?
回復(fù)

使用道具 舉報(bào)

ID:485350 發(fā)表于 2023-4-7 16:44 | 顯示全部樓層
hhh402 發(fā)表于 2019-11-27 19:28
消抖程序已經(jīng)淘汰了,根本就不需要消抖,把按鍵檢測程序放到間隔10ms以上的中斷中,按鍵抖動(dòng)小于10ms,間隔 ...

實(shí)際上非常容易二次觸發(fā)
回復(fù)

使用道具 舉報(bào)

ID:1038987 發(fā)表于 2023-4-8 11:29 | 顯示全部樓層
liuhailan5757 發(fā)表于 2018-12-15 20:17
兄弟 你不能這么想,按照這位樓主的思路,可以搞成不用傻傻的等啊,利用定時(shí)器中斷不就行了嗎   是不是

用電容,并0.1UF電容就可以了
回復(fù)

使用道具 舉報(bào)

ID:1064915 發(fā)表于 2023-4-8 14:17 | 顯示全部樓層
ziyueboy 發(fā)表于 2020-9-13 14:46
咋還討論按鍵次消抖呢?馬師傅按鍵消抖,吳師傅按鍵消抖,都是完美的方法,可以添加單觸發(fā),多觸發(fā),長按等

把程序貼出來
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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