![]() |
發布時間: 2020-7-1 07:59
正文摘要:想實現如圖的功能,具體按鍵處理方法為:長按3秒進入菜單,長按1秒退出,單擊實現其它功能。其中“長按3秒進入菜單,長按1秒退出”一點思路也沒有,想了好多辦法都沒法實現,請各位指導! |
沒有各位想的那么復雜,一個While循環搞定 |
我不知道你是學生還是已經在工作了, 如果是學生的話還可以理解.如果是出來工作了不應該一個按鍵的長短按還弄不清楚啊. 我給你一個程序,上面的注釋很清楚 ,如果你還不理解的話就不要做單片機了.這個是我所有項目都那樣寫的. 有三個點要注意:1 你要用到的那個IO口,也就是按鍵IO口必須是輸入設置,并且打開上拉,2 我的程序是4MS 一個定時. 3 不要用延時程序, 你用了延時程序以后這個就程序讀取的電平就不準了, 時間也不準了. void KEY_SCAN(void) //掃描按鍵 { if(!f_key_press) //判斷是按下還是彈起狀態 1 按下狀態 0 彈起狀態 { if(P_KEY){key_cnt=0;} // 讀取IO口的電平 因為開了上拉,沒有按按鍵的時候讀取到的為高 所以只要是高就清零計數 key_cnt++; // ++ if(key_cnt>=10) // 連續讀取IO口電平10次證明按下按鍵了, 并且穩定了這也可以理解為消抖 { key_cnt=0; // 清零按鍵計數 記得你一定要清零 f_key_press=1; //置按下按鍵標志位 并且置長按按鍵標志位 f_key_ctrl=1; // 長按標志位置起來后面要用到 } } else //判斷按鍵是按下還是彈起狀態 按下狀態 0 彈起狀態 { if(!P_KEY){key_cnt=0;} //讀取IO口電平 ,開上拉的緣故 置要讀取到為低就證明還在按下狀態中 所以要清零按鍵計數 key_cnt++; //++ if(key_cnt>=10) // 連續讀取到10次高電平就證明已經彈起按鍵了. { key_cnt=0; // 清零彈起計數 f_key_press=0; //清按下標志位 // 敲重點 這里仔細看 if(f_key_ctrl) //去讀取這個標志位還在不在, 如果這個標志位不在就說明已經按下有3S了.直接跳過這里.執行下一條命令; //如果這標志位還在就說明按下不到3S ,只能是短按,或者按下1S-3s之間.所以我們要來判斷ctrl_cnt的個數 { if(ctrl_cnt>=250) //判斷之前的計數是多少 如果大于250*4MS =1000MS 就是長按1S的動作,那么執行長按1s的程序就可以了 { ctrl_cnt=0; // 記得判斷后要立即清零 f_key_1s=1; //和f_key_3s一樣, 后面去讀取這個標志位 有就執行相應動作,沒有就不執行 } else //不大于1S就短按 我們執行短按的程序 { ctrl_cnt=0; f_key_short=1; } } //敲重點因為前面判斷了f_key_ctrl標志位還在不在,所以判斷完以后一定要清零 ,并且清理的位置不能錯 f_key_ctrl=0; // 清零長按標志位 } } // if(f_key_ctrl) // 這個長按只管3S的長按 1 S 的在彈起里面處理 { ctrl_cnt++; // 只要一讀取到f_key_ctrl為1 就開始++計數 if(ctrl_cnt>=750) //計數到750*4ms=3000ms 就清零 說明長按3S時間到了 { ctrl_cnt=0; // 清零計數 f_key_ctrl=0; // 清零標志位 f_key_3s=1; // 這個標志位是長按3s的標志位,你自己另外寫一個函數,然后來讀取這個標志位 為1就執行長按3S的動作 //否則就不執行 } } else { ctrl_cnt=0; } } void WORK_APP(void) { if(f_key_3s) //讀取上面按鍵的標志位 3S { // 自己添加相應的功能 } else if(f_key_1s) // 讀取上面按鍵的標志位1s { // 自己添加功能 } else if(f_key_short) // 讀取上面短按標志位 { // 自己添加功能 } } |
daiya 發表于 2020-7-1 18:44 3秒和1秒,這么精準的嗎? 我按兩秒會怎么樣?按4秒怎么樣? 就不能多弄按鍵復用嗎?按鍵掃描和處理都要時間,人手按鍵時間也不精準啊,誰也保證不了。 if(按下按鍵) { 延時500毫秒; if(按鍵松開)//單擊 { 功能1; } else//長按 { 延時500毫秒; if(按鍵松開) { 功能2; } 延時1500毫秒; else { 功能3; } } } |
給你寫一個短、中、長按鍵示例,具體任務自行完善。有詳細注釋,不難理解。
|
這是一個已經驗證過的匯編程序,雙擊和長按是開關機,短按是功能切換,你參考一下,如果不會匯編,那就沒有辦法了
![]() |
gl960530484 發表于 2020-7-1 17:58 按下按鍵超過3秒就認為是已經達到開機或者其它功能的條件了,然后就調用處理程序,處理玩之后再回來判斷按鍵有沒有松開,沒有松開就一直等到它松開再進行下一次的檢測,這樣就不會出現一直按下按鍵就一直有功能的現象了,我會上傳一個LED燈的程序,你試著看一下,我用的是匯編,你要是不會匯編,那就沒有辦法了 |
按鍵按下去開始計時 松開按鍵返回時間 (這里 需要用到電平反轉 中斷 啟用定時器 實際上就是 一鍵多功能 的實現 你可以查查 , ) tiime = duqu_k1_time(); //讀取定時中斷中按鍵按下去的時間 switch(time) { case 1: //處理1s 的功能代碼 baeak; case 2: //處理2s 的功能代碼 break; case 3: //處理3s 的功能代碼 break; default: //處理不再按鍵保持時間功能 break; } //偽代碼 |
根本不能在按鍵松開時判斷,因為這樣無法實現達到三秒立即進入“初始設定菜單”, |
Y_G_G 發表于 2020-7-1 17:13 按鍵1秒以上退出“初始設定菜單”,即使按鍵超過3秒也不會再次觸發出現“初始設定菜單”,這是個難點,我曾經在手電筒上見識過類似的設置,一直沒能實現,所以反復的發帖,想找到一個編程的方法 回 |
可是儀表要求的是,按鍵1秒以上退出“初始設定菜單”,即使按鍵超過3秒也不會再次觸發出現“初始設定菜單”,這是個難點,我曾經在手電筒上見識過類似的設置,一直沒能實現,所以反復的發帖,想找到一個編程的方法 |