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

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

QQ登錄

只需一步,快速開始

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

51單片機(jī)學(xué)習(xí):基于狀態(tài)機(jī)的按鍵對(duì)時(shí)程序(短按,長(zhǎng)按,連發(fā))

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
之前的電子鐘程序中,用的按鍵消抖處理方法是10ms的延時(shí),這種方法效率比較低
所以現(xiàn)在利用狀態(tài)機(jī)原理重寫一下,效率很高啊

4個(gè)獨(dú)立按鍵中用到3個(gè),
keys5用于切換對(duì)時(shí)分秒等狀態(tài),keys2是減小數(shù)值,keys3是增加數(shù)值

同時(shí)可以判斷按鍵的"短按,長(zhǎng)按,連發(fā)"等功能
小于2秒視為短按,
大于2秒視為長(zhǎng)按,
在長(zhǎng)按狀態(tài)下每0.2秒自動(dòng)連發(fā)一次, 這樣對(duì)時(shí)的時(shí)候就不用按N次了


程序分很多個(gè)文件 ,Keil uVision4 打包





  1. #include "keyScan.h"
  2. #include <reg52.h>

  3. /*按鍵初始化,若io沒有復(fù)用的話可以省略此步驟
  4. void KeyInit(void)
  5. {
  6.     keyS2 = 1 ;
  7.     keyS3 = 1 ;
  8.     keyS4 = 1 ;
  9.     keyS5 = 1 ;
  10.         //即P3|=0xf0;            
  11. }*/

  12. static u8 getKey(void)                    //獲取P3口值
  13. {
  14.     if(key_down == keyS2)
  15.         {
  16.                 return KEYS2_VALUE ;
  17.         }

  18.     if(key_down == keyS3 )
  19.         {
  20.           return KEYS3_VALUE ;
  21.         }

  22.     if(key_down == keyS4 )
  23.         {
  24.                 return KEYS4_VALUE ;
  25.         }
  26.          
  27.     if(key_down == keyS5 )
  28.         {
  29.                 return KEYS5_VALUE ;
  30.         }

  31.     return key_up ;    //0xf0  沒有任何按鍵
  32. }

  33. //函數(shù)每10ms被調(diào)用一次,而我們彈性按鍵過程時(shí)一般都20ms以上
  34. //所以每次按鍵至少調(diào)用本函數(shù)2次
  35. u8 read_key(u8* pKeyValue)                          
  36. {
  37.     static u8  s_u8keyState=0;        //未按,普通短按,長(zhǎng)按,連發(fā)等狀態(tài)
  38.     static u16 s_u16keyTimeCounts=0;  //在計(jì)時(shí)狀態(tài)的計(jì)數(shù)器
  39.         static u8  s_u8LastKey = key_up ; //保存按鍵釋放時(shí)的P3口數(shù)據(jù)

  40.     u8 keyTemp=0;                          //鍵對(duì)應(yīng)io口的電平
  41.     s8 key_return=0;                //函數(shù)返回值
  42.     keyTemp=key_up & getKey();  //提取所有的key對(duì)應(yīng)的io口

  43.     switch(s_u8keyState)           //這里檢測(cè)到的是先前的狀態(tài)
  44.     {
  45.         case state_keyUp:   //如果先前是初始態(tài),即無動(dòng)作
  46.         {
  47.             if(key_up!=keyTemp) //如果鍵被按下
  48.             {
  49.                 s_u8keyState=state_keyDown; //更新鍵的狀態(tài),普通被按下
  50.             }
  51.         }
  52.         break;
  53.         
  54.         case state_keyDown: //如果先前是被按著的
  55.         {
  56.             if(key_up!=keyTemp) //如果現(xiàn)在還被按著
  57.             {
  58.                 s_u8keyState=state_keyTime; //轉(zhuǎn)換到計(jì)時(shí)態(tài)
  59.                 s_u16keyTimeCounts=0;
  60.                                 s_u8LastKey = keyTemp;     //保存鍵值
  61.             }
  62.             else
  63.             {
  64.                 s_u8keyState=state_keyUp; //鍵沒被按著,回初始態(tài),說明是干擾
  65.             }
  66.         }
  67.         break;
  68.         
  69.         case state_keyTime:  //如果先前已經(jīng)轉(zhuǎn)換到計(jì)時(shí)態(tài)(值為3)
  70.         {  //如果真的是手動(dòng)按鍵,必然進(jìn)入本代碼塊,并且會(huì)多次進(jìn)入
  71.             if(key_up==keyTemp) //如果未按鍵
  72.             {
  73.                 s_u8keyState=state_keyUp;
  74.                 key_return=return_keyPressed;    //返回1,一次完整的普通按鍵
  75.                 //程序進(jìn)入這個(gè)語句塊,說明已經(jīng)有2次以上10ms的中斷,等于已經(jīng)消抖
  76.                 //那么此時(shí)檢測(cè)到按鍵被釋放,說明是一次普通短按
  77.             }
  78.             else  //在計(jì)時(shí)態(tài),檢測(cè)到鍵還被按著
  79.             {
  80.                 if(++s_u16keyTimeCounts>key_longTimes) //時(shí)間達(dá)到2秒
  81.                 {
  82.                     s_u8keyState=state_keyLong;  //進(jìn)入長(zhǎng)按狀態(tài)
  83.                     s_u16keyTimeCounts=0;                  //計(jì)數(shù)器清空,便于進(jìn)入連發(fā)重新計(jì)數(shù)
  84.                     key_return=return_keyLong;   //返回state_keyLong
  85.                 }
  86.                 //代碼中,在2秒內(nèi)如果我們一直按著key的話,返回值只會(huì)是0,不會(huì)識(shí)別為短按或長(zhǎng)按的
  87.             }
  88.         }
  89.         break;
  90.         
  91.         case state_keyLong:  //在長(zhǎng)按狀態(tài)檢測(cè)連發(fā)  ,每0.2秒發(fā)一次
  92.         {
  93.             if(key_up==keyTemp)
  94.             {
  95.                s_u8keyState=state_keyUp;
  96.             }
  97.             else //按鍵時(shí)間超過2秒時(shí)
  98.             {
  99.                 if(++s_u16keyTimeCounts>key_autoTimes)//10*20=200ms
  100.                 {
  101.                     s_u16keyTimeCounts=0;
  102.                     key_return=return_keyAuto;  //每0.2秒返回值的第2位置位(1<<2)
  103.                 }//連發(fā)的時(shí)候,肯定也伴隨著長(zhǎng)按
  104.             }
  105.             key_return |= return_keyLong;  //0x02是肯定的,0x04|0x02是可能的
  106.         }
  107.         break;
  108.         
  109.         default:
  110.         break;
  111.     }
  112.         *pKeyValue = s_u8LastKey ; //返回鍵值
  113.     return key_return;
  114. }
復(fù)制代碼

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

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:161747 發(fā)表于 2017-1-16 08:15 | 只看該作者
沒看到打包文件啊。
回復(fù)

使用道具 舉報(bào)

板凳
ID:976756 發(fā)表于 2021-11-1 18:02 | 只看該作者
沒有看到打包文件
回復(fù)

使用道具 舉報(bào)

地板
ID:954686 發(fā)表于 2021-11-2 08:04 | 只看該作者
方法不錯(cuò),狀態(tài)機(jī),沒有死等延時(shí)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 麻豆久久久久 | 一区二区日韩 | a级片在线观看 | 亚洲国产福利视频 | 久久精品视频一区二区 | 欧美日韩视频在线第一区 | 国产91久久久久久久免费 | 一区在线视频 | 国产十日韩十欧美 | 成人中文字幕av | 欧美成人精品在线 | www.色午夜.com| 欧美久久久久久久 | 中文字幕一区二区三区四区 | h视频在线免费 | 国产福利网站 | 国产精品视频网 | 99精品欧美 | av在线亚洲天堂 | 一区二区三区欧美 | 成人免费大片黄在线播放 | 亚洲成av | 视频一区二区三区中文字幕 | 国产三级国产精品 | 国产视频精品区 | 日韩一级免费电影 | h在线看| 国产在线精品一区 | 久久久女 | 男人天堂午夜 | 久久久久久综合 | 欧美三区在线观看 | 久久久精品影院 | 一级大片网站 | 一级黄色裸片 | 国产综合视频 | 久久亚洲欧美日韩精品专区 | 国产999精品久久久 日本视频一区二区三区 | 欧美激情va永久在线播放 | 国产精品一二三区 | 亚洲国产成人一区二区 |