找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7157|回復(fù): 10
打印 上一主題 下一主題
收起左側(cè)

C51單片機的按鍵復(fù)用控制兩個燈

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:326587 發(fā)表于 2018-8-30 20:57 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
50黑幣
請大神幫幫忙,看下有的程序有什么問題
原想著用一個按鍵控制兩個燈,短按控制第一個燈,長按控制第二個燈,F(xiàn)在長按的話,第二個燈能控制,也能影響第一個燈。這下不會改了

代碼在2樓

最佳答案

查看完整內(nèi)容

使用計數(shù)法識別長短按,給你改了一下,你試試。 #include #define key_S 1000 //宏定義短按(約20ms) #define key_L key_S*50 //宏定義長按(約1s) //定義端口 sbit KEY=P1^4; sbit LED1 = P2^0; sbit LED2 = P2^1; unsigned int count=0;//計數(shù)變量 int main (void) { LED1=1; LED2=1; KEY=1; //按鍵輸入端口電平置高 while(1) //主循環(huán) { if(!KEY) //如果檢測到低電平,說 ...
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:213173 發(fā)表于 2018-8-30 20:57 | 只看該作者

使用計數(shù)法識別長短按,給你改了一下,你試試。
#include<reg52.h>
#define key_S 1000 //宏定義短按(約20ms)
#define key_L key_S*50 //宏定義長按(約1s)
//定義端口
sbit KEY=P1^4;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
unsigned int count=0;//計數(shù)變量

int main (void)
{
        LED1=1;
        LED2=1;               
        KEY=1; //按鍵輸入端口電平置高       
        while(1)         //主循環(huán)
        {
                if(!KEY)  //如果檢測到低電平,說明按鍵按下
                {  
                        count++;  
                        if(count==key_L)                                //長按
                                LED2=!LED2;
                        if(count>key_L)
                                count=key_L+1;                                //防止count溢出          
                }  
                else                                                                        //按鍵抬起
                {  
                        if(count>key_S && count<key_L)//短按
                                LED1=!LED1;
                        count=0;                                                        //count清0
                }   
        }
}

評分

參與人數(shù) 2黑幣 +50 收起 理由
A142989 + 30 很給力!
admin + 20 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

板凳
ID:326587 發(fā)表于 2018-8-30 20:59 | 只看該作者
  1. #include<reg52.h>

  2. //定義端口
  3. sbit KEY=P1^4;
  4. sbit LED1 = P2^0;
  5. sbit LED2 = P2^1;

  6. void DelayUs2x(unsigned char t);//函數(shù)聲明
  7. void DelayMs(unsigned char t);

  8. int main (void)
  9. {
  10. unsigned char num=0,key_press_num;
  11. LED1=1;
  12. LED2=1;               
  13. KEY=1; //按鍵輸入端口電平置高

  14. while(1)         //主循環(huán)
  15.   {
  16.   if(!KEY)  //如果檢測到低電平,說明按鍵按下
  17.     {
  18.          DelayMs(20); //延時去抖,一般10-20ms
  19.      if(!KEY)     //再次確認(rèn)按鍵是否按下,沒有按下則退出
  20.            {
  21.            while(!KEY)
  22.             {
  23.                 key_press_num++;
  24.         DelayMs(10);           //10x200=2000ms=2s
  25.                 if(key_press_num==200) //大約2s
  26.                         {
  27.                        //如果達到長按鍵標(biāo)準(zhǔn)
  28.                                //則進入長按鍵動作
  29.                //這里用于識別是否按
  30.                                                            //鍵還在按下,如果按
  31.                                              //下執(zhí)行相關(guān)動作,否則退出                       
  32.                                 while(!KEY)
  33.                                 {
  34.                                        LED2=!LED2;
  35.                                         DelayMs(200);
  36.                                        
  37.                                 }
  38.                         }                       
  39.                 }
  40.                 LED1=!LED1;                               
  41.             }
  42.                   
  43.         }       
  44.   }
  45. }

  46. //uS延時函數(shù)
  47. void DelayUs2x(unsigned char t)
  48. {   
  49. while(--t);
  50. }

  51. //mS延時函數(shù)
  52. void DelayMs(unsigned char t)
  53. {
  54.      
  55. while(t--)
  56. {
  57.      //大致延時1mS
  58.      DelayUs2x(245);
  59.          DelayUs2x(245);
  60. }
  61. }
復(fù)制代碼
回復(fù)

使用道具 舉報

地板
ID:384109 發(fā)表于 2018-8-30 23:11 | 只看該作者
不應(yīng)該用延時來判斷按鍵時間,應(yīng)該用定時器來記錄按鍵按下的時間,再來判斷是短按,還是長按

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

5#
ID:390267 發(fā)表于 2018-8-31 01:24 | 只看該作者
試試我寫的這個,看看行不行。我也是新手       

if(key_up==key_press)
        {
                Delay5ms(2);
                if(key_up==key_press)               
                {
                  hold_time=0;
                        while((key_up==key_press)&&(hold_time<20))
                        {
                                Delay5ms(10);
                                hold_time++;       
                        }
                        if((hold_time>1)&&(hold_time<=10))
                                        key_press_num=key_up_code;       
                        else if((hold_time>10)&&(hold_time<=20))
                                        key_press_num=key_down_code;       
                }
        }while(!key_up);

評分

參與人數(shù) 2黑幣 +70 收起 理由
A142989 + 30 贊一個!
admin + 40 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

6#
ID:98526 發(fā)表于 2018-8-31 08:53 | 只看該作者
1、定義一個局部變量
2、長按之后將該標(biāo)志位置為1
3、在松手之后判斷該標(biāo)志位是否為1
4、如果不為1,確認(rèn)是短按松開、執(zhí)行短按功能
5、如果為1,則是長按松開、不執(zhí)行短按功能


6、按鍵不要用delay延時,可以在定義一個變量在定時器里面以1ms時基自加,按鍵函數(shù)每當(dāng)該變量大于9即10ms掃描一次按鍵狀態(tài)、如果按鍵按下將一個靜態(tài)變量自加,,連續(xù)判斷到5次以上200次以下是短按,判斷到200次以上是長按,5次以下認(rèn)為是抖動。

評分

參與人數(shù) 2黑幣 +80 收起 理由
A142989 + 30 贊一個!
admin + 50 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

7#
ID:367460 發(fā)表于 2018-8-31 19:36 | 只看該作者
用延時判斷的話 主要是防抖程序后面還要加一個判斷   看按鍵是否離開  然后在讀取鍵值

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

8#
ID:363376 發(fā)表于 2018-9-1 10:28 | 只看該作者
用定時器記錄按鍵的商家長短就可以了

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

9#
ID:392273 發(fā)表于 2018-9-1 13:24 | 只看該作者
用定時器計數(shù)
循環(huán)判斷
按下時計數(shù)器加一
抬起時判斷計數(shù)器值,
        1 執(zhí)行長按程序, 計數(shù)器清零,否則
        2執(zhí)行短安程序, 計數(shù)器清零
否則空操作(去抖)

評分

參與人數(shù) 1黑幣 +30 收起 理由
admin + 30 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

10#
ID:358725 發(fā)表于 2018-9-2 22:14 | 只看該作者
根據(jù)你的程序思路來看存在一個無法解決的問題,那就是在下面這段程序中

  1.            while(!KEY)
  2.             {
  3.                 key_press_num++;
  4.         DelayMs(10);           //10x200=2000ms=2s
  5.                 if(key_press_num==200) //大約2s
  6.                         {
  7.                        //如果達到長按鍵標(biāo)準(zhǔn)
  8.                                //則進入長按鍵動作
  9.                //這里用于識別是否按
  10.                                                            //鍵還在按下,如果按
  11.                                              //下執(zhí)行相關(guān)動作,否則退出                       
  12.                                 while(!KEY)
  13.                                 {
  14.                                        LED2=!LED2;
  15.                                         DelayMs(200);
  16.                                        
  17.                                 }
  18.                         }                        
  19.                 }
  20.                 LED1=!LED1;     
復(fù)制代碼
                        

本來你設(shè)置為當(dāng)按鍵沒有釋放時,就會進行計數(shù),而不會點亮
LED1。

但是一旦計數(shù)值到達標(biāo)準(zhǔn),LED2就會被點亮,然后延時0.2s,結(jié)束當(dāng)前的while(!KEY)循環(huán),由于程序BUG

1.如果按鍵仍然不釋放LED2就會反復(fù)亮滅

2.或當(dāng)按鍵釋放while(!KEY)循環(huán)結(jié)束,程序循序執(zhí)行LED1=!LED1

所以你的設(shè)計思路有點小問題

評分

參與人數(shù) 2黑幣 +90 收起 理由
A142989 + 30
admin + 60 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

11#
ID:358725 發(fā)表于 2018-9-2 22:31 | 只看該作者
加一個標(biāo)志位就行了
#include<reg52.h>
//定義端口
sbit KEY=P1^4;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
void DelayUs2x(unsigned char t);//函數(shù)聲明
void DelayMs(unsigned char t);
int main (void)
{
unsigned char num=0,key_press_num,marker_bits;
LED1=1;
LED2=1;               
KEY=1; //按鍵輸入端口電平置高
while(1)         //主循環(huán)
  {
  if(!KEY)  //如果檢測到低電平,說明按鍵按下
    {
         marker_bits = 1;
         DelayMs(20); //延時去抖,一般10-20ms
     if(!KEY)     //再次確認(rèn)按鍵是否按下,沒有按下則退出
           {
           while(!KEY)
            {
                key_press_num++;
        DelayMs(10);           //10x200=2000ms=2s
                if(key_press_num==200) //大約2s
                        {
                       //如果達到長按鍵標(biāo)準(zhǔn)
                               //則進入長按鍵動作
               //這里用于識別是否按
                                                           //鍵還在按下,如果按
                                             //下執(zhí)行相關(guān)動作,否則退出                       
                                while(!KEY)
                                {
                                       marker_bits =! marker_bits;
                                       LED2=!LED2;
                                        DelayMs(200);
                                       
                                }
                        }                        
                }
                if  (marker_bits)
                 {
                LED1=!LED1;
                  }                              
            }
                  
        }        
  }
}
//uS延時函數(shù)
void DelayUs2x(unsigned char t)
{   
while(--t);
}
//mS延時函數(shù)
void DelayMs(unsigned char t)
{
     
while(t--)
{
     //大致延時1mS
     DelayUs2x(245);
         DelayUs2x(245);
}
}



評分

參與人數(shù) 2黑幣 +70 收起 理由
A142989 + 30
admin + 40 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

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