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

標題: 51單片機時間片段輪詢按鍵掃描源碼 [打印本頁]

作者: cmx8608121    時間: 2018-5-7 16:42
標題: 51單片機時間片段輪詢按鍵掃描源碼
單片機源程序如下:
  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. }
復制代碼

作者: westlife96    時間: 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
復制代碼





歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 国产在线一区二区三区 | 99国内精品久久久久久久 | 麻豆精品一区二区三区在线观看 | 99久久精品国产毛片 | 欧洲精品久久久久毛片完整版 | 久久中文字幕一区 | 一级网站 | 日韩有码在线观看 | 成年人在线视频 | 国产精品美女久久久久aⅴ国产馆 | 欧美一级黑人aaaaaaa做受 | 成年人在线观看 | www.日韩 | 欧美精品一区二区三区在线播放 | 亚洲久久一区 | 成人在线观看黄 | 午夜在线视频一区二区三区 | 亚洲精品一级 | 欧美www在线观看 | 天天影视亚洲综合网 | 日本免费在线观看视频 | 国产精品资源在线观看 | 欧美全黄| 人成久久| 日韩中文字幕高清 | 色橹橹欧美在线观看视频高清 | 亚洲国产精品va在线看黑人 | 国产亚洲精品久久情网 | 精品一区二区三区四区 | 亚洲精品一区二区三区在线 | 欧美 日韩 亚洲91麻豆精品 | 日韩精品在线免费观看 | 亚洲三级av | 日日操视频 | 国产欧美精品区一区二区三区 | 亚洲精品久久久久国产 | aaa级片| 成人午夜电影在线观看 | 美女天天操 | 国产男女视频网站 | 一区二区精品 |