久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7132|回復: 10
收起左側

C51單片機的按鍵復用控制兩個燈

  [復制鏈接]
ID:326587 發表于 2018-8-30 20:57 | 顯示全部樓層 |閱讀模式
50黑幣
請大神幫幫忙,看下有的程序有什么問題
原想著用一個按鍵控制兩個燈,短按控制第一個燈,長按控制第二個燈。現在長按的話,第二個燈能控制,也能影響第一個燈。這下不會改了

代碼在2樓

最佳答案

查看完整內容

使用計數法識別長短按,給你改了一下,你試試。 #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;//計數變量 int main (void) { LED1=1; LED2=1; KEY=1; //按鍵輸入端口電平置高 while(1) //主循環 { if(!KEY) //如果檢測到低電平,說 ...
回復

使用道具 舉報

ID:213173 發表于 2018-8-30 20:57 | 顯示全部樓層

使用計數法識別長短按,給你改了一下,你試試。
#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;//計數變量

int main (void)
{
        LED1=1;
        LED2=1;               
        KEY=1; //按鍵輸入端口電平置高       
        while(1)         //主循環
        {
                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
                }   
        }
}

評分

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

查看全部評分

回復

使用道具 舉報

ID:326587 發表于 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);//函數聲明
  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)         //主循環
  15.   {
  16.   if(!KEY)  //如果檢測到低電平,說明按鍵按下
  17.     {
  18.          DelayMs(20); //延時去抖,一般10-20ms
  19.      if(!KEY)     //再次確認按鍵是否按下,沒有按下則退出
  20.            {
  21.            while(!KEY)
  22.             {
  23.                 key_press_num++;
  24.         DelayMs(10);           //10x200=2000ms=2s
  25.                 if(key_press_num==200) //大約2s
  26.                         {
  27.                        //如果達到長按鍵標準
  28.                                //則進入長按鍵動作
  29.                //這里用于識別是否按
  30.                                                            //鍵還在按下,如果按
  31.                                              //下執行相關動作,否則退出                       
  32.                                 while(!KEY)
  33.                                 {
  34.                                        LED2=!LED2;
  35.                                         DelayMs(200);
  36.                                        
  37.                                 }
  38.                         }                       
  39.                 }
  40.                 LED1=!LED1;                               
  41.             }
  42.                   
  43.         }       
  44.   }
  45. }

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

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

使用道具 舉報

ID:384109 發表于 2018-8-30 23:11 | 顯示全部樓層
不應該用延時來判斷按鍵時間,應該用定時器來記錄按鍵按下的時間,再來判斷是短按,還是長按

評分

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

查看全部評分

回復

使用道具 舉報

ID:390267 發表于 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);

評分

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

查看全部評分

回復

使用道具 舉報

ID:98526 發表于 2018-8-31 08:53 | 顯示全部樓層
1、定義一個局部變量
2、長按之后將該標志位置為1
3、在松手之后判斷該標志位是否為1
4、如果不為1,確認是短按松開、執行短按功能
5、如果為1,則是長按松開、不執行短按功能


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

評分

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

查看全部評分

回復

使用道具 舉報

ID:367460 發表于 2018-8-31 19:36 | 顯示全部樓層
用延時判斷的話 主要是防抖程序后面還要加一個判斷   看按鍵是否離開  然后在讀取鍵值

評分

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

查看全部評分

回復

使用道具 舉報

ID:363376 發表于 2018-9-1 10:28 | 顯示全部樓層
用定時器記錄按鍵的商家長短就可以了

評分

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

查看全部評分

回復

使用道具 舉報

ID:392273 發表于 2018-9-1 13:24 | 顯示全部樓層
用定時器計數
循環判斷
按下時計數器加一
抬起時判斷計數器值,
        1 執行長按程序, 計數器清零,否則
        2執行短安程序, 計數器清零
否則空操作(去抖)

評分

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

查看全部評分

回復

使用道具 舉報

ID:358725 發表于 2018-9-2 22:14 | 顯示全部樓層
根據你的程序思路來看存在一個無法解決的問題,那就是在下面這段程序中

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

本來你設置為當按鍵沒有釋放時,就會進行計數,而不會點亮
LED1。

但是一旦計數值到達標準,LED2就會被點亮,然后延時0.2s,結束當前的while(!KEY)循環,由于程序BUG

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

2.或當按鍵釋放while(!KEY)循環結束,程序循序執行LED1=!LED1

所以你的設計思路有點小問題

評分

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

查看全部評分

回復

使用道具 舉報

ID:358725 發表于 2018-9-2 22:31 | 顯示全部樓層
加一個標志位就行了
#include<reg52.h>
//定義端口
sbit KEY=P1^4;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
void DelayUs2x(unsigned char t);//函數聲明
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)         //主循環
  {
  if(!KEY)  //如果檢測到低電平,說明按鍵按下
    {
         marker_bits = 1;
         DelayMs(20); //延時去抖,一般10-20ms
     if(!KEY)     //再次確認按鍵是否按下,沒有按下則退出
           {
           while(!KEY)
            {
                key_press_num++;
        DelayMs(10);           //10x200=2000ms=2s
                if(key_press_num==200) //大約2s
                        {
                       //如果達到長按鍵標準
                               //則進入長按鍵動作
               //這里用于識別是否按
                                                           //鍵還在按下,如果按
                                             //下執行相關動作,否則退出                       
                                while(!KEY)
                                {
                                       marker_bits =! marker_bits;
                                       LED2=!LED2;
                                        DelayMs(200);
                                       
                                }
                        }                        
                }
                if  (marker_bits)
                 {
                LED1=!LED1;
                  }                              
            }
                  
        }        
  }
}
//uS延時函數
void DelayUs2x(unsigned char t)
{   
while(--t);
}
//mS延時函數
void DelayMs(unsigned char t)
{
     
while(t--)
{
     //大致延時1mS
     DelayUs2x(245);
         DelayUs2x(245);
}
}



評分

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

查看全部評分

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久乐国产精品 | 久久久久久久久蜜桃 | 国产xxxx搡xxxxx搡麻豆 | 欧美成人免费电影 | 亚洲精品第一 | 精品国产一区二区三区久久影院 | 日日干日日 | 91精品国产91久久久久久吃药 | 综合自拍| 男女羞羞视频大全 | 国产精品亚洲成在人线 | 成人久久 | 在线看片国产 | 欧美日韩专区 | 亚洲精品在线视频 | 日韩中文一区二区三区 | 久久99视频 | 久久久久一区 | 日韩视频一区二区在线 | 免费a国产 | av资源中文在线 | 午夜免费福利电影 | 成人免费在线观看 | 偷牌自拍 | www.色午夜.com| 高清亚洲 | 久久久精品日本 | 国产亚洲精品久久久优势 | 久久久精选 | 中文字幕精品视频 | 91网在线播放 | 亚洲精品乱码8久久久久久日本 | 久久久久久国产一区二区三区 | 成人深夜福利网站 | 免费国产黄网站在线观看视频 | 91久久久久 | 天天操欧美 | 一区二区视频在线 | 久久视频精品 | 国产综合区 | 婷婷综合五月天 |