找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機(jī)輪詢按鍵程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:77367 發(fā)表于 2015-4-19 02:22 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
修改N次?膳袛喟聪。長按。放手。
跟蹤程序跟了N次才理解清楚。然后修改成現(xiàn)在這樣。
  1. #include <reg52.h>
  2. #define uchar unsigned char
  3. //按鍵端口定義
  4. sbit io_key_1 = P2^0 ;
  5. sbit io_key_2 = P2^1 ;
  6. sbit io_key_3 = P2^2 ;
  7. sbit io_key_4 = P2^3 ;
  8. sbit P30 = P3^0;
  9. sbit P31 = P3^1;
  10. sbit P32 = P3^2;
  11. sbit P33 = P3^3;
  12.                   
  13. //定義長按鍵的TICK數(shù),以及連_發(fā)間隔的TICK數(shù)
  14. #define KEY_LONG_PERIOD         100  
  15. #define KEY_CONTINUE_PERIOD     20
  16. #define KEY_DOUDONG             20
  17. //定義按鍵返回值狀態(tài)(按下,長按,連_發(fā),釋放)
  18. #define KEY_DOWN            0x80  
  19. #define KEY_LONG            0x40  
  20. #define KEY_CONTINUE        0x20  
  21. #define KEY_UP              0x10      
  22. //定義按鍵狀態(tài)
  23. #define KEY_STATE_INIT      0  
  24. #define KEY_STATE_WOBBLE    1  
  25. #define KEY_STATE_PRESS     2  
  26. #define KEY_STATE_LONG      3  
  27. #define KEY_STATE_CONTINUE  4  
  28. #define KEY_STATE_RELEASE   5  
  29. //按鍵值
  30. #define KEY_VALUE_1         0x0e
  31. #define KEY_VALUE_2         0x0d
  32. #define KEY_VALUE_3         0x0b
  33. #define KEY_VALUE_4         0x07
  34. #define KEY_NULL            0x0f
  35. static uchar s_u8KeyState = KEY_STATE_INIT;     //關(guān)鍵狀態(tài)  
  36. static uchar s_u8KeyTimeCount = 0;      //關(guān)鍵時(shí)間計(jì)數(shù)
  37. static uchar s_u8LastKey = KEY_NULL;   //保存按鍵釋放時(shí)候的鍵值
  38. void delay_nms(unsigned char k)
  39. {
  40.     unsigned int i,j;
  41.     for(i=0;i<k;i++)
  42.         for(j=0;j<120;j++)
  43.             ;
  44. }
  45. //按鍵初始化
  46. void KeyInit(void)
  47. {
  48.      io_key_1 = 1;
  49.      io_key_2 = 1;
  50.      io_key_3 = 1;
  51.      io_key_4 = 1;            
  52. }
  53. //按鍵掃描
  54. static uchar KeyScan(void)
  55. {
  56.      if(io_key_1 == 0)return KEY_VALUE_1;
  57.      if(io_key_2 == 0)return KEY_VALUE_2;
  58.      if(io_key_3 == 0)return KEY_VALUE_3;
  59.      if(io_key_4 == 0)return KEY_VALUE_4;
  60.      return KEY_NULL;
  61. }
  62. void GetKey(uchar *pKeyValue)
  63. {
  64.      static uchar s_u8KeyState = KEY_STATE_INIT ;
  65.      static uchar s_u8KeyTimeCount = 0 ;
  66.      static uchar s_u8LastKey = KEY_NULL ;   //保存按鍵釋放時(shí)候的鍵值
  67.      static uchar s_doudong=0;
  68.      uchar KeyTemp = KEY_NULL ;
  69.      KeyTemp = KeyScan() ;         //獲取鍵值
  70.      switch(s_u8KeyState)
  71.      {
  72.          case KEY_STATE_INIT :          //初始化S1狀態(tài)
  73.                  {
  74.                      if(KEY_NULL != (KeyTemp))  //如果有按鍵按下 進(jìn)入狀態(tài)2
  75.                      {
  76.                          s_u8KeyState = KEY_STATE_WOBBLE ;
  77.                      }
  78.                  }
  79.          break ;
  80.          case KEY_STATE_WOBBLE :        //去抖動(dòng)S2狀態(tài)  
  81.                  {
  82.                     if(++s_doudong==KEY_DOUDONG)
  83.                     {
  84.                         s_doudong=0;
  85.                         s_u8KeyState = KEY_STATE_PRESS ;     
  86.                     }
  87.                     else
  88.                         s_u8KeyState = KEY_STATE_WOBBLE;   
  89.                  }
  90.          break ;
  91.          case KEY_STATE_PRESS :         //確認(rèn)有按鍵按下S3狀態(tài) 并返回按鍵值         
  92.                  {
  93.                      if(KEY_NULL != (KeyTemp))  
  94.                      {
  95.                          s_u8LastKey = KeyTemp ; //保存鍵值,以便在釋放按鍵狀態(tài)返回鍵值
  96.                          KeyTemp |= KEY_DOWN ;   //按鍵按下
  97.                          s_u8KeyState = KEY_STATE_LONG ;    //保存下次進(jìn)入長按狀態(tài)
  98.                      }
  99.                      else   //如果沒有按鍵按下 返回初始化S1
  100.                      {
  101.                          s_u8KeyState = KEY_STATE_INIT ;
  102.                      }
  103.                  }
  104.          break ;
  105.          case KEY_STATE_LONG :          //進(jìn)入長按
  106.                  {
  107.                      if(KEY_NULL != (KeyTemp))  //確認(rèn)有按鍵按下  計(jì)數(shù)
  108.                      {
  109.                          if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)   //到達(dá)閥值 返回長按鍵值
  110.                          {
  111.                              s_u8KeyTimeCount = 0 ;
  112.                              KeyTemp |= KEY_LONG ;   //長按鍵事件發(fā)生
  113.                              s_u8KeyState = KEY_STATE_LONG ;    //保存下次進(jìn)入
  114.                          }
  115.                      }
  116.                      else
  117.                      {
  118.                          s_u8KeyState = KEY_STATE_RELEASE ;         //長按狀態(tài) 按鍵放開
  119.                      }
  120.                  }
  121.          break ;
  122.          case KEY_STATE_CONTINUE :                                  //連發(fā)狀態(tài)
  123.                  {
  124.                      if(KEY_NULL != (KeyTemp))
  125.                      {
  126.                          if(++s_u8KeyTimeCount > KEY_CONTINUE_PERIOD)
  127.                          {
  128.                              s_u8KeyTimeCount = 0 ;
  129.                              KeyTemp |= KEY_CONTINUE ;
  130.                          }
  131.                      }
  132.                      else       //如果沒有按鍵 直接返回按鍵
  133.                      {
  134.                          s_u8KeyState = KEY_STATE_RELEASE ;
  135.                      }
  136.                  }
  137.          break ;
  138.          case KEY_STATE_RELEASE :           //短按返回
  139.                  {
  140.                      s_u8LastKey |= KEY_UP ;
  141.                      KeyTemp = s_u8LastKey ;
  142.                      s_u8KeyState = KEY_STATE_INIT ;
  143.                  }
  144.          break ;
  145.          default : break ;
  146.      }
  147.      *pKeyValue = KeyTemp ; //返回鍵值     
  148. }
  149. void Key_Proc(uchar key_value)
  150. {
  151.     switch(key_value)
  152.     {
  153.         case KEY_VALUE_1 | KEY_DOWN:
  154.             P3=0X0f;    //0000 1111
  155.             delay_nms(500);
  156.             break;
  157.         case KEY_VALUE_1 | KEY_LONG:
  158.             P3 = 0xf0;  //1111 0000
  159.             break;
  160.         case KEY_VALUE_1 | KEY_UP:
  161.             P3 = 0x33;  //0011 0011
  162.             break;
  163.         default:
  164.             break;
  165.     }
  166. }
  167. void main(void)
  168. {     
  169.     uchar KeyValue = KEY_NULL;
  170.     KeyInit();
  171.     P2=0xff;
  172.     P3=0x00;
  173.     while(1)                  
  174.     {   
  175.         GetKey(&KeyValue) ;
  176.         Key_Proc(KeyValue);                     
  177.     }
  178. }
復(fù)制代碼



評分

參與人數(shù) 1黑幣 +12 收起 理由
YJGG + 12

查看全部評分

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

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:98707 發(fā)表于 2016-3-1 18:21 | 只看該作者
很好的代碼,學(xué)習(xí)了.51黑電子論壇上的好資料真多!
回復(fù)

使用道具 舉報(bào)

板凳
ID:82098 發(fā)表于 2016-11-22 16:31 | 只看該作者
矩陣鍵盤可以用這個(gè)程序嗎?
回復(fù)

使用道具 舉報(bào)

地板
ID:159270 發(fā)表于 2017-3-3 01:42 | 只看該作者
這個(gè)程序會(huì)阻塞的嗎?
回復(fù)

使用道具 舉報(bào)

5#
ID:377382 發(fā)表于 2020-4-20 20:44 | 只看該作者
很不錯(cuò)的
回復(fù)

使用道具 舉報(bào)

6#
ID:748312 發(fā)表于 2020-5-10 17:24 | 只看該作者
下來測試下,謝謝提供
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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