標(biāo)題: 51單片機(jī)識(shí)別 "單擊.雙擊.長(zhǎng)按"-我寫(xiě)的代碼相信你能讀懂 [打印本頁(yè)]

作者: Kxuan163    時(shí)間: 2024-11-17 12:22
標(biāo)題: 51單片機(jī)識(shí)別 "單擊.雙擊.長(zhǎng)按"-我寫(xiě)的代碼相信你能讀懂
//51單片機(jī)識(shí)別 "單擊.雙擊.長(zhǎng)按" 代碼
//作者:Kxuan163
//程序功能:檢測(cè)按鈕的按下彈起次數(shù),以識(shí)別"單擊.雙擊.長(zhǎng)按"
//MCU: STC89c52RC        晶振 11.0592MHZ
//Proteus8仿真通過(guò);51開(kāi)發(fā)板實(shí)驗(yàn)通過(guò)。

#include<reg52.h>   
#include<stdlib.h>  
sbit button =P1^2;    //按鈕連接的單片機(jī)引腳
sbit LED1 =P2^7;             //單擊則LED1亮
sbit LED2 =P2^4;      //雙擊則LED2亮
sbit LED3 =P2^0;      //長(zhǎng)按則LED3亮
unsigned char count;  //T0計(jì)數(shù)溢出中斷次數(shù)
unsigned char finish; //T0計(jì)時(shí)一輪結(jié)束標(biāo)志
unsigned char read;   //讀取P1^2引腳電平的變量
unsigned char dn;     //讀得P1^2引腳低電平次數(shù)
unsigned char up;     //button彈起次數(shù)

//延時(shí)函數(shù),入口參數(shù)ms為延時(shí)的毫秒數(shù)/////
void delayms(unsigned int ms)
{         unsigned char i;
        while(ms--)
        { for(i = 0; i < 120; i++); }                                       
} //////////////////////////////////////

//主函數(shù)
void main(void)         
{
  //T0 初始化 //////////////////////////
         TMOD=0x01;              //使用定時(shí)器T0的模式1
    TH0=(65536-46083)/256;  //定時(shí)器T0的高8位設(shè)置初值
    TL0=(65536-46083)%256;  //定時(shí)器T0的低8位設(shè)置初值
    EA=1;                   //開(kāi)總中斷
    ET0=1;                  //T0中斷允許
  //////////////////////////////////////

  while(1)
   {
    LED1 =1; LED2=1; LED3=1;
    dn =0; up=0; count =0; finish =0;

    TR0=1;              //啟動(dòng)T0計(jì)時(shí)
    while(finish !=1 )  //在設(shè)定的T0計(jì)時(shí)段內(nèi)循環(huán)檢測(cè)
     {
      read =button;            //讀取P1^2引腳電平
          if (read == 0) delayms(10); //延時(shí)10毫秒消熱抖動(dòng)         

          if (button == 0)
            {dn ++; read =button;} //讀得P1^2低電平次數(shù)累加

          if (read ==0 && button ==1) up ++;//彈起次數(shù)累加
         } //end of while(finish !=1 )

    // T0計(jì)時(shí)一輪結(jié)束,進(jìn)行識(shí)別:
        TR0 =0;
    if (dn >=1 && up ==1 )       //彈起1次,即單擊               
              { LED1 =0; delayms(1000);} //LED1亮

    if (dn >=2 && up ==2 )            //彈起2次,即雙擊               
       { LED2=0; delayms(1000);}  //LED2亮

        if (dn>=20 && up==0 )        //持續(xù)未彈起,即長(zhǎng)按     
              { LED3=0; delayms(1000);}  //LED3亮         
         
   } //end of while(1)
} //end of main()  


//函數(shù):定時(shí)器T0的中斷服務(wù) ////////////////
void Time0(void ) interrupt 1 using 1
  {
    count++;            //T0計(jì)數(shù)溢出中斷次數(shù)累加
    if(count==20)  //若T0計(jì)數(shù)溢出次數(shù)累計(jì)達(dá)設(shè)定值
          {count =0; finish =1;} //一輪計(jì)時(shí)結(jié)束                          

         TH0=(65536-46083)/256;  
        TL0=(65536-46083)%256;  
  } ///////////////////////////////////////






作者: lkc8210    時(shí)間: 2024-11-17 22:13
看到while+delayms就知道不用看懂也可以

作者: Kxuan163    時(shí)間: 2024-11-17 23:50
lkc8210 發(fā)表于 2024-11-17 22:13
看到while+delayms就知道不用看懂也可以

謝謝跟帖!
我嘗試過(guò)用此算法,將代碼略加修改即可識(shí)別三擊...
作者: qsssuv    時(shí)間: 2024-11-18 11:45
http://www.torrancerestoration.com/bbs/dpj-238107-1.html
作者: STC莊偉    時(shí)間: 2024-11-19 08:51
你用AI8051U的 支持USB下載  兼容89C52的  
作者: Kxuan163    時(shí)間: 2024-11-19 11:39
STC莊偉 發(fā)表于 2024-11-19 08:51
你用AI8051U的 支持USB下載  兼容89C52的

謝謝莊偉先生建議,我亦正有此意。
作者: 趙八百    時(shí)間: 2024-11-19 16:52
你這個(gè)delay10ms不要這樣寫(xiě),你1ms近義詞中斷,20ms掃描一次就已經(jīng)消抖了,
作者: Kxuan163    時(shí)間: 2024-11-20 10:49
發(fā)表于 2024-11-19 16:52
你這個(gè)delay10ms不要這樣寫(xiě),你1ms近義詞中斷,20ms掃描一次就已經(jīng)消抖了,

delayms(10); //延時(shí)10毫秒消熱抖動(dòng)   ------這行代碼無(wú)問(wèn)題。有 書(shū)為依據(jù)
作者: xujibicool    時(shí)間: 2024-11-20 21:16
你都用定時(shí)器,還搞個(gè)delay 帶壞小朋友
作者: Kxuan163    時(shí)間: 2024-11-21 11:59
發(fā)表于 2024-11-20 21:16
你都用定時(shí)器,還搞個(gè)delay

定時(shí)器中斷方式計(jì)時(shí), delayms()軟件方式計(jì)時(shí),  各有各的用途。你未完全讀懂。
作者: dj3365191    時(shí)間: 2024-11-21 17:22
有時(shí)候按兩次還是LED1亮,程序修改哪里才能避免這種情況發(fā)生
作者: Kxuan163    時(shí)間: 2024-11-22 12:15
dj3365191 發(fā)表于 2024-11-21 17:22
有時(shí)候按兩次還是LED1亮,程序修改哪里才能避免這種情況發(fā)生

你是用proteus仿真嗎?  晶振是否 11.0592MHZ?
我剛剛為解答你的問(wèn)題,試修改代碼,再次仿真成功。
原代碼   if (read == 0) delayms(10);  //延時(shí)10毫秒消熱抖動(dòng)
修改為   if (read == 0) delayms(5);    //延時(shí) 5毫秒消熱抖動(dòng)
作者: zhangdong533    時(shí)間: 2025-4-2 01:10
程序功能:檢測(cè)按鈕的按下彈起次數(shù),以識(shí)別"單擊.雙擊.長(zhǎng)按"。。學(xué)習(xí)了




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