找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2917|回復(fù): 1
收起左側(cè)

狀態(tài)機(jī)思想在單片機(jī)中的應(yīng)用 附程序和大量資料

[復(fù)制鏈接]
ID:74758 發(fā)表于 2017-2-28 10:54 | 顯示全部樓層 |閱讀模式
FSM,有限狀態(tài)機(jī)。在一個(gè)高效的程序中,一般都能看到狀態(tài)機(jī)的身影。最近自己在試著將自己寫的程序用狀態(tài)機(jī)的思想重新整一遍,找了一些資料,分享下。如有侵權(quán),望告知,馬上刪除。。
0.png
單片機(jī)狀態(tài)機(jī)的全部資料下載:
狀態(tài)機(jī).rar (12.5 MB, 下載次數(shù): 135)

我自己參考別人更改的狀態(tài)機(jī)按鍵掃描程序:
  1. enum FSM_key_status
  2. {
  3.         _Idle = 0,
  4.         _Key1_Down,
  5.         _Key1_Press,
  6.         _Key1_Up,
  7.         _Key2_Down,
  8.         _Key2_Press,
  9.         _Key2_Up,               
  10. };


  11. uchar event_key_scan(void)
  12. {
  13.         static volatile uchar key_status = 0;                                //按鍵狀態(tài)累計(jì)
  14.         static volatile uchar key_restate = 0;                                //按鍵狀態(tài)累計(jì)
  15.         static volatile uint key_count = 0;                                        //按鍵保持時(shí)間累計(jì)
  16.         volatile uchar  key_return = 0;                                                //按鍵返回值
  17.         static uchar key_type=0;
  18.         uchar num = 0;
  19.         uchar new_key=0;
  20.        
  21.         new_key = _pa & 0x06;
  22. //        num = Judge_key(new_key);                                //存在多個(gè)按鍵連按時(shí)
  23.         if(num == 1)
  24.                 LED_G_ON;

  25.         switch(key_status)
  26.         {
  27.                 case _Idle:                                                                        //空閑狀態(tài)時(shí)判斷按鍵是否按下,判定為按下時(shí)按鍵狀態(tài)累計(jì)加1
  28.                         {
  29.                                 switch(num)
  30.                                 {
  31.                                         case 1:
  32.                                                 {
  33.                                                         key_restate = new_key;
  34.                                                         key_status = _Key1_Down;               
  35.                                                 }        break;
  36.                                         case 2:
  37.                                                 {
  38.                                                         key_restate = new_key;
  39.                                                         key_status = _Key2_Down;       
  40.                                                 }        break;
  41.                                         default:        break;       
  42.                                 }
  43.                                 key_status = 0;
  44.                                 key_count = 0;
  45.                                 key_return = 0;                                                                                //未按下時(shí)清除相應(yīng)的變量
  46.                                 key_type = 0;
  47.                         }        break;
  48.                 case _Key1_Down:
  49.                         {
  50.                                 switch(num)
  51.                                 {
  52.                                         case 1:
  53.                                                 {
  54.                                                         if(key_restate == new_key)
  55.                                                                 key_status++;
  56.                                                         else                                                       
  57.                                                                 key_status = _Idle;
  58.                                                                
  59.                                                 }        break;
  60.                                         case 2:
  61.                                                 {
  62.                                                         key_restate = new_key;
  63.                                                         key_status = _Key2_Down;
  64.                                                 }        break;
  65.                                         default:  key_status = _Idle;  break;       
  66.                                 }                               
  67.                         }        break;       
  68.                 case _Key1_Press:                                                                //按鍵為按下狀態(tài)時(shí),累計(jì)按下的時(shí)間
  69.                         {
  70.                                 switch(num)
  71.                                 {
  72.                                         case 1:
  73.                                                 {
  74.                                                         if(key_restate == new_key)
  75.                                                                 key_count++;
  76.                                                         else                                                       
  77.                                                                 key_status++;       
  78.                                                         if(key_restate == K_LED)
  79.                                                                 key_type = 1;
  80.                                                         else
  81.                                                                 key_type = 2;
  82.                                                 }        break;
  83.                                         case 2:
  84.                                                 {
  85.                                                         key_restate = new_key;
  86.                                                         key_status = _Key2_Down;
  87.                                                         key_type = 0;
  88.                                                         key_count = 0;
  89.                                                 }        break;
  90.                                         default:
  91.                                                 {
  92.                                                         key_status = _Idle;
  93.                                                         key_type = 0;
  94.                                                         key_count = 0;
  95.                                                 }  break;       
  96.                                 }       
  97.                         }        break;
  98.                 case _Key1_Up:                                                                        //按鍵放開后,根據(jù)保持時(shí)間來判斷是長按還是短按
  99.                         {
  100.                                 if(key_count < 100)
  101.                                 {
  102.                                         if(key_type == 1)
  103.                                                 key_return = _LED_Short_Press;
  104.                                         else
  105.                                                 key_return = _MIST_Short_Press;       
  106.                                 }
  107.                                 else
  108.                                         if(key_type == 1)
  109.                                                 key_return = _LED_Long_Press;
  110.                                         else
  111.                                                 key_return = _MIST_Long_Press;       
  112.                                 key_count = 0;
  113.                                 key_type = 0;
  114.                                 key_status = _Idle;
  115.                                 key_restate = new_key;
  116.                         }        break;
  117.                  case _Key2_Down:
  118.                          {
  119.                                  if(key_restate == new_key)
  120.                                         key_status++;
  121.                                 else                                                       
  122.                                         key_status = _Idle;                       
  123.                          }        break;
  124.                  case _Key2_Press:
  125.                          {
  126.                                  if(key_restate == new_key)
  127.                                          key_count++;
  128.                                  else
  129.                                          key_status++;       
  130.                          }        break;
  131.                   case _Key2_Up:
  132.                           {
  133.                                   if(key_count > 100)
  134.                                         key_return = _Double_Press;
  135.                                 key_count = 0;
  136.                                 key_type = 0;
  137.                                 key_status = _Idle;
  138.                                 key_restate = new_key;
  139.                           }        break;
  140.                 default: break;       
  141.         }       
  142.         return key_return;               
  143. }
復(fù)制代碼


回復(fù)

使用道具 舉報(bào)

ID:108573 發(fā)表于 2020-1-14 13:06 | 顯示全部樓層
好帖子,學(xué)習(xí)一下
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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