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

QQ登錄

只需一步,快速開始

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

求指導(dǎo):按鍵處理方法,長按3秒進(jìn)入菜單,長按1秒退出,單擊實(shí)現(xiàn)其它功能

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
想實(shí)現(xiàn)如圖的功能,具體按鍵處理方法為:長按3秒進(jìn)入菜單,長按1秒退出,單擊實(shí)現(xiàn)其它功能。其中“長按3秒進(jìn)入菜單,長按1秒退出”一點(diǎn)思路也沒有,想了好多辦法都沒法實(shí)現(xiàn),請(qǐng)各位指導(dǎo)!


按鍵操作方式.jpg (37.93 KB, 下載次數(shù): 75)

紅框內(nèi)為按鍵處理方式

紅框內(nèi)為按鍵處理方式
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:401564 發(fā)表于 2020-7-1 17:13 | 只看該作者
如果我沒有記錯(cuò)的話,哥們你搞這個(gè)“按鍵”已經(jīng)快兩年了,我記得我說過“兩年時(shí)間,學(xué)一門編程語言都可以了”,更何況只是一個(gè)功能而已呢
1:設(shè)定一個(gè)標(biāo)志位,用于標(biāo)志當(dāng)前是在菜單中,還是已經(jīng)退出菜單了
2:當(dāng)按下按鍵之后,去抖動(dòng),一邊檢測按鍵有沒有松開,一邊計(jì)時(shí)
3:按鍵松開之后,通過計(jì)時(shí)時(shí)間的長短來判定功能:
A不到1秒,無效,
B如果是已經(jīng)進(jìn)入菜單,大于1秒,小于3秒,退出。大于3秒,無效
C如果是沒有進(jìn)入菜單,小于3秒的都無效

評(píng)分

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

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

板凳
ID:91521 發(fā)表于 2020-7-1 17:47 | 只看該作者
可是儀表要求的是,按鍵1秒以上退出“初始設(shè)定菜單”,即使按鍵超過3秒也不會(huì)再次觸發(fā)出現(xiàn)“初始設(shè)定菜單”,這是個(gè)難點(diǎn),我曾經(jīng)在手電筒上見識(shí)過類似的設(shè)置,一直沒能實(shí)現(xiàn),所以反復(fù)的發(fā)帖,想找到一個(gè)編程的方法
回復(fù)

使用道具 舉報(bào)

地板
ID:781892 發(fā)表于 2020-7-1 17:58 來自手機(jī) | 只看該作者
Y_G_G 發(fā)表于 2020-7-1 17:13
如果我沒有記錯(cuò)的話,哥們你搞這個(gè)“按鍵”已經(jīng)快兩年了,我記得我說過“兩年時(shí)間,學(xué)一門編程語言都可以了 ...

按鍵1秒以上退出“初始設(shè)定菜單”,即使按鍵超過3秒也不會(huì)再次觸發(fā)出現(xiàn)“初始設(shè)定菜單”,這是個(gè)難點(diǎn),我曾經(jīng)在手電筒上見識(shí)過類似的設(shè)置,一直沒能實(shí)現(xiàn),所以反復(fù)的發(fā)帖,想找到一個(gè)編程的方法
回復(fù)

使用道具 舉報(bào)

5#
ID:91521 發(fā)表于 2020-7-1 18:44 | 只看該作者
根本不能在按鍵松開時(shí)判斷,因?yàn)檫@樣無法實(shí)現(xiàn)達(dá)到三秒立即進(jìn)入“初始設(shè)定菜單”,
回復(fù)

使用道具 舉報(bào)

6#
ID:7209 發(fā)表于 2020-7-1 18:59 | 只看該作者
按鍵按下去開始計(jì)時(shí)
松開按鍵返回時(shí)間
(這里 需要用到電平反轉(zhuǎn) 中斷
  啟用定時(shí)器
  實(shí)際上就是 一鍵多功能 的實(shí)現(xiàn)
你可以查查  ,
)

tiime  = duqu_k1_time(); //讀取定時(shí)中斷中按鍵按下去的時(shí)間
switch(time)
   {
   case 1:  //處理1s 的功能代碼  
   baeak;
   case 2:  //處理2s 的功能代碼
   break;
   case 3: //處理3s 的功能代碼
   break;
  default:  //處理不再按鍵保持時(shí)間功能
  break;

   }
//偽代碼
回復(fù)

使用道具 舉報(bào)

7#
ID:401564 發(fā)表于 2020-7-1 19:08 | 只看該作者
gl960530484 發(fā)表于 2020-7-1 17:58
按鍵1秒以上退出“初始設(shè)定菜單”,即使按鍵超過3秒也不會(huì)再次觸發(fā)出現(xiàn)“初始設(shè)定菜單”,這是個(gè)難點(diǎn),我 ...

按下按鍵超過3秒就認(rèn)為是已經(jīng)達(dá)到開機(jī)或者其它功能的條件了,然后就調(diào)用處理程序,處理玩之后再回來判斷按鍵有沒有松開,沒有松開就一直等到它松開再進(jìn)行下一次的檢測,這樣就不會(huì)出現(xiàn)一直按下按鍵就一直有功能的現(xiàn)象了,我會(huì)上傳一個(gè)LED燈的程序,你試著看一下,我用的是匯編,你要是不會(huì)匯編,那就沒有辦法了
回復(fù)

使用道具 舉報(bào)

8#
ID:401564 發(fā)表于 2020-7-1 19:10 | 只看該作者
這是一個(gè)已經(jīng)驗(yàn)證過的匯編程序,雙擊和長按是開關(guān)機(jī),短按是功能切換,你參考一下,如果不會(huì)匯編,那就沒有辦法了 LED V8.0.rar (11.1 KB, 下載次數(shù): 21)
回復(fù)

使用道具 舉報(bào)

9#
ID:213173 發(fā)表于 2020-7-1 20:50 | 只看該作者
給你寫一個(gè)短、中、長按鍵示例,具體任務(wù)自行完善。有詳細(xì)注釋,不難理解。
  1. #include<reg52.h>
  2. sbit LED1=P1^0;
  3. sbit LED2=P1^1;
  4. sbit LED3=P1^2;
  5. sbit key=P1^7;

  6. void Timer0Init()        //10毫秒@12.000MHz
  7. {
  8.         TMOD= 0x01;                //設(shè)置定時(shí)器模式
  9.         TL0 = 0xF0;                //設(shè)置定時(shí)初值
  10.         TH0 = 0xD8;                //設(shè)置定時(shí)初值
  11.         TR0 = 1;                        //定時(shí)器0開始計(jì)時(shí)
  12.         EA  = 1;       //開總中斷
  13.         ET0 = 1;       //開T0中斷
  14. }

  15. //按鍵掃描
  16. void keyscan()
  17. {
  18.         static unsigned int time=0;//計(jì)數(shù)變量
  19.         static bit key_sign=0;                //按鍵狀態(tài)標(biāo)志
  20.         if(!key)//按鍵按下
  21.         {
  22.                 time++;
  23.                 if(time>300)
  24.                         time=301;//防止溢出
  25.                 if(time>1 && key_sign==0)//10ms消抖
  26.                         key_sign=1;//確認(rèn)按鍵按下
  27.                 if(time==300)//判斷按下3s有效
  28.                         LED3=~LED3;//任務(wù)3
  29.         }
  30.         else //沒有按或按下后松手
  31.         {
  32.                 if(key_sign==1)//判斷是按鍵按下后松手
  33.                 {
  34.                         key_sign=0;
  35.                         if(time<100)//小于1s判斷短按
  36.                                 LED1=~LED1;//任務(wù)1
  37.                         if(time>=100 && time<300)//大于1s有效
  38.                                 LED2=~LED2;//任務(wù)2
  39.                 }
  40.                 time=0;
  41.         }
  42. }
  43. //主函數(shù)
  44. void main()
  45. {
  46.         Timer0Init();//定時(shí)器初始化函數(shù)
  47.         while(1)
  48.         {
  49.                 //其它任務(wù)
  50.         }
  51. }
  52. //T0中斷服務(wù)函數(shù)
  53. void Timer0Interrupt() interrupt 1
  54. {
  55.         TL0 = 0xF0;                //設(shè)置定時(shí)初值
  56.         TH0 = 0xD8;                //設(shè)置定時(shí)初值
  57.         keyscan();                //按鍵掃描
  58. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

10#
ID:633559 發(fā)表于 2020-7-1 22:41 | 只看該作者
該我出場的時(shí)候了,如果人人都獻(xiàn)出一份愛~~~,咳咳,我的截圖工具今晚不給力啊,只能分兩張了

評(píng)分

參與人數(shù) 1黑幣 +40 收起 理由
admin + 40 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

11#
ID:592807 發(fā)表于 2020-7-2 11:43 | 只看該作者
daiya 發(fā)表于 2020-7-1 18:44
根本不能在按鍵松開時(shí)判斷,因?yàn)檫@樣無法實(shí)現(xiàn)達(dá)到三秒立即進(jìn)入“初始設(shè)定菜單”,

3秒和1秒,這么精準(zhǔn)的嗎?
我按兩秒會(huì)怎么樣?按4秒怎么樣?
就不能多弄按鍵復(fù)用嗎?按鍵掃描和處理都要時(shí)間,人手按鍵時(shí)間也不精準(zhǔn)啊,誰也保證不了。


if(按下按鍵)
{
   延時(shí)500毫秒;
  if(按鍵松開)//單擊  {
      功能1;
  }
else//長按
{
     延時(shí)500毫秒;
     if(按鍵松開)
     {
        功能2;
     }
    延時(shí)1500毫秒;
    else
      {
          功能3;
      }
}
}

回復(fù)

使用道具 舉報(bào)

12#
ID:548551 發(fā)表于 2020-7-2 17:18 | 只看該作者
我不知道你是學(xué)生還是已經(jīng)在工作了,  如果是學(xué)生的話還可以理解.如果是出來工作了不應(yīng)該一個(gè)按鍵的長短按還弄不清楚啊. 我給你一個(gè)程序,上面的注釋很清楚 ,如果你還不理解的話就不要做單片機(jī)了.這個(gè)是我所有項(xiàng)目都那樣寫的. 有三個(gè)點(diǎn)要注意:1  你要用到的那個(gè)IO口,也就是按鍵IO口必須是輸入設(shè)置,并且打開上拉,2 我的程序是4MS 一個(gè)定時(shí). 3 不要用延時(shí)程序, 你用了延時(shí)程序以后這個(gè)就程序讀取的電平就不準(zhǔn)了, 時(shí)間也不準(zhǔn)了.
void KEY_SCAN(void)                                        //掃描按鍵
{
    if(!f_key_press)                                        //判斷是按下還是彈起狀態(tài) 1 按下狀態(tài) 0 彈起狀態(tài)
    {
        if(P_KEY){key_cnt=0;}                        // 讀取IO口的電平 因?yàn)殚_了上拉,沒有按按鍵的時(shí)候讀取到的為高 所以只要是高就清零計(jì)數(shù)
        key_cnt++;                                        // ++
        if(key_cnt>=10)                                        // 連續(xù)讀取IO口電平10次證明按下按鍵了, 并且穩(wěn)定了這也可以理解為消抖
        {
            key_cnt=0;                                        // 清零按鍵計(jì)數(shù) 記得你一定要清零
            f_key_press=1;                                //置按下按鍵標(biāo)志位 并且置長按按鍵標(biāo)志位
            f_key_ctrl=1;                                        // 長按標(biāo)志位置起來后面要用到
        }
    }
    else                                                        //判斷按鍵是按下還是彈起狀態(tài) 按下狀態(tài) 0 彈起狀態(tài)
    {
        if(!P_KEY){key_cnt=0;}                        //讀取IO口電平 ,開上拉的緣故 置要讀取到為低就證明還在按下狀態(tài)中 所以要清零按鍵計(jì)數(shù)
        key_cnt++;                                        //++
        if(key_cnt>=10)                                        // 連續(xù)讀取到10次高電平就證明已經(jīng)彈起按鍵了.
        {
            key_cnt=0;                                        // 清零彈起計(jì)數(shù)
            f_key_press=0;                                //清按下標(biāo)志位
            // 敲重點(diǎn)  這里仔細(xì)看
            if(f_key_ctrl)                                        //去讀取這個(gè)標(biāo)志位還在不在, 如果這個(gè)標(biāo)志位不在就說明已經(jīng)按下有3S了.直接跳過這里.執(zhí)行下一條命令;
                                                                    //如果這標(biāo)志位還在就說明按下不到3S ,只能是短按,或者按下1S-3s之間.所以我們要來判斷ctrl_cnt的個(gè)數(shù)                                         
            {
                if(ctrl_cnt>=250)                        //判斷之前的計(jì)數(shù)是多少 如果大于250*4MS =1000MS 就是長按1S的動(dòng)作,那么執(zhí)行長按1s的程序就可以了
                {
                        ctrl_cnt=0;                        // 記得判斷后要立即清零
                        f_key_1s=1;                        //和f_key_3s一樣, 后面去讀取這個(gè)標(biāo)志位 有就執(zhí)行相應(yīng)動(dòng)作,沒有就不執(zhí)行
                }
                else                                                //不大于1S就短按  我們執(zhí)行短按的程序
                {
                        ctrl_cnt=0;
                        f_key_short=1;
                }
             }
             //敲重點(diǎn)因?yàn)榍懊媾袛嗔薴_key_ctrl標(biāo)志位還在不在,所以判斷完以后一定要清零 ,并且清理的位置不能錯(cuò)
             f_key_ctrl=0;                                // 清零長按標(biāo)志位               
        }       
    }
    //
    if(f_key_ctrl)                                                // 這個(gè)長按只管3S的長按 1 S 的在彈起里面處理
    {
        ctrl_cnt++;                                        // 只要一讀取到f_key_ctrl為1 就開始++計(jì)數(shù)
        if(ctrl_cnt>=750)                                //計(jì)數(shù)到750*4ms=3000ms 就清零 說明長按3S時(shí)間到了
        {
                ctrl_cnt=0;                                // 清零計(jì)數(shù)
                f_key_ctrl=0;                                // 清零標(biāo)志位
                f_key_3s=1;                                // 這個(gè)標(biāo)志位是長按3s的標(biāo)志位,你自己另外寫一個(gè)函數(shù),然后來讀取這個(gè)標(biāo)志位 為1就執(zhí)行長按3S的動(dòng)作
                                                                //否則就不執(zhí)行
        }
     }
     else
     {
        ctrl_cnt=0;
     }
}
void WORK_APP(void)
{
        if(f_key_3s)                        //讀取上面按鍵的標(biāo)志位 3S
        {
                // 自己添加相應(yīng)的功能
        }
        else if(f_key_1s)                        // 讀取上面按鍵的標(biāo)志位1s
        {
                // 自己添加功能
        }
        else if(f_key_short)                // 讀取上面短按標(biāo)志位
        {       
                // 自己添加功能
        }
}
回復(fù)

使用道具 舉報(bào)

13#
ID:91521 發(fā)表于 2022-2-4 18:45 | 只看該作者
沒有各位想的那么復(fù)雜,一個(gè)While循環(huán)搞定
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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