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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機(jī)實(shí)現(xiàn)按鍵短按雙擊長按程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1020872 發(fā)表于 2023-9-13 14:32 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
這個(gè)程序使用狀態(tài)機(jī)實(shí)現(xiàn)長按,雙擊,短按識別程序,很好的用,歡迎大家參考和指導(dǎo)
  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;                                                                        //!!!修改此處,可以增加/減少按鍵數(shù)量
  10.         else if(!KEY2) keynumber = 2;                                                        //!!!修改此處,可以增加/減少按鍵數(shù)量
  11.         else if(!KEY3) keynumber = 3;                                                        //!!!修改此處,可以增加/減少按鍵數(shù)量
  12.         else if(!KEY4) keynumber = 4;                                                        //!!!修改此處,可以增加/減少按鍵數(shù)量
  13.         else keynumber = 0;
  14.         return keynumber;
  15. }

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


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

使用道具 舉報(bào)

沙發(fā)
ID:123289 發(fā)表于 2023-9-15 15:29 | 只看該作者
要點(diǎn):做一個(gè)計(jì)數(shù)器CJ來判定長按與短按,CJ的規(guī)則如下:
1、CJ計(jì)數(shù)只發(fā)生于定時(shí)器的中斷服務(wù)程序中,每次中斷+1,計(jì)滿不再計(jì),即不回0。
2、CJ計(jì)數(shù)只發(fā)生于鍵按下的時(shí)候,未按下不計(jì)。
3、做一個(gè)鍵狀態(tài)判定觸發(fā)標(biāo)記:B_OK,如果鍵未按下,但CJ<>0,則置B_OK=1,表示是判斷鍵狀態(tài)的時(shí)候了。
4、當(dāng)B_OK=1,判斷鍵狀態(tài)的界定法則是:CJ<某個(gè)值為短按,CJ>某個(gè)值為長按,某個(gè)值是多少由你決定。建議事先將長短兩個(gè)界定值放置在某個(gè)寄存器中,這樣可以隨意變更界定值。
5、狀態(tài)界定完成后將:B_OK清0、CJ清0以備下次再界定。

雙擊:只是規(guī)定的時(shí)間內(nèi),發(fā)生了兩個(gè)短按,這不在此敘述了。三擊、多擊如法炮制。
回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

地板
ID:140489 發(fā)表于 2024-7-1 10:56 | 只看該作者
按鍵程序這樣寫太復(fù)雜了,你有時(shí)間去學(xué)學(xué)吳堅(jiān)鴻的程序?qū)懛ǎ饶銓W(xué)這些強(qiáng)多了
回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产视频线观看永久免费 | 中文字幕在线一区二区三区 | 91九色porny首页最多播放 | 精品国产乱码久久久久久丨区2区 | 中文一区二区视频 | 亚洲精品乱码久久久久久蜜桃91 | 美女福利视频网站 | 成人高潮片免费视频欧美 | 免费看一级毛片 | 色视频网站 | 人人草天天草 | 成人欧美一区二区三区白人 | 国产亚洲一区二区三区 | 精品久久久久一区二区国产 | 久久久久久久久久一区 | 91久久国产综合久久 | 国产在线观 | 天天操天天干天天爽 | 黄色免费观看 | 亚洲一区国产精品 | av片免费 | 欧美日韩一二三区 | 亚洲欧美一区二区三区视频 | 国产精品欧美一区二区三区 | 宅女噜噜66国产精品观看免费 | 日韩色综合 | 国产欧美在线视频 | 国产福利资源在线 | 国产亚洲精品综合一区 | 精品欧美在线观看 | 一级黄色毛片 | 男女视频在线观看网站 | 免费观看毛片 | 黄视频欧美 | av一区二区三区四区 | 成人精品| 国产精品久久久久无码av | 国产91在线视频 | 久久国产精品久久久久久 | 国产三级日本三级 | 国产在线二区 |