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

QQ登錄

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

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

判斷按鈕單、雙、三擊,開(kāi)關(guān)相應(yīng)的led,編譯通過(guò),邏輯卻沒(méi)反應(yīng),誠(chéng)心請(qǐng)教指點(diǎn),謝謝

[復(fù)制鏈接]
ID:52701 發(fā)表于 2013-9-4 09:08 | 顯示全部樓層 |閱讀模式
#include<reg51.h>     //使用的是stc12c4052ad
sbit led1  = P1^7;     // LED1接P1.7腳
sbit led2  = P1^6;     // LED2接P1.6腳
sbit led3  = P1^5;     // LED3接P1.5腳
sbit led4  = P1^4;     // LED4接P1.4腳
sbit button = P1^0;     // 按鈕接P1.0腳
void s(unsigned int a) 、// 延時(shí)函數(shù)
{
unsigned char i,j;
for(i=0;i<a;i++)
  for(j=0;j<600;j++);
}
void main(void)
{
unsigned  char key=0;        //按鈕狀態(tài)判斷變量
led1=led2=led3=led4=1;          //led初始均為關(guān)閉
button=1;          //按鈕初始化為按下
while(1){
    if(button==0){      
     key+=1;        //單擊key值為1
      s(20);
   if(button==0){
      key+=1;       //雙擊key值為2
       s(20);
    if(button==0){
       key+=1;         //三擊key值為3
        s(20);
     if(button==0){
        key+=1;     //四擊key值為4
         s(20);
      if(button==0){
       key+=1;    //長(zhǎng)按key值為5
       s(100);
        while(button==0);
      }
     }
    }
  
   }
  }
  switch(key){         //根據(jù)key值開(kāi)關(guān)相應(yīng)引腳的led燈
   case 1:
    led1=~led1;
    break;
   case 2:
    led2=~led2;
    break;
   case 3:
    led3=~led3;
    break;
   case 4:
    led4=~led4;
    break;
   default:
    break;
  }

}
}

回復(fù)

使用道具 舉報(bào)

ID:1 發(fā)表于 2013-9-4 12:25 | 顯示全部樓層
你應(yīng)該要做一下消抖處理
回復(fù)

使用道具 舉報(bào)

ID:153199 發(fā)表于 2017-1-8 16:09 | 顯示全部樓層
消抖處理一下
回復(fù)

使用道具 舉報(bào)

ID:140489 發(fā)表于 2017-1-11 11:15 | 顯示全部樓層
這樣寫(xiě)可以做到按一次亮一個(gè)燈,按第5次,燈全滅
#include<reg52.h>   
sbit led1  = P1^7;     // LED1接P1.7腳
sbit led2  = P1^6;     // LED2接P1.6腳
sbit led3  = P1^5;     // LED3接P1.5腳
sbit led4  = P1^4;     // LED4接P1.4腳
sbit button = P1^0;     // 按鈕接P1.0腳
void delay(unsigned char ms)// 延時(shí)函數(shù)
{
unsigned char i,j;
for(i=ms;i>0;i--)
  for(j=110;j>0;j--);
}  


void main(void)
{
unsigned  char key=0;        //按鈕狀態(tài)判斷變量

//led1=led2=led3=led4=1;          //led初始均為關(guān)閉

button=1;          //按鈕初始化為按下
while(1){
   
        if(button==0)
        {
          delay(30);
          
          if(button==0)
          {   
        key++;
          while(button==0);
          }
  }
  switch(key){         //根據(jù)key值開(kāi)關(guān)相應(yīng)引腳的led燈
   case 1:
    led1=0;
    break;
   case 2:
    led2=0;
    break;
   case 3:
    led3=0;
    break;
   case 4:
    led4=0;
    break;
        case 5:
    led1=led2=led3=led4=1;
    break;
   default:
    break;
  }

}
}
回復(fù)

使用道具 舉報(bào)

ID:140489 發(fā)表于 2017-1-11 11:24 | 顯示全部樓層
//按1次亮1個(gè)燈,按4次4個(gè)燈全亮,按第5次,燈全滅,如此循環(huán);仿真通過(guò)

#include<reg52.h>   
sbit led1  = P1^7;     // LED1接P1.7腳
sbit led2  = P1^6;     // LED2接P1.6腳
sbit led3  = P1^5;     // LED3接P1.5腳
sbit led4  = P1^4;     // LED4接P1.4腳
sbit button = P1^0;     // 按鈕接P1.0腳
void delay(unsigned char ms)// 延時(shí)函數(shù)
{
unsigned char i,j;
for(i=ms;i>0;i--)
  for(j=110;j>0;j--);
}  


void main(void)
{
unsigned  char key=0;        //按鈕狀態(tài)判斷變量

//led1=led2=led3=led4=1;          //led初始均為關(guān)閉

button=1;          //按鈕初始化為按下
while(1){
   
        if(button==0)
        {
          delay(30);
          
          if(button==0)
          {   
        key++;
          while(button==0);
          if(key==6)
          {key=0;}
          }
  }
  switch(key){         //根據(jù)key值開(kāi)關(guān)相應(yīng)引腳的led燈
   case 1:
    led1=0;
    break;
   case 2:
    led2=0;
    break;
   case 3:
    led3=0;
    break;
   case 4:
    led4=0;
    break;
        case 5:
    led1=led2=led3=led4=1;
    break;
   default:
    break;
  }

}
}
回復(fù)

使用道具 舉報(bào)

ID:140489 發(fā)表于 2017-1-11 14:03 | 顯示全部樓層
//按1次亮1個(gè)燈,按4次4個(gè)燈全亮,按第5次,燈全滅,如此循環(huán)

#include<reg52.h>   
sbit led1  = P1^7;     // LED1接P1.7腳
sbit led2  = P1^6;     // LED2接P1.6腳
sbit led3  = P1^5;     // LED3接P1.5腳
sbit led4  = P1^4;     // LED4接P1.4腳
sbit button = P1^0;     // 按鈕接P1.0腳
void delay(unsigned char ms)// 延時(shí)函數(shù)
{
unsigned char i,j;
for(i=ms;i>0;i--)
  for(j=110;j>0;j--);
}  


void main(void)
{
unsigned  char key=0;        //按鈕狀態(tài)判斷變量

//led1=led2=led3=led4=1;          //led初始均為關(guān)閉

button=1;          //按鈕初始化為按下
while(1){
   
        if(button==0)
        {
          delay(30);
          
          if(button==0)
          {   
        key+=1;
          while(button==0);
          if(key==6)
          key=0;
          }
  }
  switch(key){         //根據(jù)key值開(kāi)關(guān)相應(yīng)引腳的led燈
   case 1:
    led1=0;
    break;
   case 2:
    led2=0;
    break;
   case 3:
    led3=0;
    break;
   case 4:
    led4=0;
    break;
        case 5:
    led1=led2=led3=led4=1;
    break;
   default:
    break;
  }

}
}
回復(fù)

使用道具 舉報(bào)

ID:129918 發(fā)表于 2017-1-11 20:57 | 顯示全部樓層
頂ing一個(gè)
回復(fù)

使用道具 舉報(bào)

ID:161477 發(fā)表于 2017-1-12 15:54 | 顯示全部樓層
單擊,雙擊,長(zhǎng)按
/***********************************************************************************************************

程序的功能:一個(gè)按鍵的單擊,雙擊,長(zhǎng)按。三種按鍵方式,然后做不同的處理。這里就以P1口LED燈變化作為測(cè)試。

單擊:點(diǎn)亮P1口上第一個(gè)LED燈。(低電平點(diǎn)亮)

雙擊:點(diǎn)亮P1口上第二個(gè)LED燈。(低電平點(diǎn)亮)

長(zhǎng)按:長(zhǎng)按:點(diǎn)亮P1口上的8個(gè)LED燈。(低電平點(diǎn)亮)

使用方法:

硬件的連接:P2.0作為按鍵的輸入,P1口作為L(zhǎng)ED顯示,連接好后,直接復(fù)制粘貼生成HEX文件,燒寫(xiě)進(jìn)C51就能用。

************************************************************************************************************/

#include<reg51.h>

#define N_key 0 //無(wú)鍵

#define S_key 1 //單鍵

#define D_key 2 //雙鍵

#define L_key 3 //長(zhǎng)鍵

#define key_state_0 0

#define key_state_1 1

#define key_state_2 2

#define key_state_3 3

sbit key_input = P2^0; // 按鍵輸入口

unsigned char time_10ms_ok = 0;

unsigned char key = 0;

unsigned char key_driver(void)

{

static unsigned char key_state = key_state_0, key_time = 0;

unsigned char key_return = N_key;

bit key_press;

key_press = key_input; // 讀按鍵I/O電平

switch (key_state)

{

case key_state_0: // 按鍵初始態(tài)

if (!key_press) key_state = key_state_1; // 鍵被按下,狀態(tài)轉(zhuǎn)換到按鍵消抖和確認(rèn)狀態(tài)

break;

case key_state_1: // 按鍵消抖與確認(rèn)態(tài)

if (!key_press)

{

key_time = 0; //

key_state = key_state_2; // 按鍵仍然處于按下,消抖完成,狀態(tài)轉(zhuǎn)換到按下鍵時(shí)間的計(jì)時(shí)狀態(tài),但返回的還是無(wú)鍵事件

}

else

key_state = key_state_0; // 按鍵已抬起,轉(zhuǎn)換到按鍵初始態(tài)。此處完成和實(shí)現(xiàn)軟件消抖,其實(shí)按鍵的按下和釋放都在此消抖的。

break;

case key_state_2:

if(key_press)

{

key_return = S_key; // 此時(shí)按鍵釋放,說(shuō)明是產(chǎn)生一次短操作,回送S_key

key_state = key_state_0; // 轉(zhuǎn)換到按鍵初始態(tài)

}

else if (++key_time >= 100) // 繼續(xù)按下,計(jì)時(shí)加10ms(10ms為本函數(shù)循環(huán)執(zhí)行間隔)

{

key_return = L_key; // 按下時(shí)間>1000ms,此按鍵為長(zhǎng)按操作,返回長(zhǎng)鍵事件

key_state = key_state_3; // 轉(zhuǎn)換到等待按鍵釋放狀態(tài)

}

break;

case key_state_3: // 等待按鍵釋放狀態(tài),此狀態(tài)只返回?zé)o按鍵事件

if (key_press) key_state = key_state_0; //按鍵已釋放,轉(zhuǎn)換到按鍵初始態(tài)

break;

}

return key_return;

}

/*=============

中間層按鍵處理函數(shù),調(diào)用低層函數(shù)一次,處理雙擊事件的判斷,返回上層正確的無(wú)鍵、單鍵、雙鍵、長(zhǎng)鍵4個(gè)按鍵事件。

本函數(shù)由上層循環(huán)調(diào)用,間隔10ms

===============*/

unsigned char key_read(void)

{

static unsigned char key_m = key_state_0, key_time_1 = 0;

unsigned char key_return = N_key,key_temp;

key_temp = key_driver();

switch(key_m)

{

case key_state_0:

if (key_temp == S_key )

{

key_time_1 = 0; // 第1次單擊,不返回,到下個(gè)狀態(tài)判斷后面是否出現(xiàn)雙擊

key_m = key_state_1;

}

else

key_return = key_temp; // 對(duì)于無(wú)鍵、長(zhǎng)鍵,返回原事件

break;

case key_state_1:

if (key_temp == S_key) // 又一次單擊(間隔肯定<500ms)

{

key_return = D_key; // 返回雙擊鍵事件,回初始狀態(tài)

key_m = key_state_0;

}

else

{ // 這里500ms內(nèi)肯定讀到的都是無(wú)鍵事件,因?yàn)殚L(zhǎng)鍵>1000ms,在1s前低層返回的都是無(wú)鍵

if(++key_time_1 >= 50)

{

key_return = S_key; // 500ms內(nèi)沒(méi)有再次出現(xiàn)單鍵事件,返回上一次的單鍵事件

key_m = key_state_0; // 返回初始狀態(tài)

}

}

break;

}

return key_return;

}

void main()

{

P1 = 0xff;        //IO口初始化

P2 = 0xff;

//定時(shí)器的初始化

TMOD = 0x01;        //選擇定時(shí)器的工作模式:定時(shí)器0,方式1

TH0 = (65535 - 10000)/256; //定時(shí)器的初值

TL0 = (65535 - 10000)%256;

EA = 1;        //開(kāi)打總中斷使能

ET0 = 1;        //打開(kāi)定時(shí)器0 的使能

TR0 = 1;        //打開(kāi)定時(shí)器0 ,開(kāi)始工作

while(1)

{

if(time_10ms_ok) //time_10ms_ok = 1,表示計(jì)時(shí)到了10MS。(10MS掃描一次按鍵)

{

time_10ms_ok = 0; //清除計(jì)時(shí)10MS標(biāo)志

key = key_read(); //調(diào)用掃描按鍵程序,返回一個(gè)鍵值

if (key == L_key) //長(zhǎng)按:點(diǎn)亮P1口上的8個(gè)LED燈。(低電平點(diǎn)亮)

{

P1 = 0x00;

}

else if(key == D_key)//雙擊:點(diǎn)亮P1口上第二個(gè)LED燈。(低電平點(diǎn)亮)

{

P1 = 0xfd;

}

else if(key == S_key)//單擊:點(diǎn)亮P1口上第一個(gè)LED燈。(低電平點(diǎn)亮)

{

P1 = 0xfe;

}

}

}

}
void timer0(void) interrupt 1        //用的是定時(shí)器0, 這個(gè)“interrupt 1”中的“1”代表1號(hào)中斷即是定時(shí)器0中斷。如果是“0”就是外部中斷0;“2“=外部中斷1;”3“定時(shí)器1中斷;”4“=串行口中斷
{

TH0 = (65535 - 10000)/256;

TL0 = (65535 - 10000)%256; //定時(shí)器0的方式1,得在中斷程序中重復(fù)初值。

time_10ms_ok = 1; //定時(shí)10MS 的標(biāo)志

}
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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