威海職業學院 孔憲青
三段式狀態機在單片機中的實現
威海職業學院 孔憲青
本文提供一種用于單片機的編程方法。通過介紹VHDL中的狀態機,本文陳述如何將其應用于單片機中,其闡述的方法是一種優化的實時處理方式,比順序編程更有效/更具實時性。
狀態機;單片機
對于PLD,編程時一般使用狀態機,這是一種行之有效的編程方法。狀態機是以事件行為為描述核心,并通過狀態機體現事件之間的轉移機制。由于PLD使用并行宏單元,因此事件都可描述為宏單元組,而事件的關聯使用開關門和線路實現,因此說狀態機是PLD器件中主要的編程方法。
有限狀態機在PLD的應用中有四種類型,分別是一段式、兩段式和三段式和多段式。其中多段式狀態機對條件描述比較繁瑣,而兩段式狀態機實際就是三段式的精簡。因此實際類型就是一段式和三段式兩種。其中一段狀態機用于描述和順序時間相關的控制進程,例如對于單總線器件ds1820的控制。但是一段式加深了宏單元深度和綜合難度。而標準的三段式狀態機對深度和綜合都較好。以米勒狀態機結構為例,見圖1。
圖1 米勒狀態機
在VHDL中的代碼如下:
代碼中有三個并行宏單元,相對于順序描述有更快的實時響應。因此,如果把上述結構使用在單片機上,使用類似的三段式狀態機會比單純的順序和中斷結構有更好的實時性。
單片機由于CPU在同一時間段內只能唯一執行一個任務,因此唯一的方式是把CPU運行時間分為若干時間段分段執行,類似于時鐘脈沖CLK。代價是使用一個定時器,定時中斷進行狀態改變。下面是一段電梯運行的狀態機,C代碼舉例如下:
上面代碼中,定時中斷服務程序不斷檢索條件并不斷改變狀態(使用枚舉量定義狀態量),使用switch對應VHDL中的進程,復現上圖中的“狀態改變寄存器邏輯”。同時,輸出再使用switch進行狀態輸出,并提供狀態改變的部分條件。這樣在一個定時中斷中就實現了一個狀態機,并把其他不同任務寫成狀態機的形式,放入定時中斷中,就可把順序的程序結構變為脈沖類型的偽并行邏輯。由于任務都在中斷中實現,因此實時性很強。
另外,以上單片機進行狀態轉移,檢索條件改變和輸出是最簡單的一種,不需要存儲上一次的狀態量。如果需要把狀態存儲并保存到下一次狀態到來,需要在定時器中斷進行保存。例如按鍵狀態機需要進行前后兩次按鍵狀態才能轉移狀態量,則類似于下面的代碼情況:
unsigned char past; //past和now是按鍵前后兩次狀態,不是狀態機狀態量
past=now; //按鍵三段式按鍵狀態機,狀態保存
if(key!=0xff)now=0; //由前后兩次狀態比較得到可用條件
else now=1; //條件可用于狀態轉移組合邏輯
這種模式應用在定時器多的單片機上更為有效。如果定時器有冗余,則可以開更多的定時器線程,每個線程填入多個狀態機,即可滿足運行復雜的實時處理情況。通過狀態機在單片機上應用,可以把程序結構寫成事件觸發狀態機,這種編程方式為一些任務重、實時強、邏輯復雜的情況提供了一種新的模式和參考。
孔憲青,男,1976年出生,山東省威海人,碩士,講師,研究方向:單片機應用。