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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機時間片段輪詢按鍵掃描源碼

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

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:139222 發表于 2018-5-8 05:00 | 只看該作者
非常好的注釋,不過我發現程序中可能出現了一個錯誤,請指正。


  1. case KEY_STATE_LONG :          //進入長按
  2.                  {
  3.                      if(KEY_NULL != (KeyTemp))  //確認有按鍵按下  計數
  4.                      {
  5.                          if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)   //到達閥值 返回長按鍵值
  6.                          {
  7.                              s_u8KeyTimeCount = 0 ;
  8.                              KeyTemp |= KEY_LONG ;   //長按鍵事件發生
  9.                              s_u8KeyState = KEY_STATE_LONG ;    //保存下次進入
  10.                          }
  11.                      }
  12.                      else
  13.                      {
  14.                          s_u8KeyState = KEY_STATE_RELEASE ;         //長按狀態 按鍵放開
  15.                      }
  16.                  }
復制代碼


其中達到閥值以后,應該是進入連發狀態。即
  1. s_u8KeyState = KEY_STATE_CONTINUE
復制代碼

評分

參與人數 1黑幣 +80 收起 理由
admin + 80 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日本三级全黄三级三级三级口周 | 免费一级欧美在线观看视频 | 亚洲国产成人精品女人久久久 | 久久国产精品视频 | 日韩一区二区av | 国产一区二区久久 | 国产特级毛片aaaaaa | 国产精品久久片 | 午夜精品久久久久久久久久久久 | 国产极品车模吞精高潮呻吟 | 国产精品亚洲一区二区三区在线观看 | 国产精品免费视频一区 | 亚洲精品久久久久久久久久久久久 | 久久久久久久久99 | 伊人精品视频 | 欧美成人在线网站 | 国产91丝袜在线18 | 国产精品激情 | 中文字幕精品一区 | 日日天天 | 久久免费精品 | 午夜免费在线 | 亚洲欧美一区二区三区视频 | 蜜桃在线一区二区三区 | 91不卡在线 | 欧美一级www片免费观看 | 在线播放一区二区三区 | 狠狠操网站 | 色婷婷综合久久久久中文一区二区 | 久久精品亚洲精品国产欧美 | 国产伦精品一区二区三区四区视频 | 欧美日韩国产三级 | 九九热在线免费观看 | 97超碰免费| 亚洲日本一区二区 | 欧美福利网站 | av一区二区在线观看 | 中文字幕动漫成人 | 成人免费视频网站在线观看 | 在线视频日韩 | 成人免费精品视频 |