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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機輪詢按鍵程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:77367 發表于 2015-4-19 02:22 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
修改N次?膳袛喟聪。長按。放手。
跟蹤程序跟了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數,以及連_發間隔的TICK數
  14. #define KEY_LONG_PERIOD         100  
  15. #define KEY_CONTINUE_PERIOD     20
  16. #define KEY_DOUDONG             20
  17. //定義按鍵返回值狀態(按下,長按,連_發,釋放)
  18. #define KEY_DOWN            0x80  
  19. #define KEY_LONG            0x40  
  20. #define KEY_CONTINUE        0x20  
  21. #define KEY_UP              0x10      
  22. //定義按鍵狀態
  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;     //關鍵狀態  
  36. static uchar s_u8KeyTimeCount = 0;      //關鍵時間計數
  37. static uchar s_u8LastKey = KEY_NULL;   //保存按鍵釋放時候的鍵值
  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 ;   //保存按鍵釋放時候的鍵值
  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狀態
  73.                  {
  74.                      if(KEY_NULL != (KeyTemp))  //如果有按鍵按下 進入狀態2
  75.                      {
  76.                          s_u8KeyState = KEY_STATE_WOBBLE ;
  77.                      }
  78.                  }
  79.          break ;
  80.          case KEY_STATE_WOBBLE :        //去抖動S2狀態  
  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 :         //確認有按鍵按下S3狀態 并返回按鍵值         
  92.                  {
  93.                      if(KEY_NULL != (KeyTemp))  
  94.                      {
  95.                          s_u8LastKey = KeyTemp ; //保存鍵值,以便在釋放按鍵狀態返回鍵值
  96.                          KeyTemp |= KEY_DOWN ;   //按鍵按下
  97.                          s_u8KeyState = KEY_STATE_LONG ;    //保存下次進入長按狀態
  98.                      }
  99.                      else   //如果沒有按鍵按下 返回初始化S1
  100.                      {
  101.                          s_u8KeyState = KEY_STATE_INIT ;
  102.                      }
  103.                  }
  104.          break ;
  105.          case KEY_STATE_LONG :          //進入長按
  106.                  {
  107.                      if(KEY_NULL != (KeyTemp))  //確認有按鍵按下  計數
  108.                      {
  109.                          if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)   //到達閥值 返回長按鍵值
  110.                          {
  111.                              s_u8KeyTimeCount = 0 ;
  112.                              KeyTemp |= KEY_LONG ;   //長按鍵事件發生
  113.                              s_u8KeyState = KEY_STATE_LONG ;    //保存下次進入
  114.                          }
  115.                      }
  116.                      else
  117.                      {
  118.                          s_u8KeyState = KEY_STATE_RELEASE ;         //長按狀態 按鍵放開
  119.                      }
  120.                  }
  121.          break ;
  122.          case KEY_STATE_CONTINUE :                                  //連發狀態
  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. }
復制代碼



評分

參與人數 1黑幣 +12 收起 理由
YJGG + 12

查看全部評分

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

地板
ID:159270 發表于 2017-3-3 01:42 | 只看該作者
這個程序會阻塞的嗎?
回復

使用道具 舉報

5#
ID:377382 發表于 2020-4-20 20:44 | 只看該作者
很不錯的
回復

使用道具 舉報

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产成人午夜高潮毛片 | 麻豆视频在线免费观看 | 日本精品一区二区三区视频 | 一区二区三区观看视频 | 粉嫩av在线 | www.国产91| 欧美日韩国产精品一区二区 | 成人国产精品久久 | 亚洲久视频 | 日本成人免费网站 | 久久99国产精一区二区三区 | 国产精品久久777777 | 少妇久久久久 | 亚洲成人免费av | 超碰97人人人人人蜜桃 | 91免费版在线观看 | 欧美一区二区免费在线 | 午夜精品久久久久久不卡欧美一级 | 久久久久国产精品 | 91精品国产综合久久久久久首页 | 成人国产精品一级毛片视频毛片 | www.4hu影院| 国产精品久久久久久久久久久久午夜片 | 欧美午夜影院 | 亚洲视频一区 | 亚洲成人免费 | 国产小u女发育末成年 | 欧美三级在线 | 色爱综合网 | 免费看黄色片 | 免费观看的黄色网址 | 欧美日韩国产精品一区 | 男人的天堂久久 | 精品国产乱码久久久久久蜜退臀 | 一级毛片高清 | 国产一级片一区二区三区 | 中文字幕一区在线观看视频 | 国产精品久久久久久久三级 | 国产精品夜色一区二区三区 | 亚洲欧美日韩国产综合 | 日韩在线免费观看视频 |