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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4905|回復: 14
打印 上一主題 下一主題
收起左側

51單片機怎樣用按鍵控制長短按切換界面,求程序思路

  [復制鏈接]
跳轉到指定樓層
樓主
ID:444712 發表于 2019-7-29 17:09 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我要用兩個按鍵k1,k2。長按K2,切換到設置界面,短按K2切換到常規界面。弄了好久沒有弄好,請高手幫忙指導一下,謝謝!
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:435708 發表于 2019-7-29 19:54 | 只看該作者
請工程化,定制化你的單片機代碼
http://www.zg4o1577.cn/bbs/dpj-162218-1.html
(出處: 單片機論壇)
回復

使用道具 舉報

板凳
ID:332444 發表于 2019-7-29 20:44 | 只看該作者
一般使用狀態進行切換,你是怎么弄的不行?
回復

使用道具 舉報

地板
ID:213173 發表于 2019-7-29 21:18 | 只看該作者
如果K2只是用于切換界面不必采用長短按方式,只要設置一個標志隨操作取反即可。如果K2是多功能鍵才有必要分長短按。給你一個簡單實用的長短按示例程序參考,希望對你有所幫助。
  1. #include <REG51.H>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. #define key_S 20                                                //宏定義短按(20ms)
  5. #define key_L key_S*50                                //宏定義長按(1s)

  6. sbit key1=P3^5;
  7. sbit key2=P3^6;
  8. sbit LED1=P1^0;
  9. sbit LED2=P1^2;
  10. sbit LED3=P1^4;
  11. sbit LED4=P1^6;
  12. uchar KeySec=0;

  13. void Timer0Init()//1毫秒@12.000MHz
  14. {
  15.         TMOD= 0x01;                //設置定時器模式
  16.         TL0 = 0x18;                //設置定時初值
  17.         TH0 = 0xFC;                //設置定時初值
  18.         TF0 = 0;                        //清除TF0標志
  19.         TR0 = 1;                        //定時器0開始計時
  20.         EA=1;                                //開總中斷
  21.         ET0=1;                        //開定時器0中斷
  22. }

  23. void keyscan()                                                        //按鍵掃描
  24. {
  25.         static uint count1=0;                        //計數變量
  26.         static uint count2=0;                        //計數變量
  27.         if(!key1)   
  28.         {  
  29.                 count1++;  
  30.                 if(count1==key_L)                                //長按
  31.                         KeySec=2;                                        //輸出鍵值2
  32.                 if(count1>key_L)                                //防止count溢出
  33.                         count1=key_L+1;          
  34.         }  
  35.         else                                                                        //按鍵抬起
  36.         {  
  37.                 if(count1>key_S && count1<key_L)//短按
  38.                         KeySec=1;                                        //輸出鍵值1
  39.                         count1=0;                                        //count清0
  40.         }   
  41.         if(!key2)   
  42.         {  
  43.                 count2++;  
  44.                 if(count2==key_L)                                //長按
  45.                         KeySec=4;                                        //輸出鍵值4
  46.                 if(count2>key_L)                                //防止count溢出
  47.                         count2=key_L+1;          
  48.         }  
  49.         else                                                                        //按鍵抬起
  50.         {  
  51.                 if(count2>key_S && count2<key_L)//短按
  52.                         KeySec=3;                                        //輸出鍵值3
  53.                         count2=0;                                        //count清0
  54.         }   
  55. }

  56. void key_service()                                        //按鍵服務程序
  57. {
  58.         switch(KeySec)                                                //按鍵服務狀態切換
  59.         {
  60.                 case 1:LED2=!LED2;KeySec=0;break;
  61.                 case 2:LED1=!LED1;KeySec=0;break;
  62.                 case 3:LED4=!LED4;KeySec=0;break;
  63.                 case 4:LED3=!LED3;KeySec=0;break;
  64.                 default: break;
  65.         }
  66. }

  67. void main()
  68. {
  69.         Timer0Init();                //初始化定時器
  70.         while(1)
  71.         {
  72.                 key_service();        //按鍵服務程序
  73.         }
  74. }
  75. void timer0() interrupt        1//1毫秒@12.000MHz
  76. {
  77.         TL0 = 0x18;                //設置定時重裝值
  78.         TH0 = 0xFC;                //設置定時重裝值
  79.         keyscan();                //按鍵掃描程序
  80. }
復制代碼



回復

使用道具 舉報

5#
ID:136106 發表于 2019-7-29 22:34 | 只看該作者
這個可以用定時器來操作,假設K2按下的時間超過2S進入設置界面。配置好定時器計時計數,當檢測到K2按下時開啟計時。比如說100ms來一次中斷,計數值temp++,當來20次中斷后時間就為2S。判斷按鍵松開時temp的值是否大于20?當temp的值大于20就進入你所說的設置界面,小于20就進入頁面切換。這樣的小程序用51來操作很容易,但是要注意定時器計數器的初值裝載的問題,還有就是51單片機所用的晶振。12MHz的晶振和11.0592MHz的初值裝載是不一樣的。沒看懂的話就要回去看看51的定時器的知識了
回復

使用道具 舉報

6#
ID:388197 發表于 2019-7-29 23:59 | 只看該作者
隨手寫的,就寫了1個按鍵長按短按不同功能,不保證沒BUG.注釋標得也自認為是清楚了,你對著你想要的修改調試下應該就可以了.


#define Long_Push_Time    n        //長按功能按鍵時長(n乘以定時器中斷周期)
#define Short_Push_Time   m       //短按功能按鍵時間,需注意必須n 大于 m
sbit KEY = Px^x;                               //按鍵IO口定義
bit Flag_Short_Push_Funcation = 0;    //短按觸發標志
bit Flag_Long_Push_Funcation = 0;    //長按觸發標志
bit Flag_KEY_Pushed               = 0;   //按鍵曾經按下標志

void Init_T0()                                 //定時器中斷設置
{
   .....
}

void Short_Push_Prog()
{
    ..........
}

void Long_Push_Prog()
{
     ............
}
void mian()
{
     Init_T0();
     while(1)
     {
        if(Flag_Short_Push_Funcation)                      //如果短按功能被置1
        {
              Short_Push_Prog();                              //執行短按功能對應的函數
              Flag_Short_Push_Funcation = 0;           //清短按功能標志.
        }
        if(Flag_Long_Push_Funcation)                    //長按功能,跟上面類同.
       {
               Long_Push_Prog();
               Flag_Long_Push_Funcation = 0;
       }
     }
}

void T0_ISR() interrupt 1
{
    TH0 = XXXX;
    TL0 = XXXX;
     if(!KEY)                                             //按鍵按下
     {
        KEY_CNT++;                                 //開始計時
        Flag_KEY_Pushed= 1;                    //按鍵已經按過的標志置1
        Flag_Short_Push_Funcation = 0;                   //短按無效
        Flag_Long_Push_Funcation  = 0;                   //長按無效
     }
     if(KEY && Flag_KEY_Pushed == 1 && KEY_CNT < Short_Push_Time)
     /*如果按鍵沒有按下但按鍵曾經按下,可是按下時間很短,不足以觸發短按的設定時間,則認為是干擾*/
    {
         Flag_KEY_Pushed= 0;                                  //清按鍵曾經按下標志
         KEY_CNT = 0;                                            //清按鍵按下計時變量
         Flag_Short_Push_Funcation = 0;                   //短按無效
         Flag_Long_Push_Funcation  = 0;                   //長按無效
         return;                                          //如判斷為干擾,則下面的代碼無須執行,直接跳出.  
    }
     if(KEY && Flag_KEY_Pushed == 1 && KEY_CNT>=Short_Push_Time &&
       KEY_CNT < Long_Push_Time)
      /*如果按鍵沒有按下, 但按鍵已經按過(用來判斷按過后彈起),
            并且曾經按下時間超過 設定短按時間且不超過長按時間*/
     {
           Flag_Short_Push_Funcation = 1;         //短按功能有效
           Flag_Long_Push_Funcation = 0;         //長按功能無效
           KEY_CNT             = 0;                      //清按鍵計時變量
           Flag_KEY_Pushed=  0;                      //清按鍵曾經按下標志
           return;                       //判斷完成,直接跳出
     }
}

      if(KEY && Flag_KEY_Pushed == 1 && KEY_CNT>=Long_Push_Time )
      /*如果按鍵沒有按下, 但按鍵已經按過(用來判斷按過后彈起),
            且曾經按下時間超過 長按時間*/
       {
           Flag_Short_Push_Funcation = 0;         //短按功能無效
           Flag_Long_Push_Funcation = 1;         //長按功能有效
           KEY_CNT             = 0;                      //清按鍵計時變量
           Flag_KEY_Pushed=  0;                      //清按鍵曾經按下標志
       }
}
回復

使用道具 舉報

7#
ID:511461 發表于 2019-7-30 08:27 | 只看該作者
cjm82 發表于 2019-7-29 23:59
隨手寫的,就寫了1個按鍵長按短按不同功能,不保證沒BUG.注釋標得也自認為是清楚了,你對著你想要的修改調試下 ...

謝謝分享
回復

使用道具 舉報

8#
ID:123289 發表于 2019-7-30 08:31 | 只看該作者
要點:做一個計數器CJ來判定長按與短按,CJ的規則如下:
1、CJ計數只發生于定時器的中斷服務程序中,每次中斷+1,計滿不再計,即不回0。
2、CJ計數只發生于鍵按下的時候,未按下不計。
3、做一個鍵狀態判定觸發標記:B_OK,如果鍵未按下,但CJ<>0,則置B_OK=1,表示是判斷鍵狀態的時候了。
4、當B_OK=1,判斷鍵狀態的界定法則是:CJ<某個值為短按,CJ>某個值為長按,某個值是多少由你決定。建議事先將長短兩個界定值放置在某個寄存器中,這樣可以隨意變更界定值。
5、狀態界定完成后將:B_OK清0、CJ清0以備下次再界定。
回復

使用道具 舉報

9#
ID:123289 發表于 2019-7-30 08:40 | 只看該作者
設置界面、常規界面各做一個標記如:B_SET、B_NOR。在哪個界面哪個置1。再多的界面也這樣做。如果只有兩個界面可以只用一個標記。界面分層疊進疊退時還需要增加次序(層面記憶),這里不說了。
長按以后的動作是:B_SET=1、其它B_NOR=0。
短按以后的動作是:B_NOR=1、其它B_SET=0。
回復

使用道具 舉報

10#
ID:123289 發表于 2019-7-30 08:41 | 只看該作者
界面的切換,發生于B_SET、B_NOR有變化的時候。
回復

使用道具 舉報

11#
ID:307020 發表于 2019-7-30 10:47 | 只看該作者
參考文章“請工程化,定制化你的單片機代碼”,用中斷服務對按下鍵進行計數,根據計數的多少便可換算時間長短、便可根據不同時間長短執行不同的程序了。
回復

使用道具 舉報

12#
ID:592379 發表于 2019-7-30 15:31 | 只看該作者
用定時器做,按下按鈕開始計數,放開按鈕結束計數,按鈕函數里面要加個防抖延時
回復

使用道具 舉報

13#
ID:444712 發表于 2019-8-1 16:47 | 只看該作者
謝謝!
回復

使用道具 舉報

14#
ID:444712 發表于 2019-8-2 16:45 | 只看該作者
cjm82 發表于 2019-7-29 23:59
隨手寫的,就寫了1個按鍵長按短按不同功能,不保證沒BUG.注釋標得也自認為是清楚了,你對著你想要的修改調試下 ...

Init_T0,void Short_Push_Prog(),void Long_Push_Prog().里邊的內容能否幫忙提供一下.謝謝!
回復

使用道具 舉報

15#
ID:415527 發表于 2019-8-4 10:47 | 只看該作者
當按鍵按下時,開啟定時器,并且在定時器中斷里面用一個變量來計數,當按鍵松開時再來判斷計數時間,如果小于0.5s,則判斷為短按,標志位給0,如果大于0.5s,標志位給1,然后根據標志位進行界面切換。定時器的計數時間要設置一個上限,否則如果時間太長可能會溢出,判斷按鍵按下或松開,可以用經典的三行代碼,其中有兩個變量,一個變量是用來判斷按鍵的“下降沿”(其實準確來說并不能定義為下降沿,只是按鍵按下時,第一遍執行程序時,對應的位會發生改變,當執行第二遍時就又變為0,有點類似于static的作用),另一個變量是用來檢測按鍵是否為按下狀態,可以用這兩個變量來判斷按鍵按下和松開,從而開啟或改變定時器,讀取計數值,讀取完計數值后需要將計數值清零,否則,第二次按下按鍵時則判斷不了短按。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美黑人国产人伦爽爽爽 | 成人性视频免费网站 | 91精品久久久久久久久 | 伊人二区 | 久国久产久精永久网页 | 亚洲毛片在线观看 | 日韩中文字幕 | 精品国产18久久久久久二百 | 99re视频| 国产在线视频在线观看 | 成人深夜福利 | 国产精品美女久久久久aⅴ国产馆 | 黄色大片免费观看 | 婷婷综合在线 | 欧美日韩在线播放 | 日韩久草| 国产免费a | 成人免费视频网址 | 你懂的在线视频播放 | 午夜视频网站 | 国产精品一区二区不卡 | 国产一区免费 | 日韩欧美精品 | 免费爱爱视频 | 久久99深爱久久99精品 | 久久久久一区 | 蜜月aⅴ免费一区二区三区 99re在线视频 | 二区三区视频 | 懂色中文一区二区在线播放 | 欧美日韩高清一区 | 九九久久国产精品 | 草久在线| 91视频.com| 夜夜爽夜夜操 | 国产目拍亚洲精品99久久精品 | 日韩天堂av | 国产一区视频在线 | 99成人 | 天天久久 | 欧美日韩三区 | 亚洲精品乱码久久久久久9色 |