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

QQ登錄

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

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

關(guān)于單片機(jī)按鍵控制燈長(zhǎng)按短按程序

[復(fù)制鏈接]
ID:237797 發(fā)表于 2021-9-2 11:09 | 顯示全部樓層 |閱讀模式
要實(shí)現(xiàn)的功能:?jiǎn)为?dú)按鍵,長(zhǎng)按按鍵2S開(kāi)關(guān)燈,開(kāi)燈默認(rèn)白色。開(kāi)燈后,短按按鍵對(duì)燈顏色顯示切換紅,黃,綠,青,蘭,紫,白循環(huán)切換。我現(xiàn)在的程序可以實(shí)現(xiàn)長(zhǎng)按按鍵開(kāi)關(guān)燈,開(kāi)燈后短按只能第一次短按鍵起作用,后面不起作用。有啥辦法實(shí)現(xiàn)我說(shuō)的功能?
#include<reg51.h>

sfr P5 = 0XC8;

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long

sbit LEDR = P3^1;
sbit LEDG = P5^5;
sbit LEDB = P3^0;
sbit LEDM = P3^2;
sbit KEY = P3^3;

u8 sysTim; //系統(tǒng)時(shí)基
u8 keyProcTim; //按鍵處理時(shí)間
u8 ledProcTim; //LED燈處理時(shí)間

u8 keyState; // 按鍵狀態(tài)
u8 keyDownCnt; //按鍵按下計(jì)數(shù)器

u8 keyShort; //短按鍵標(biāo)志
u8 keyLong;  //長(zhǎng)按鍵標(biāo)志
u8 ledState = 0; //led狀態(tài)
u8 ledon; //開(kāi)機(jī)標(biāo)志,開(kāi)機(jī)為1
u8 ledmode; //led工作模式

void key_Proc();
void led_Proc();

void main()
{
    LEDR = 0;
    LEDG = 0;
    LEDB = 0;
    ledState = 0;

    EA = 1;
    TMOD = 0X01;
    TH0 = 0XFC;
    TL0 = 0X66;
    ET0 = 1;
    TR0 = 1;

    while(1)
    {
        key_Proc();
        led_Proc();
    }   
}


void key_Proc()
{
    if(sysTim-keyProcTim >= 20)  //20ms掃描一次按鍵
    {
        keyProcTim = sysTim;

        switch(keyState)
        {
            case 0:  //檢測(cè)有按鍵按下
                if(!KEY)
                {
                    keyDownCnt = 0;
                    keyState = 1;
                }
                break;
            case 1: //消抖和短按鍵確認(rèn)
                if(!KEY)
                {
                    keyDownCnt++;
                    if(keyDownCnt >= 50)  //20ms掃描一次,
                    //掃描50次即:50*20=1000ms長(zhǎng)按鍵(500ms以上)
                    {
                        keyLong = 1;  //長(zhǎng)按鍵標(biāo)志,長(zhǎng)按鍵按下
                        keyState = 2; //按鍵狀態(tài)標(biāo)志為2
                    }
                }
                else
                {
                    if(keyDownCnt != 0) //短按鍵
                    {
                        keyShort = 1;   //短按鍵標(biāo)志,短按鍵按下
                        keyState = 0;   //按鍵狀態(tài)標(biāo)志為0
                    }
                }
                break;
            default:   //case 2:  //等待按鍵釋放
            if(KEY)
            {
                keyLong = 0;  //長(zhǎng)按鍵標(biāo)志,長(zhǎng)按鍵沒(méi)有按下
                keyState = 0; //按鍵狀態(tài)為0
            }
            break;
        }
    }
    if(1==keyShort)    //短按鍵處理
    {
        keyShort = 0;
            ledState = 1;   //led狀態(tài)1
    }
    if(1==keyLong) //長(zhǎng)按鍵處理
    {
        keyLong = 0;
        ledState = 2;  //led狀態(tài)2
    }
}


void led_Proc()
{
        if(1==ledon)    //開(kāi)燈
        {
            if(ledState==1)  //led狀態(tài)1,短按鍵
            {
                ledState = 0;
                LEDR = 0;
                LEDB = 0;
                LEDG = 1;        //綠燈亮               
             }  
        }

        if(2==ledState)      //led狀態(tài)2,長(zhǎng)按鍵
        {  
            ledState = 0;
             if(0==ledon)     //如果在關(guān)燈
             {
                ledon = 1;    //就打打開(kāi)燈
                LEDR = 1;   //開(kāi)燈白光
                LEDG = 1;
                LEDB = 1;
             }
             else            //如何在開(kāi)燈
             {
                ledon = 0;   //就關(guān)燈
                LEDR = 0;
                LEDG = 0;
                LEDB = 0;
             }                          
        }      
}


void interruptTimer0() interrupt 1
{
    TH0 = 0XFC;
    TL0 = 0X66;

    sysTim++;
}


回復(fù)

使用道具 舉報(bào)

ID:554500 發(fā)表于 2021-9-2 14:21 | 顯示全部樓層
sbit key=P3^2;   //按鍵
u8 val=0;           //紅,黃,綠,青,蘭,紫,白


void key_scan()
{
   static u8 i=0,c=0;
       
   if(key==0)
         {
                 if(i==0)
                 {
                         if(key==0&&c++>200) //長(zhǎng)按,適當(dāng)調(diào)整時(shí)間
                         {
                                 i=1;
                                 
                                 //開(kāi)關(guān)機(jī)
                         }
                 }
         }
         else
         {
                 if(c>100&&c<200) //短按,適當(dāng)調(diào)整時(shí)間
                 {
                         val++;
                         if(val>6)
                                 val=0;
                         
                         switch(val)
                         {
                                 case 0 : break; //白
                                 case 1 : break;
                                 case 2 : break;
                                 case 3 : break;
                                 case 4 : break;
                                 case 5 : break;
                                 case 6 : break;
                         }
                         
                 }
                 i=0;
                 c=0;
         }
}


//大概思路就是這樣子,自己思考吧
回復(fù)

使用道具 舉報(bào)

ID:237797 發(fā)表于 2021-9-2 16:03 | 顯示全部樓層
18701931930 發(fā)表于 2021-9-2 14:21
sbit key=P3^2;   //按鍵
u8 val=0;           //紅,黃,綠,青,蘭,紫,白

謝謝你的回復(fù),我按照你的思路改了一下 我的程序,還是不行,短按鍵按下沒(méi)有反應(yīng)了,和我以前想的方法相近,不知道是不是我理解錯(cuò)了,下面是我修改后的程序:
#include<reg51.h>

sfr P5 = 0XC8;

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long

sbit LEDR = P3^1;
sbit LEDG = P5^5;
sbit LEDB = P3^0;
sbit LEDM = P3^2;
sbit KEY = P3^3;

u8 sysTim; //系統(tǒng)時(shí)基
u8 keyProcTim; //按鍵處理時(shí)間
u8 ledProcTim; //LED燈處理時(shí)間

u8 keyState; // 按鍵狀態(tài)
u8 keyDownCnt; //按鍵按下計(jì)數(shù)器

u8 keyShort; //短按鍵標(biāo)志
u8 keyLong;  //長(zhǎng)按鍵標(biāo)志
u8 ledState = 0; //led狀態(tài)
u8 ledon; //開(kāi)機(jī)標(biāo)志,開(kāi)機(jī)為1
u8 ledmode; //led工作模式
u8 val=0;           //紅,黃,綠,青,蘭,紫,白


//u8 code LED_TEB[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//u8 LOOP_TEMP=0;

void key_Proc();
void led_Proc();

void main()
{
    LEDR = 0;
    LEDG = 0;
    LEDB = 0;
    ledState = 0;

    EA = 1;
    TMOD = 0X01;
    TH0 = 0XFC;
    TL0 = 0X66;
    ET0 = 1;
    TR0 = 1;

    while(1)
    {
        key_Proc();
        led_Proc();
    }   
}


void key_Proc()
{   
    if(sysTim-keyProcTim >= 20)  //20ms掃描一次按鍵
    {
        keyProcTim = sysTim;

        switch(keyState)
        {
            case 0:  //檢測(cè)有按鍵按下
                if(!KEY)
                {
                    keyDownCnt = 0;
                    keyState = 1;
                }
                break;
            case 1: //消抖和短按鍵確認(rèn)
                if(!KEY)
                {
                    keyDownCnt++;
                    if(keyDownCnt >= 50)  //20ms掃描一次,
                    //掃描50次即:50*20=1000ms長(zhǎng)按鍵(500ms以上)
                    {
                        keyLong = 1;  //長(zhǎng)按鍵標(biāo)志,長(zhǎng)按鍵按下
                        keyState = 2; //按鍵狀態(tài)標(biāo)志為2
                    }
                }
                else
                {
                    if(keyDownCnt != 0) //短按鍵
                    {
                        keyShort = 1;   //短按鍵標(biāo)志,短按鍵按下
                        keyState = 0;   //按鍵狀態(tài)標(biāo)志為0
                    }
                }
                break;
            default:   //case 2:  //等待按鍵釋放
            if(KEY)
            {
                keyLong = 0;  //長(zhǎng)按鍵標(biāo)志,長(zhǎng)按鍵沒(méi)有按下
                keyState = 0; //按鍵狀態(tài)為0
            }
            break;
        }
    }
    if(1==keyShort)    //短按鍵處理
    {
        keyShort = 0;
            ledState = 1;   //led狀態(tài)1
            
    }
    if(1==keyLong) //長(zhǎng)按鍵處理
    {
        keyLong = 0;
        ledState = 10;  //led狀態(tài)2
    }
}


void led_Proc()
{
        if(1==ledon)    //開(kāi)燈
        {
            if(ledState==1)  //led狀態(tài)1,短按鍵
            {
//                ledState = 0;
//                LEDR = 0;
//                LEDB = 0;
//                LEDG = 1;
             val++;
             if(val>6)
                     val=0;
            
             switch(val)
             {
                     case 0 :LEDR = 1;LEDG = 1;LEDB = 1;break; //白
                     case 1 :LEDR = 1;LEDG = 0;LEDB = 0;break;
                     case 2 :LEDR = 1;LEDG = 1;LEDB = 0;break;
                     case 3 :LEDR = 0;LEDG = 1;LEDB = 0;break;
                     case 4 :LEDR = 0;LEDG = 1;LEDB = 1;break;
                     case 5 :LEDR = 0;LEDG = 0;LEDB = 1;break;
                     case 6 :LEDR = 1;LEDG = 0;LEDB = 1;break;
             }                       
             }  
        }
      
        if(10==ledState)      //led狀態(tài)2,長(zhǎng)按鍵
        {  
            ledState = 0;
             if(0==ledon)     //如果在關(guān)燈
             {
                ledon = 1;    //就打打開(kāi)燈
                LEDR = 1;
                LEDG = 1;
                LEDB = 1;
             }
             else            //如何在開(kāi)燈
             {
                ledon = 0;   //就關(guān)燈
                LEDR = 0;
                LEDG = 0;
                LEDB = 0;
             }                          
        }      
}


void interruptTimer0() interrupt 1
{
    TH0 = 0XFC;
    TL0 = 0X66;
   
    sysTim++;
}
回復(fù)

使用道具 舉報(bào)

ID:237797 發(fā)表于 2021-9-2 17:37 | 顯示全部樓層
18701931930 發(fā)表于 2021-9-2 14:21
sbit key=P3^2;   //按鍵
u8 val=0;           //紅,黃,綠,青,蘭,紫,白

謝謝你的回復(fù),現(xiàn)在可以了,我把ledState = 0;這句注解了,所以不行,F(xiàn)在修改好的程序如下:
#include<reg51.h>

sfr P5 = 0XC8;

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long

sbit LEDR = P3^1;
sbit LEDG = P5^5;
sbit LEDB = P3^0;
sbit LEDM = P3^2;
sbit KEY = P3^3;

u8 sysTim; //系統(tǒng)時(shí)基
u8 keyProcTim; //按鍵處理時(shí)間
u8 ledProcTim; //LED燈處理時(shí)間

u8 keyState; // 按鍵狀態(tài)
u8 keyDownCnt; //按鍵按下計(jì)數(shù)器

u8 keyShort; //短按鍵標(biāo)志
u8 keyLong;  //長(zhǎng)按鍵標(biāo)志
u8 ledState = 0; //led狀態(tài)
u8 ledon; //開(kāi)機(jī)標(biāo)志,開(kāi)機(jī)為1
u8 ledmode; //led工作模式,紅,黃,綠,青,蘭,紫,白

void key_Proc();
void led_Proc();

void main()
{
    LEDR = 0;
    LEDG = 0;
    LEDB = 0;
    ledState = 0;

    EA = 1;
    TMOD = 0X01;
    TH0 = 0XFC;
    TL0 = 0X66;
    ET0 = 1;
    TR0 = 1;

    while(1)
    {
        key_Proc();
        led_Proc();
    }   
}


void key_Proc()
{   
    if(sysTim-keyProcTim >= 20)  //20ms掃描一次按鍵
    {
        keyProcTim = sysTim;

        switch(keyState)
        {
            case 0:  //檢測(cè)有按鍵按下
                if(!KEY)
                {
                    keyDownCnt = 0;
                    keyState = 1;
                }
                break;
            case 1: //消抖和短按鍵確認(rèn)
                if(!KEY)
                {
                    keyDownCnt++;
                    if(keyDownCnt >= 50)  //20ms掃描一次,
                    //掃描50次即:50*20=1000ms長(zhǎng)按鍵(500ms以上)
                    {
                        keyLong = 1;  //長(zhǎng)按鍵標(biāo)志,長(zhǎng)按鍵按下
                        keyState = 2; //按鍵狀態(tài)標(biāo)志為2
                    }
                }
                else
                {
                    if(keyDownCnt != 0) //短按鍵
                    {
                        keyShort = 1;   //短按鍵標(biāo)志,短按鍵按下
                        keyState = 0;   //按鍵狀態(tài)標(biāo)志為0
                    }
                }
                break;
            default:   //case 2:  //等待按鍵釋放
            if(KEY)
            {
                keyLong = 0;  //長(zhǎng)按鍵標(biāo)志,長(zhǎng)按鍵沒(méi)有按下
                keyState = 0; //按鍵狀態(tài)為0
            }
            break;
        }
    }
    if(1==keyShort)    //短按鍵處理
    {
        keyShort = 0;
            ledState = 1;   //led狀態(tài)1
            
    }
    if(1==keyLong) //長(zhǎng)按鍵處理
    {
        keyLong = 0;
        ledState = 2;  //led狀態(tài)2
    }
}


void led_Proc()
{
        if(1==ledon)    //開(kāi)燈
        {
            if(ledState==1)  //led狀態(tài)1,短按鍵
            {
                ledState = 0;
                ledmode++;    //LED亮模式
                if(ledmode>6)  // 最大模式數(shù)
                ledmode=0;     //到最大模式數(shù)后歸零,即循環(huán)      
                switch(ledmode)
                {
                     case 0 :LEDR = 1;LEDG = 1;LEDB = 1;break; //白
                     case 1 :LEDR = 1;LEDG = 0;LEDB = 0;break;//紅
                     case 2 :LEDR = 1;LEDG = 1;LEDB = 0;break;//黃
                     case 3 :LEDR = 0;LEDG = 1;LEDB = 0;break;//綠
                     case 4 :LEDR = 0;LEDG = 1;LEDB = 1;break;//青
                     case 5 :LEDR = 0;LEDG = 0;LEDB = 1;break;//藍(lán)
                     case 6 :LEDR = 1;LEDG = 0;LEDB = 1;break;//紫
                     default:break;
                }                     
             }      
        }
        
      
        if(2==ledState)      //led狀態(tài)2,長(zhǎng)按鍵
        {  
            ledState = 0;
             if(0==ledon)     //如果在關(guān)燈
             {
                ledon = 1;    //就打打開(kāi)燈
                LEDR = 1;
                LEDG = 1;
                LEDB = 1;
             }
             else            //如何在開(kāi)燈
             {  
                ledon = 0;   //就關(guān)燈
                LEDR = 0;
                LEDG = 0;
                LEDB = 0;
                ledmode=0;   //關(guān)燈后亮燈模式歸零,即開(kāi)始依次循環(huán),
                //無(wú)詞句關(guān)燈模式不歸零,即下次開(kāi)機(jī)第一次白色,后面按照關(guān)機(jī)前顏色循環(huán)。
             }                          
        }      
}


void interruptTimer0() interrupt 1
{
    TH0 = 0XFC;
    TL0 = 0X66;
   
    sysTim++;
}
回復(fù)

使用道具 舉報(bào)

ID:609524 發(fā)表于 2021-9-4 14:55 | 顯示全部樓層
本帖最后由 楊天想 于 2021-9-4 15:05 編輯

void key_proc(void)   //5ms掃描一次
{                     //長(zhǎng)按時(shí)間大于一秒啟動(dòng)長(zhǎng)按功能
        if(!KEY)
        {
                key_con1=0;
                if(++key_con>=200)   // 長(zhǎng)按
                {
                        key_con=200
                       
                }       
        }
        else
        {
                if(++key_con1>=6)
                {
                        if(key_con>=6&&key_con<200)  //短按
                        {
                               
                        }
                }
                key_con1=6;
                key_con=0;
        }
}
回復(fù)

使用道具 舉報(bào)

ID:66287 發(fā)表于 2021-9-8 15:26 | 顯示全部樓層
把樓主最初的帖子修改了一下,感覺(jué)思路清晰一些,運(yùn)行相當(dāng)流暢,現(xiàn)分享出來(lái)。
#include <reg51.h>
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long

sbit LEDR = P0^0;
sbit LEDG = P0^1;
sbit LEDB = P0^2;

enum {ON, OFF};

sbit KEY = P1^4;

u8 sysTim; //系統(tǒng)時(shí)基
u8 keyProcTim; //按鍵處理時(shí)間

u8 keyState; // 按鍵狀態(tài)
u8 keyDownCnt; //按鍵按下計(jì)數(shù)器

u8 keyShort; //短按鍵標(biāo)志
u8 keyLong;  //長(zhǎng)按鍵標(biāo)志
u8 ledState = 0; //led狀態(tài)
u8 ledon; //開(kāi)機(jī)標(biāo)志,開(kāi)機(jī)為1

void Timer0Init();
void key_Proc();
void led_Proc();

void main()
{
  LEDR = 1;
  LEDG = 1;
  LEDB = 1;
  ledState = 0;

  Timer0Init();

  while(1)
   {
    key_Proc();
    led_Proc();
   }   
}

void key_Proc()
{       
  if(sysTim-keyProcTim >= 20)  //20ms掃描一次按鍵
   {
    keyProcTim = sysTim;
    switch(keyState)
     {
      case 0:  //檢測(cè)到按鍵按下
             if(!KEY)
              {
               keyDownCnt = 0;
               keyState = 1;
              }
             break;
      case 1: //消抖和短按鍵確認(rèn)
             if(!KEY)         //仍然按下
              {
               keyDownCnt++;
               if(keyDownCnt >= 50)  //20ms掃描一次,
                    //掃描50次即:50*20=1000ms長(zhǎng)按鍵(500ms以上)
                {
                 keyLong = 1;  //長(zhǎng)按鍵標(biāo)志置 1
                 keyState = 2; //按鍵狀態(tài)標(biāo)志為2                                               
                }
              }
             else
              {
               if(keyDownCnt != 0) //短按鍵
                {       
                                 keyDownCnt = 0;
                 keyShort = 1;   //短按鍵標(biāo)志,短按鍵按下
                 keyState = 0;   //按鍵狀態(tài)標(biāo)志為0
                }
              }
             break;
          case 2:
             if(KEY)
              {
               keyLong = 0;  //長(zhǎng)按鍵標(biāo)志置 0
               keyState = 0; //按鍵狀態(tài)為0
              }
             break;
     }
   }
  if(1==keyShort)    //短按鍵處理
   {
   
    keyShort = 0;
    ledState = 1;   //led狀態(tài)1
   }
  if(1==keyLong) //長(zhǎng)按鍵處理
   {   
    keyLong = 0;
    ledState = 2;  //led狀態(tài)2
   }
}

void led_Proc()
{
  static u8 i;
  if((ledon==0)&&(2==ledState))      //關(guān)燈狀態(tài)下,led狀態(tài)2,長(zhǎng)按鍵,就打開(kāi)燈
   {  
    ledState = 0;
    ledon = 1;   
    LEDR = ON;   //開(kāi)燈白光
    LEDG = ON;
    LEDB = ON;
   }
  if((ledon==1)&&(2==ledState))              //開(kāi)燈狀態(tài)下,led狀態(tài)2,長(zhǎng)按,就關(guān)燈
   {       
    ledState = 0;
    ledon = 0;   //就關(guān)燈
    LEDR = OFF;
    LEDG = OFF;
    LEDB = OFF;
   }                          
  if((ledon==1)&&(ledState==1))//開(kāi)燈狀態(tài)下,led狀態(tài)1,短按鍵
   {
    switch(i)
        {
     case 0:         
                        LEDR = 0;
                        LEDG = 1;
                        LEDB = 1;                                  
                        break;       
     case 1:                                  
                        LEDR = 1;                                  
                        LEDG = 0;
                        LEDB = 1;
                        break;
     case 2:                                  
                        LEDR = 1;
                        LEDG = 1;
                        LEDB = 0;                                  
                        break;      
         case 3:
            LEDR = 0;
                        LEDG = 0;
                        LEDB = 0;
                        break;
    }                       
        i++;   
        i=i%4;         
    ledState = 0;   
   }      
               
}

void Timer0Init()                //1毫秒@11.0592MHz
{
        /***
        AUXR &= 0x7F;                //定時(shí)器時(shí)鐘12T模式
        TMOD &= 0xF0;                //設(shè)置定時(shí)器模式
        TMOD |= 0x01;                //設(shè)置定時(shí)器模式
        TL0 = 0x66;                //設(shè)置定時(shí)初值
        TH0 = 0xFC;                //設(shè)置定時(shí)初值
        TF0 = 0;                //清除TF0標(biāo)志
        TR0 = 1;                //定時(shí)器0開(kāi)始計(jì)時(shí)
        EA = 1;
        ***/
  EA = 1;
  TMOD = 0x01;
  TH0 = 0xFC;
  TL0 = 0x66;
  ET0 = 1;
  TR0 = 1;
}

void interruptTimer0() interrupt 1
{
    TH0 = 0xFC;
    TL0 = 0x66;

    sysTim++;
}
回復(fù)

使用道具 舉報(bào)

ID:237797 發(fā)表于 2021-9-10 14:59 | 顯示全部樓層
bhjyqjs 發(fā)表于 2021-9-8 15:26
把樓主最初的帖子修改了一下,感覺(jué)思路清晰一些,運(yùn)行相當(dāng)流暢,現(xiàn)分享出來(lái)。
#include
#define u8 unsi ...

謝謝你的回復(fù)。驗(yàn)證了一下你的程序,用枚舉會(huì)變成了開(kāi)機(jī)后短按鍵不起作用,在關(guān)燈后短按鍵才起作用。第一次上電要先開(kāi)機(jī)再關(guān)機(jī),后面關(guān)機(jī)狀態(tài)是短按鍵才有效。
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2021-9-11 16:42 | 顯示全部樓層
lclbf 發(fā)表于 2021-9-10 14:59
謝謝你的回復(fù)。驗(yàn)證了一下你的程序,用枚舉會(huì)變成了開(kāi)機(jī)后短按鍵不起作用,在關(guān)燈后短按鍵才起作用。第一 ...

看你那么久都沒(méi)有搞定, 給你個(gè)思路吧,按你現(xiàn)在的狀態(tài),最簡(jiǎn)單的改法是,按鍵按下以后,觸發(fā)外部中斷,外部中斷響應(yīng)后打開(kāi)定時(shí)器,開(kāi)始計(jì)時(shí),你設(shè)置一個(gè)臨界點(diǎn),到了這個(gè)臨界點(diǎn),定時(shí)器中斷判斷一下按鍵狀態(tài),如果已經(jīng)釋放,說(shuō)明是短按,標(biāo)記短按,如果沒(méi)有釋放則標(biāo)志長(zhǎng)按(也可以沒(méi)到臨界點(diǎn)前多次判斷,比如100MS判斷1次,15次以后,1.5秒為臨界點(diǎn),只要沒(méi)到臨界點(diǎn)釋放就是短按,超過(guò)臨界點(diǎn)還沒(méi)有釋放就是長(zhǎng)按),然后關(guān)閉定時(shí)器,等下次外部中斷被觸發(fā)再次由外部中斷開(kāi)啟。主程序里就反復(fù)判斷長(zhǎng)按短按標(biāo)記又沒(méi)有置位就好了。
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2021-9-11 20:39 | 顯示全部樓層
給你擬定一個(gè)程序構(gòu)架,添加具體任務(wù)內(nèi)容即可。
  1. #include<reg51.h>
  2. sfr P5 = 0XC8;
  3. #define key_S 10                                        //宏定義短按(約10ms)
  4. #define key_L key_S*200                        //宏定義長(zhǎng)按(約200ms)
  5. #define u8 unsigned char
  6. #define u16 unsigned int
  7. #define u32 unsigned long

  8. sbit LEDR = P3^1;
  9. sbit LEDG = P5^5;
  10. sbit LEDB = P3^0;
  11. sbit LEDM = P3^2;
  12. sbit KEY  = P3^3;

  13. //u8 sysTim; //系統(tǒng)時(shí)基
  14. //u8 keyProcTim; //按鍵處理時(shí)間
  15. //u8 ledProcTim; //LED燈處理時(shí)間
  16. //u8 keyState; // 按鍵狀態(tài)
  17. //u8 keyDownCnt; //按鍵按下計(jì)數(shù)器
  18. //u8 keyShort; //短按鍵標(biāo)志
  19. bit keyLong;  //長(zhǎng)按鍵標(biāo)志
  20. u8 ledState = 0; //led狀態(tài)
  21. //u8 ledon; //開(kāi)機(jī)標(biāo)志,開(kāi)機(jī)為1
  22. //u8 ledmode; //led工作模式

  23. void key_Proc();
  24. void led_Proc();

  25. void Timer0Init()                //1毫秒@11.0592MHz
  26. {
  27.         TMOD &= 0xF0;                //設(shè)置定時(shí)器模式
  28.         TMOD |= 0x01;                //設(shè)置定時(shí)器模式
  29.         TL0 = 0x66;                //設(shè)置定時(shí)初值
  30.         TH0 = 0xFC;                //設(shè)置定時(shí)初值
  31.         TF0 = 0;                //清除TF0標(biāo)志
  32.         TR0 = 1;                //定時(shí)器0開(kāi)始計(jì)時(shí)
  33. }

  34. void main()
  35. {
  36.         LEDR = 0;
  37.         LEDG = 0;
  38.         LEDB = 0;
  39.         ledState = 0;
  40.         Timer0Init();
  41.         while(1)
  42.         {
  43.                 if(TF0)
  44.                 {
  45.                         TF0=0;
  46.                         TL0=0x66;                //設(shè)置定時(shí)初值
  47.                         TH0=0xFC;                //設(shè)置定時(shí)初值
  48.                         key_Proc();
  49.                         led_Proc();
  50.                 }
  51.         }   
  52. }

  53. void key_Proc()
  54. {
  55.         static u16 count=0;                        //計(jì)數(shù)變量
  56.         if(!KEY)   
  57.         {  
  58.                 count++;  
  59.                 if(count==key_L)                        //長(zhǎng)按
  60.                 {
  61.                         keyLong=~keyLong;                //長(zhǎng)按標(biāo)志取反
  62.                         //長(zhǎng)按任務(wù)
  63.                 }
  64.                 if(count>key_L)                                //防止count溢出
  65.                         count=key_L+1;          
  66.         }  
  67.         else                                                        //按鍵抬起
  68.         {  
  69.                 if(count>key_S && count<key_L && keyLong==1)//keyLong=1短按才有效
  70.                 {
  71.                         //短按任務(wù)
  72.                 }
  73.                 count=0;                                        //count清0
  74.         }  
  75. }

  76. void led_Proc()
  77. {
  78.         //服務(wù)內(nèi)容

  79. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:66287 發(fā)表于 2021-9-13 09:12 | 顯示全部樓層
樓主,你驗(yàn)證不行,是因?yàn)槲覀z的LED點(diǎn)亮邏輯不一樣,我的是"0"點(diǎn)亮,所以出現(xiàn)你說(shuō)的情況出現(xiàn)。
無(wú)標(biāo)題.png
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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