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

QQ登錄

只需一步,快速開始

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

單片機(jī)長(zhǎng)按按鍵點(diǎn)亮、關(guān)閉LED燈的問題 求思路

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
我現(xiàn)在會(huì)中斷掃描處理按鍵,短按一下LED亮,短按一下再滅,我現(xiàn)在想長(zhǎng)按一下LED亮,長(zhǎng)按一下再滅,不知道如何下手,請(qǐng)問高手指點(diǎn)一下

1652.png (20.99 KB, 下載次數(shù): 73)

1652.png
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:320306 發(fā)表于 2021-2-26 16:20 | 只看該作者
統(tǒng)計(jì)按下的時(shí)間應(yīng)該可以,就是時(shí)間超過2S認(rèn)為長(zhǎng)按,才開燈!
回復(fù)

使用道具 舉報(bào)

板凳
ID:213173 發(fā)表于 2021-2-26 16:50 | 只看該作者
//適用于STC8
#include <reg52.h>

sbit key=P3^0;
sbit LED=P3^3;
long count;//計(jì)數(shù)變量
bit  key_sign;//按鍵狀態(tài)標(biāo)志

void main()
{
        while(1)
        {
                if(!key)//長(zhǎng)按大約0.6秒響應(yīng),增加count值就可增加延時(shí)
                {
                        if(++count>=100000 && key_sign==0)
                        {
                                key_sign=1;//記憶按鍵狀態(tài)
                                LED=~LED;//LED取反
                        }
                }
                else//松手
                {
                        count=0;//計(jì)數(shù)變量清0
                        key_sign=0;//按鍵狀態(tài)復(fù)位
                }
        }
}

評(píng)分

參與人數(shù) 1黑幣 +15 收起 理由
liuhailan5757 + 15 絕世好帖!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

地板
ID:827243 發(fā)表于 2021-2-26 17:00 | 只看該作者
定時(shí)中斷采樣鍵盤,鍵盤按下就計(jì)數(shù)+1,若判斷鍵盤松開,讀取鍵盤按下的計(jì)數(shù),根據(jù)大小判斷長(zhǎng)短按。
回復(fù)

使用道具 舉報(bào)

5#
ID:473159 發(fā)表于 2021-2-26 20:48 | 只看該作者
壇子里有詳細(xì)講解的代碼,上面找找看看,很容易
回復(fù)

使用道具 舉報(bào)

6#
ID:823677 發(fā)表于 2021-2-26 20:55 | 只看該作者
wulin 發(fā)表于 2021-2-26 16:50
//適用于STC8
#include

謝謝,我就是苦惱在了計(jì)數(shù)怎么計(jì)的問題
回復(fù)

使用道具 舉報(bào)

7#
ID:548551 發(fā)表于 2021-2-27 09:07 | 只看該作者
非STC得芯片?
回復(fù)

使用道具 舉報(bào)

8#
ID:818410 發(fā)表于 2021-2-27 16:06 | 只看該作者
P3.0讀到0后f計(jì)數(shù),
P3.0變成1后看f的值,
若f大于某一樹,則認(rèn)為是長(zhǎng)按,否則判定位短按或未按。
回復(fù)

使用道具 舉報(bào)

9#
ID:885009 發(fā)表于 2021-2-28 01:01 | 只看該作者
用定時(shí)器計(jì)數(shù)唄,
或者每過一小段時(shí)間讀一次進(jìn)行采樣,按照采樣次數(shù)來確定是否長(zhǎng)按
回復(fù)

使用道具 舉報(bào)

10#
ID:491577 發(fā)表于 2021-2-28 10:25 | 只看該作者
這是基本功,你不是會(huì)中斷掃描處理按鍵了嗎,定時(shí)器的中斷時(shí)間是很準(zhǔn)確的,比如你的定時(shí)器中斷時(shí)間是10ms,在中斷中加一句:time++;這個(gè)time就是10ms計(jì)時(shí),第一次按鍵變1后,將time=0;等按鍵再一次變0后,time*10ms就是按鍵按下的準(zhǔn)確時(shí)間。
回復(fù)

使用道具 舉報(bào)

11#
ID:387856 發(fā)表于 2021-3-6 13:51 | 只看該作者
wulin 發(fā)表于 2021-2-26 16:50
//適用于STC8
#include

終于看到高手了,這才是真確的按鍵處理思路。不像有些菜鳥,按鍵處理程序里面有delay();
回復(fù)

使用道具 舉報(bào)

12#
ID:716656 發(fā)表于 2021-3-6 15:00 | 只看該作者
  1. #include <reg51.h>

  2. sbit key = P3^0;
  3. sbit led1 = P2^0;
  4. sbit led2 = P2^1;
  5. sbit led3 = P2^2;

  6. unsigned char x = 0;

  7. void init(void); //初始化定時(shí)器0
  8. void delay(unsigned int a); //延時(shí)
  9. void key_main(void); //按鍵事件判斷

  10. void main()
  11. {
  12.                 init();
  13.                 key_main();
  14. }

  15. void init(void) //初始化定時(shí)器0
  16. {
  17.                 TMOD = 0x01;
  18. //                IT0 = 1;      //低電平有效
  19.                 TH0 = (65536-50000)/256;
  20.                 TL0 = (65536-50000)%256;
  21.                 EA = 1;
  22.                 ET0 = 1;             //允許定時(shí)器t0中斷
  23. //                EX0 = 1;
  24.                 key = 1;
  25.                 P2 = 0x00;
  26. }

  27. void key_main(void) //按鍵事件判斷
  28. {
  29.                 while(1)
  30.                 {
  31.                                 new:if(key == 0)
  32.                                 {
  33.                                                 delay(10);
  34.                                                 if(key == 0)
  35.                                                 {
  36.                                                                 TR0 = 1;
  37.                                                                 while(key == 0);       //第一次按鍵釋放
  38.                                                                 TR0 = 0;
  39.                                                           
  40.                                                                 if(x>16)        //判斷是否為長(zhǎng)按
  41.                                                                 {
  42.                                                                                 x = 0;
  43.                                                                                 led3 = 1;

  44.                                                                                 goto new;
  45.                                                                 }
  46.                                                                
  47.                                                                 x = 0;
  48.                                                                 TR0 = 1;

  49.                                                                 while(x<=6) //在第一次按鍵事件完成后,若0.5秒內(nèi)無按鍵事件,則為單擊,否則是雙擊
  50.                                                                 {
  51.                                                                                 if(key == 0)
  52.                                                                                 {
  53.                                                                                                 delay(10);
  54.                                                                                                        
  55.                                                                                                 if(key == 0)
  56.                                                                                                 {
  57.                                                                                                                         TR0 = 0;
  58.                                                                                                                         x = 0;
  59.                                                                                                                         while(key == 0);
  60.                                                                                                                         led2 = 1;

  61.                                                                                                                         goto new;
  62.                                                                                                 }
  63.                                                                                         }
  64.                                                                 }
  65.                                                                
  66.                                                                 TR0 = 0;

  67.                                                                 if(x != 0)
  68.                                                                 {
  69.                                                                                 x = 0;
  70.                                                                                 led1 = 1;

  71.                                                                                 goto new;
  72.                                                                 }
  73.                                                 }
  74.                                 }
  75.                 }
  76. }


  77. void delay(unsigned int a) //延時(shí)
  78. {
  79.                 unsigned int i;
  80.                 for(a;a>0;a--)
  81.                 for(i=110;i>0;i--);
  82. }

  83. void time0(void) interrupt 1 //定時(shí)器0
  84. {
  85. //                ET0 = 0;
  86.                 {
  87.                                 TH0 = (65536-50000)/256;
  88.                                 TL0 = (65536-50000)%256;
  89.                                 x += 1;
  90.                 }
  91. //                ET0 = 1;
  92. }

  93. //void over(void) interrupt 0 //外部中斷           觸發(fā)后亮的指示燈滅
  94. //{
  95. //                ET0 = 0;
  96. //                {
  97. //                                if(led1 == 1)
  98. //                                led1 = 0;
  99. //                                if(led2 == 1)
  100. //                                led2 = 0;
  101. //                                if(led3 == 1)
  102. //                                led3 = 0;
  103. //                }
  104. //                ET0 = 1;
  105. //}
復(fù)制代碼
單擊,雙擊,長(zhǎng)按,是一類一起學(xué)習(xí)吧
回復(fù)

使用道具 舉報(bào)

13#
ID:340765 發(fā)表于 2021-3-6 16:40 | 只看該作者
我的思路是這樣的,判斷按鍵按下在while循環(huán)自加一個(gè)變量,松開后用if判斷自加變量是否大于你定的時(shí)間變量,大于LED取反,自加變量置0.
回復(fù)

使用道具 舉報(bào)

14#
ID:47286 發(fā)表于 2021-3-6 17:05 | 只看該作者
旁觀者 發(fā)表于 2021-3-6 16:40
我的思路是這樣的,判斷按鍵按下在while循環(huán)自加一個(gè)變量,松開后用if判斷自加變量是否大于你定的時(shí)間變量 ...

必須加計(jì)數(shù)器 而且要設(shè)定計(jì)數(shù)器的時(shí)長(zhǎng)或者間隔 不然以單片機(jī)的速度 瞬間你這個(gè)變量就溢出了 然后重新計(jì)數(shù) 最后得到值未知 即 不一定是你需要的值

假設(shè)你定義個(gè)int變量 那么最大范圍是65535 如果不加計(jì)數(shù)器 int變量從0到65535也就是毫秒級(jí)別 等你松手的時(shí)候int的值可能是0~65535之間任意一個(gè)數(shù)值

簡(jiǎn)單的流程應(yīng)該是這樣

用計(jì)數(shù)器設(shè)定一個(gè)20~50ms計(jì)數(shù)器 即每一次中斷是20~50ms
然后設(shè)置一個(gè)變量 變量=計(jì)時(shí)器中斷次數(shù) 即 每20~50ms這個(gè)變量被+一次
按下按鍵后防抖 確認(rèn)按下時(shí) 清零變量
松開按鍵后防抖 確認(rèn)松開時(shí) 檢察變量的值
如果變量>閥值=長(zhǎng)按 否則是短按
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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