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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機實現按鍵短按雙擊長按程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:1020872 發表于 2023-9-13 14:32 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
這個程序使用狀態機實現長按,雙擊,短按識別程序,很好的用,歡迎大家參考和指導
  1. /*-----------------------------------------------
  2.   名稱:按鍵
  3. ------------------------------------------------*/
  4. #include"key.h"
  5. extern unsigned char keyvalue;

  6. unsigned char keyscan()
  7. {
  8.         unsigned char keynumber;
  9.         if(!KEY1) keynumber = 1;                                                                        //!!!修改此處,可以增加/減少按鍵數量
  10.         else if(!KEY2) keynumber = 2;                                                        //!!!修改此處,可以增加/減少按鍵數量
  11.         else if(!KEY3) keynumber = 3;                                                        //!!!修改此處,可以增加/減少按鍵數量
  12.         else if(!KEY4) keynumber = 4;                                                        //!!!修改此處,可以增加/減少按鍵數量
  13.         else keynumber = 0;
  14.         return keynumber;
  15. }

  16. unsigned char key_multi(void)
  17. {
  18.         static uchar key_state;                                                                         //按鍵狀態變量
  19.         static uint key_time;                                                                                 //按鍵計時變量
  20.         static uchar key_press_nums;                                                        //按鍵次數變量               
  21.         static uint key_time_double;                                                        //按鍵雙擊時間
  22.         static uchar keynum;                                                                                        //鍵值
  23.         static uchar new_keynum;                                                                        //新的鍵值
  24.         uchar key_press, key_return;                                                        //鍵值和返回值
  25.        
  26.         key_return = None_click;                                                                         //清除返回按鍵值
  27.        
  28.         switch(keyscan())
  29.         {
  30.                 case 1:key_press = KEY1;new_keynum = 1;break;                //!!!修改此處,可以增加/減少按鍵數量
  31.                 case 2:key_press = KEY2;new_keynum = 2;break;                //!!!修改此處,可以增加/減少按鍵數量
  32.                 case 3:key_press = KEY3;new_keynum = 3;break;                //!!!修改此處,可以增加/減少按鍵數量
  33.                 case 4:key_press = KEY4;new_keynum = 4;break;                //!!!修改此處,可以增加/減少按鍵數量
  34.                 default:key_press = 1;break;
  35.         }
  36.         if(key_press_nums > 0)                                                                                 //按鍵次數大于0,說明有按鍵
  37.         {
  38.                 key_time_double++;                                                                                        //是否開始雙擊計
  39.                 if(key_time_double >= DOUBLE_KEY_TIME && key_time_double < LONG_KEY_TIME) key_state = KEY_STATE_2;//如果時間到了在雙擊和長按之間,切換到狀態2
  40.         }
  41.         switch (key_state)
  42.         {
  43.                 case KEY_STATE_0:                                                                                         //按鍵狀態0:判斷有無按鍵按下
  44.                 {
  45.                         if (!key_press)                                                                                         //是否有按鍵按下,沒有按下就退出
  46.                         {
  47.                                 key_time = 0;                                                                                         //清零時間間隔計數
  48.                                 key_state = KEY_STATE_1;                                                 //然后進入 按鍵狀態1
  49.                         }
  50.                 }break;
  51.                 case KEY_STATE_1:                                                                                         //按鍵狀態1:軟件消抖(確定按鍵是否有效,而不是誤觸)。按鍵有效的定義:按鍵持續按下超過設定的消抖時間。
  52.                 {
  53.                         if (!key_press)
  54.                         {
  55.                                 key_time++;                                                                                                 //一次10ms
  56.                                 if(key_time>=SINGLE_KEY_TIME)                         //消抖時間為:SINGLE_KEY_TIME*10ms = 10ms;
  57.                                 {
  58.                                         key_state = KEY_STATE_2;                                         //如果按鍵時間超過 消抖時間,即判定為按下的按鍵有效。進入按鍵狀態2,繼續判定到底是單擊、雙擊還是長按
  59.                                         key_press_nums++;                                                                        //按鍵次數+1
  60.                                 }
  61.                         }
  62.                         else key_state = KEY_STATE_0;                                 //如果按鍵時間沒有超過,判定為誤觸,按鍵無效,返回 按鍵狀態0,繼續等待按鍵
  63.                 }break;
  64.                 case KEY_STATE_2:                                                                                         //按鍵狀態2:判定按鍵有效的種類:是單擊,雙擊,還是長按
  65.                 {
  66.                         if(key_press)                                                                                                 //如果按鍵在 設定的雙擊時間內釋放,則判定為單擊/雙擊
  67.                         {
  68.                                 if(key_time_double < DOUBLE_KEY_TIME ) key_state = KEY_STATE_0;                                                        //雙擊時間達到前,再次掃描按鍵,看還有沒有按鍵按下
  69.                                 if(key_time_double >= DOUBLE_KEY_TIME && key_time_double < LONG_KEY_TIME)         //達到雙擊設定時間后,如果時間超過雙擊的時間則判斷按鍵按下的次數
  70.                                 {
  71.                                         if(key_press_nums == 1) key_return = Single_click + new_keynum*10;                                 //判斷只按了1次,返回有效按鍵值:單擊,通過不同的值判斷是哪個按鍵按下的單擊
  72.                                         else if(key_press_nums ==2 && new_keynum == keynum) key_return = Double_click + new_keynum*10;         //判斷按了2次和兩次按鍵按的一樣,返回有效按鍵值:雙擊,通過不同的值判斷是哪個按鍵按下的雙擊
  73.                                         key_state = KEY_STATE_0;                                         //返回 按鍵狀態0,繼續等待按鍵
  74.                                         key_press_nums = 0;                                                                //清空按鍵次數
  75.                                         key_time_double = 0;                                                        //清空雙擊計時
  76.                                 }
  77.                                 if(key_time_double >LONG_KEY_TIME ) key_state = KEY_STATE_3;        //如果長按之后才松開的,則切換到狀態3清0
  78.                         }
  79.                         else
  80.                         {       
  81.                                 key_time++;                                                                                                        //按鍵一直按著的話,長按計時
  82.                                 if(key_time >= LONG_KEY_TIME)                         //如果按鍵時間超過 設定的長按時間(LONG_KEY_TIME*10ms=80*10ms=800ms), 則判定為 長按
  83.                                 {
  84.                                         key_return = Long_click + new_keynum*10;         //返回有效鍵值值:長按,通過不同的值判斷是哪個按鍵按下的長按了
  85.                                         //key_state = KEY_STATE_3;                                         //去狀態3,等待按鍵釋放
  86.                                 }
  87.                         }
  88.                 }break;
  89.                 case KEY_STATE_3:                                                                                         //等待按鍵釋放
  90.                 {
  91.                         if (key_press)
  92.                         {
  93.                                 key_state = KEY_STATE_0;                                                 //按鍵釋放后,進入 按鍵狀態0 ,進行下一次按鍵的判定
  94.                                 key_press_nums = 0;                                                                        //清空按鍵次數
  95.                                 key_time_double = 0;                                                                //清空雙擊計時
  96.                         }
  97.                 }break;
  98.                 default:key_state = KEY_STATE_0;break;        //特殊情況:key_state是其他值得情況,清零key_state。這種情況一般出現在 沒有初始化key_state,第一次執行這個函數的時候
  99.         }
  100.         keynum = new_keynum;                                                                                        //將新獲取的鍵值賦值給鍵值
  101.         return key_return;                                                                                                 //返回 按鍵值
  102. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏12 分享淘帖 頂4 踩
回復

使用道具 舉報

沙發
ID:123289 發表于 2023-9-15 15:29 | 只看該作者
要點:做一個計數器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以備下次再界定。

雙擊:只是規定的時間內,發生了兩個短按,這不在此敘述了。三擊、多擊如法炮制。
回復

使用道具 舉報

板凳
ID:275826 發表于 2023-9-17 20:37 | 只看該作者
這個程序太復雜了
回復

使用道具 舉報

地板
ID:140489 發表于 2024-7-1 10:56 | 只看該作者
按鍵程序這樣寫太復雜了,你有時間去學學吳堅鴻的程序寫法,比你學這些強多了
回復

使用道具 舉報

5#
ID:1126459 發表于 2024-7-1 12:13 | 只看該作者
有沒有簡單的  程序或者更加詳細的說明
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美激情久久久 | 黄色精品 | 在线一区| 国产高清在线精品一区二区三区 | 蜜桃av一区二区三区 | 久久久成 | 亚洲免费一区 | 亚洲在线一区 | 久久亚洲精品视频 | 精品国产一区二区久久 | 中文字幕不卡视频在线观看 | 国产精品久久久久久吹潮日韩动画 | 欧美极品在线视频 | 成人午夜电影在线观看 | 日韩美女爱爱 | 女人一区| 成人国产网站 | 欧美成人激情 | 久久久久久国产精品三区 | 欧美日韩精品久久久免费观看 | 欧美老妇交乱视频 | 国产性色视频 | av香蕉| 国产真实精品久久二三区 | 久久综合一区二区三区 | 亚洲综合色网 | 欧美精品一二三 | jdav视频在线观看免费 | 亚洲精品一区二区三区蜜桃久 | 99免费| 久久久久精| 久久免费精品视频 | 亚洲成年人免费网站 | 97精品国产97久久久久久免费 | 成人欧美一区二区三区黑人孕妇 | 日本一本在线 | 亚洲精品亚洲人成人网 | 日韩一区二区在线观看 | xxx国产精品视频 | 91视在线国内在线播放酒店 | 三级黄色片在线播放 |