標(biāo)題: 按鍵加減為什么會(huì)出現(xiàn)兩次1 附單片機(jī)程序 [打印本頁(yè)]

作者: sr861126    時(shí)間: 2023-5-24 11:22
標(biāo)題: 按鍵加減為什么會(huì)出現(xiàn)兩次1 附單片機(jī)程序
/********************************************************************
* 文件名  : 獨(dú)立按鍵.c
* 描述    :  該程序?qū)崿F(xiàn)獨(dú)立按鍵去控制 LED燈 的亮滅,并講訴了對(duì)按鍵的處理方法。
                         獨(dú)立按鍵相應(yīng)的IO口平時(shí)為高電平,一旦按鍵按下,單片機(jī)便檢測(cè)到低電平。
                         按下P3.2,P0.0口對(duì)應(yīng)的LED亮滅交替變化。
                         按下P3.3,P0.1口對(duì)應(yīng)的LED亮滅交替變化。
                         按下P3.4,P0.2口對(duì)應(yīng)的LED亮滅交替變化。
* 創(chuàng)建人  : 東流,2009年8月27日
* 版本號(hào)  : 1.0
***********************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int
#define u8 unsigned char
sbit KEY1 = P3^2;   
sbit KEY2 = P3^3;
sbit KEY3 = P3^4;

sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
sfr P4 =0Xe8;
sbit P4_0 = P4^0;
u8 cost=0;
/********************************************************************
* 名稱(chēng) : Delay()
* 功能 : 延時(shí),延時(shí)時(shí)間為 10ms * del
* 輸入 : del
* 輸出 : 無(wú)
***********************************************************************/
void Delay(uint del)
{
        uint i,j;
        for(i=0; i<del; i++)
        for(j=0; j<1827; j++)   
        ;
}

/********************************************************************
* 名稱(chēng) : Delay()
* 功能 : 實(shí)現(xiàn)按鍵功能,當(dāng)按鍵按下時(shí),相應(yīng)的LED亮滅交替
* 輸入 : 無(wú)
* 輸出 : 無(wú)
***********************************************************************/
void KEY()
{
        if(KEY1==0 || KEY2==0 || KEY3==0)        
        {
//                Delay(2);                            //20毫秒軟件防抖
                if(KEY1 == 0)
                {
                Delay(2);
                 P4_0  = 0 ;                //LED顯示取反
             cost++;                  
         SBUF= cost;
                 while(!TI);TI=0;
                }
if(KEY2 == 0)
                {                        
                P4_0 = 1;
                cost--;
                         SBUF= cost;
                           while(!TI);TI=0;
                }
                else
                {                        
                        LED3 = !LED3;
                }
                Delay(50);                        //延時(shí)0.5秒再進(jìn)行下次按鍵的檢測(cè)
        }        
}

/*------------------------------------------------
                    串口初始化
------------------------------------------------*/
void InitUART  (void)
{

    SCON  = 0x50;                        // SCON: 模式 1, 8-bit UART, 使能接收  
//              // TMOD: timer 1, mode 2, 8-bit 重裝
    TMOD |= 0x21;    //T1方式2、T0方式1
        TH1   = 0xFD;               // TH1:  重裝值 9600 波特率 晶振 11.0592MHz  
    TL1 = 0xFD;      //波特率
        TR1   = 1;                  // TR1:  timer 1 打開(kāi)                        
    IE |= 0x92;      //開(kāi)啟中斷
        EA    = 1;                  //打開(kāi)總中斷
//    ES    = 1;                  //打開(kāi)串口中斷
}                           

  初始時(shí)按鍵按下,計(jì)數(shù)器出現(xiàn)兩次1,或者不累加是什么問(wèn)題?


/********************************************************************
* 名稱(chēng) : Main()
* 功能 : 實(shí)現(xiàn)按鍵控制LED的亮滅
* 輸入 : 無(wú)
* 輸出 : 無(wú)
***********************************************************************/
void Main(void)
{
        
        InitUART();
        while(1)
        {
                 KEY();
        }
}

捕獲.PNG (12.67 KB, 下載次數(shù): 37)

捕獲.PNG

作者: 123456ZXC1    時(shí)間: 2023-5-24 12:29
可能是由于按鍵的按下動(dòng)作引起了按鍵的抖動(dòng)
作者: sr861126    時(shí)間: 2023-5-24 15:51
123456ZXC1 發(fā)表于 2023-5-24 12:29
可能是由于按鍵的按下動(dòng)作引起了按鍵的抖動(dòng)

但是后面再按就沒(méi)有抖動(dòng)了,只是初始時(shí)有這樣的情況
作者: A-set    時(shí)間: 2023-5-24 17:22
按鍵1的消抖再判斷之后的里面的那個(gè)延時(shí)去掉看看還有沒(méi)有
作者: A-set    時(shí)間: 2023-5-24 17:23
sr861126 發(fā)表于 2023-5-24 15:51
但是后面再按就沒(méi)有抖動(dòng)了,只是初始時(shí)有這樣的情況

按鍵1消抖后里面的延時(shí)去掉看看還有沒(méi)有
作者: huaruolong    時(shí)間: 2023-5-24 18:41
你這程序是沒(méi)copy全,還是就是這樣, SBUF,TI,都沒(méi)看到定義。難到不會(huì)報(bào)錯(cuò)。另建議key,不要用p3.2,P3.3,p3.4.因?yàn)檫@幾個(gè)IO有第二功能,在用這幾個(gè)io時(shí)就有可能和其他沖突,程序肯定不會(huì)報(bào)錯(cuò),但可能會(huì)有莫名奇妙的問(wèn)題產(chǎn)生。
作者: wulin    時(shí)間: 2023-5-24 21:18
描述與按鍵代碼不一致,你這代碼近乎長(zhǎng)短按,短按響應(yīng)一次,長(zhǎng)按每隔0.5秒重復(fù)響應(yīng)。延時(shí)消抖被注釋掉了,移放在不恰當(dāng)?shù)奈恢谩?hr noshade size="2" width="100%" color="#808080"> 作者: 188610329    時(shí)間: 2023-5-24 22:21
和按鍵抖動(dòng)無(wú)關(guān), 如果抖動(dòng)了, 發(fā)送前 肯定會(huì) ++ 或者 -- 一次, 絕對(duì)有別的代碼,  所謂的 發(fā)兩次1 是要發(fā) 2 的時(shí)候被 -1 了,  看你那個(gè)  5 后面  發(fā)了個(gè)3 就知道, 肯定有個(gè)地方在  - cost
作者: sr861126    時(shí)間: 2023-5-25 07:56
188610329 發(fā)表于 2023-5-24 22:21
和按鍵抖動(dòng)無(wú)關(guān), 如果抖動(dòng)了, 發(fā)送前 肯定會(huì) ++ 或者 -- 一次, 絕對(duì)有別的代碼,  所謂的 發(fā)兩次1 是要發(fā) 2  ...

別人的地方?jīng)]有--,初始時(shí)是0,按理說(shuō)按一次就加1,但是按了2次才加1,后面按就正常按一次加1
作者: sr861126    時(shí)間: 2023-5-25 08:28
188610329 發(fā)表于 2023-5-24 22:21
和按鍵抖動(dòng)無(wú)關(guān), 如果抖動(dòng)了, 發(fā)送前 肯定會(huì) ++ 或者 -- 一次, 絕對(duì)有別的代碼,  所謂的 發(fā)兩次1 是要發(fā) 2  ...

  按一次,抖動(dòng)了出現(xiàn)了兩個(gè)“1”

捕獲.PNG (18.04 KB, 下載次數(shù): 30)

捕獲.PNG

作者: sr861126    時(shí)間: 2023-5-25 08:43
huaruolong 發(fā)表于 2023-5-24 18:41
你這程序是沒(méi)copy全,還是就是這樣, SBUF,TI,都沒(méi)看到定義。難到不會(huì)報(bào)錯(cuò)。另建議key,不要用p3.2,P3.3 ...

沒(méi)有關(guān)系,還是抖動(dòng)的問(wèn)題

作者: sr861126    時(shí)間: 2023-5-25 08:45
123456ZXC1 發(fā)表于 2023-5-24 12:29
可能是由于按鍵的按下動(dòng)作引起了按鍵的抖動(dòng)

是抖動(dòng),剛上電按下出現(xiàn)抖動(dòng),后面按就沒(méi)有抖動(dòng)了
作者: sr861126    時(shí)間: 2023-5-25 08:59
sr861126 發(fā)表于 2023-5-25 08:43
沒(méi)有關(guān)系,還是抖動(dòng)的問(wèn)題

為什么消不掉呢

作者: sr861126    時(shí)間: 2023-5-25 10:11
A-set 發(fā)表于 2023-5-24 17:23
按鍵1消抖后里面的延時(shí)去掉看看還有沒(méi)有

去掉延時(shí)是一樣de

作者: 人中狼    時(shí)間: 2023-5-25 10:28
找個(gè)例程看看防抖怎么做吧,暫時(shí)看是防抖沒(méi)做好,或者說(shuō)沒(méi)做防抖

作者: 涅槃重生1    時(shí)間: 2023-5-25 20:01
按鍵代碼需要做消抖處理
作者: 188610329    時(shí)間: 2023-5-26 00:05
sr861126 發(fā)表于 2023-5-25 08:28
按一次,抖動(dòng)了出現(xiàn)了兩個(gè)“1”

你明白抖動(dòng)的意思么?
按你的代碼,如果按鍵抖動(dòng),應(yīng)該按一次后,連續(xù)發(fā)出 01,02  甚至還有 03
但是,你是發(fā)兩次  01, 說(shuō)明,運(yùn)行了兩次  SBUF = cost, 卻沒(méi)有運(yùn)行兩次 cost++,所以和抖動(dòng)沒(méi)有任何關(guān)系。
作者: wulin    時(shí)間: 2023-5-26 08:47
188610329 發(fā)表于 2023-5-26 00:05
你明白抖動(dòng)的意思么?
按你的代碼,如果按鍵抖動(dòng),應(yīng)該按一次后,連續(xù)發(fā)出 01,02  甚至還有 03
但是, ...

同意17樓意見(jiàn),雖然樓主按鍵代碼寫(xiě)得......,但問(wèn)題核心不在于此。在于串口初始化函數(shù)被胡亂開(kāi)啟中斷。眾所周知,T1作為波特率發(fā)生器就得禁止定時(shí)器1中斷。否則就可能發(fā)生不可預(yù)測(cè)的錯(cuò)誤。按如下設(shè)置問(wèn)題迎刃而解。
void InitUART(void)                //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位數(shù)據(jù),可變波特率
        TMOD |= 0x20;                //設(shè)置定時(shí)器模式
        TL1 = 0xFD;                //設(shè)置定時(shí)初始值
        TH1 = 0xFD;                //設(shè)置定時(shí)重載值
        ET1 = 0;                //禁止定時(shí)器1中斷
        TR1 = 1;                //定時(shí)器1開(kāi)始計(jì)時(shí)
}
作者: yueguang3048    時(shí)間: 2023-5-26 09:23
沒(méi)細(xì)看程序,完按鍵,記得檢測(cè)按鍵松開(kāi)
作者: 陶888    時(shí)間: 2023-5-26 14:26
按鍵加減時(shí)出現(xiàn)兩次1的情況通常是由于按鍵抖動(dòng)引起的。按鍵抖動(dòng)是指在按下或釋放按鍵時(shí),由于機(jī)械性質(zhì)或電氣接觸不穩(wěn)定等原因,導(dǎo)致按鍵信號(hào)在短時(shí)間內(nèi)多次切換狀態(tài)。這種抖動(dòng)可能會(huì)導(dǎo)致單片機(jī)在檢測(cè)按鍵狀態(tài)時(shí)誤認(rèn)為按鍵被按下了兩次。  為了解決按鍵抖動(dòng)問(wèn)題,可以在軟件中使用適當(dāng)?shù)陌存I消抖算法。一種常用的按鍵消抖方法是使用軟件延時(shí)和狀態(tài)判斷的組合。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1