有限狀態機概念
有限狀態機是一種概念思想,把複雜的控制邏輯分解成有限個穩定狀態,組成閉環系統,通過事件觸發,讓狀態機按設定的順序處理事務。單片機C語言的狀態機編程,是利用條件選擇語句(switch、case或者if、else)切換狀態,通過改變狀態機狀態,讓程序按設定的順序執行。
有限狀態機由有限的狀態和相互之間的轉移構成,在任何時候只能處於給定數目的狀態中的一個。當接收到一個輸入事件時,狀態機產生一個輸出,同時也可能伴隨著狀態的轉移。狀態機的原理如下:在當前狀態下,發生某個事件後轉移到下一個狀態,然後決定執行的功能動作。可參考如下示意圖:
應用舉例
要想使用狀態機思想進行編程,需要將任務分解成有限個穩定狀態。
這裡以常見的按鍵動作進行舉例說明:
上圖為按鍵典型的動作圖,可以分解為四個狀態,分別為:狀態1 = 按鍵彈起、狀態2 = 前沿抖動、狀態3 = 按鍵按下、狀態4 = 後沿抖動。有限狀態機的C代碼實現如下:
if (定時器 >= 10ms) //10ms是典型消抖時間
{
switch (按鍵狀態)
{
case 按鍵彈起狀態:if (IO讀取為低電平) 按鍵狀態=前沿抖動; break;
case 前沿抖動狀態:if (IO讀取為低電平) 按鍵狀態=按鍵按下; break;
case 按鍵按下狀態:if (IO讀取為高電平) 按鍵狀態=後沿抖動; break;
case 後沿抖動狀態:if (IO讀取為高電平) 按鍵狀態=按鍵彈起; break;
default:按鍵狀態=按鍵彈起;
}
}
狀態機編程建議
巧妙的使用結構體和枚舉一方面可以便於擴展和維護狀態機的狀態和事件,另一方面可提高程序的可讀性。假設有3種狀態(狀態數可以隨意增加),狀態枚舉如下:
<code>typedef
enum
{ state_1=1
, state_2, state_3 }State;/<code>
假設有5個事件(也可以隨意增加),事件枚舉如下:
<code>typedef
enum
{ event_1=1
, event_2, event_3, event_4, event_5 }Event;/<code>
定義一個結構體描述如下:
<code>typedef
struct
{ State curState; Event eventId; State nextState; Action action; }StateEvent;/<code>
根據具體的應用場景調整State和Event,並賦予相應的動作功能,整體的基本流程如下:當前狀態->有事件觸發->跳到下一個狀態->具體的動作功能
總結
狀態機應用很廣泛,也可以鍛鍊邏輯思維,LoRa消息推送也常採用狀態機的思想, 實際上狀態機涉及的知識點很多,本篇文章只是簡要的介紹了下單片機C語言的狀態機編程思想,在日後的開發設計中,需要不斷的總結經驗並靈活應用。