狀態(tài)機簡(jiǎn)介及其思路在單片機程序設計中的應用
狀態(tài)機的概念
狀態(tài)機是軟件編程中的一個(gè)重要概念。比這個(gè)概念更重要的是對它的靈活應用。在一個(gè)思路清晰而且高效的程序中,必然有狀態(tài)機的身影浮現。
比如說(shuō)一個(gè)按鍵命令解析程序,就可以被看做狀態(tài)機:本來(lái)在A(yíng)狀態(tài)下,觸發(fā)一個(gè)按鍵后切換到了B狀態(tài);再觸發(fā)另一個(gè)鍵后切換到C狀態(tài),或者返回到A狀態(tài)。這就是最簡(jiǎn)單的按鍵狀態(tài)機例子。實(shí)際的按鍵解析程序會(huì )比這更復雜些,但這不影響我們對狀態(tài)機的認識。
進(jìn)一步看,擊鍵動(dòng)作本身也可以看做一個(gè)狀態(tài)機。一個(gè)細小的擊鍵動(dòng)作包含了:釋放、抖動(dòng)、閉合、抖動(dòng)和重新釋放等狀態(tài)。
同樣,一個(gè)串行通信的時(shí)序(不管它是遵循何種協(xié)議,標準串口也好、I2C也好;也不管它是有線(xiàn)的、還是紅外的、無(wú)線(xiàn)的)也都可以看做由一系列有限的狀態(tài)構成。
顯示掃描程序也是狀態(tài)機;通信命令解析程序也是狀態(tài)機;甚至連繼電器的吸合/釋放控制、發(fā)光管(LED)的亮/滅控制又何嘗不是個(gè)狀態(tài)機。
當我們打開(kāi)思路,把狀態(tài)機作為一種思想導入到程序中去時(shí),就會(huì )找到解決問(wèn)題的一條有效的捷徑。有時(shí)候用狀態(tài)機的思維去思考程序該干什么,比用控制流程的思維去思考,可能會(huì )更有效。這樣一來(lái)狀態(tài)機便有了更實(shí)際的功用。
程序其實(shí)就是狀態(tài)機。
也許你還不理解上面這句話(huà)。請想想看,計算機的大廈不就是建立在“0”和“1”兩個(gè)基本狀態(tài)的地基之上么?
狀態(tài)機的要素
狀態(tài)機可歸納為4個(gè)要素,即現態(tài)、條件、動(dòng)作、次態(tài)。這樣的歸納,主要是出于對狀態(tài)機的內在因果關(guān)系的考慮。“現態(tài)”和“條件”是因,“動(dòng)作”和“次態(tài)”是果。詳解如下:
①現態(tài):是指當前所處的狀態(tài)。
②條件:又稱(chēng)為“事件”。當一個(gè)條件被滿(mǎn)足,將會(huì )觸發(fā)一個(gè)動(dòng)作,或者執行一次狀態(tài)的遷移。
③動(dòng)作:條件滿(mǎn)足后執行的動(dòng)作。動(dòng)作執行完畢后,可以遷移到新的狀態(tài),也可以仍舊保持原狀態(tài)。動(dòng)作不是必需的,當條件滿(mǎn)足后,也可以不執行任何動(dòng)作,直接遷移到新?tīng)顟B(tài)。
④次態(tài):條件滿(mǎn)足后要遷往的新?tīng)顟B(tài)。“次態(tài)”是相對于“現態(tài)”而言的,“次態(tài)”一旦被激活,就轉變成新的“現態(tài)”了。
如果我們進(jìn)一步歸納,把“現態(tài)”和“次態(tài)”統一起來(lái),而把“動(dòng)作”忽略(降格處理),則只剩下兩個(gè)最關(guān)鍵的要素,即:狀態(tài)、遷移條件。
狀態(tài)機的表示方法有許多種,我們可以用文字、圖形或表格的形式來(lái)表示一個(gè)狀態(tài)機。
純粹用文字描述是很低效的,所以就不介紹了。接下來(lái)先介紹圖形的方式。
狀態(tài)遷移圖(STD)
狀態(tài)遷移圖(STD),是一種描述系統的狀態(tài)、以及相互轉化關(guān)系的圖形方式。狀態(tài)遷移圖的畫(huà)法有許多種,不過(guò)一般都大同小異。我們結合一個(gè)例子來(lái)說(shuō)明一下它的畫(huà)法,如圖1所示。
圖1 狀態(tài)遷移圖
①狀態(tài)框:用方框表示狀態(tài),包括所謂的“現態(tài)”和“次態(tài)”。
②條件及遷移箭頭:用箭頭表示狀態(tài)遷移的方向,并在該箭頭上標注觸發(fā)條件。
③節點(diǎn)圓圈:當多個(gè)箭頭指向一個(gè)狀態(tài)時(shí),可以用節點(diǎn)符號(小圓圈)連接匯總。
④動(dòng)作框:用橢圓框表示。
⑤附加條件判斷框:用六角菱形框表示。
狀態(tài)遷移圖和我們常見(jiàn)的流程圖相比有著(zhù)本質(zhì)的區別,具體體現為:在流程圖中,箭頭代表了程序PC指針的跳轉;而在狀態(tài)遷移圖中,箭頭代表的是狀態(tài)的改變。
我們會(huì )發(fā)現,這種狀態(tài)遷移圖比普通程序流程圖更簡(jiǎn)練、直觀(guān)、易懂。這正是我們需要達到的目的。
狀態(tài)遷移表
除了狀態(tài)遷移圖,我們還可以用表格的形式來(lái)表示狀態(tài)之間的關(guān)系。這種表一般稱(chēng)為狀態(tài)遷移表。
表1就是前面介紹的那張狀態(tài)遷移圖的另一種描述形式。
表1 狀態(tài)遷移表
①采用表格方式來(lái)描述狀態(tài)機,優(yōu)點(diǎn)是可容納更多的文字信息。例如,我們不但可以在狀態(tài)遷移表中描述狀態(tài)的遷移關(guān)系,還可以把每個(gè)狀態(tài)的特征描述也包含在內。
②如果表格內容較多,過(guò)于臃腫不利于閱讀,我們也可以將狀態(tài)遷移表進(jìn)行拆分。經(jīng)過(guò)拆分后的表格根據其具體內容,表格名稱(chēng)也有所變化。
③比如,我們可以把狀態(tài)特征和遷移關(guān)系分開(kāi)列表。被單獨拆分出來(lái)的描述狀態(tài)特征的表格,也可以稱(chēng)為“狀態(tài)真值表”。這其中比較常見(jiàn)的就是把每個(gè)狀態(tài)的顯示內容單獨列表。這種描述每個(gè)狀態(tài)顯示內容的表稱(chēng)之為“顯示真值表”。同樣,我們把單獨表述基于按鍵的狀態(tài)遷移表稱(chēng)為“按鍵功能真值表”。另外,如果每一個(gè)狀態(tài)包含的信息量過(guò)多,我們也可以把每個(gè)狀態(tài)單獨列表。
④由此可見(jiàn),狀態(tài)遷移表作為狀態(tài)遷移圖的有益補充,它的表現形式是靈活的。
⑤狀態(tài)遷移表優(yōu)點(diǎn)是信息涵蓋面大,缺點(diǎn)是視覺(jué)上不夠直觀(guān),因此它并不能取代狀態(tài)遷移圖。比較理想的是將圖形和表格結合應用。用圖形展現宏觀(guān),用表格說(shuō)明細節。二者互為參照,相得益彰。
用狀態(tài)機思路實(shí)現一個(gè)時(shí)鐘程序
接下來(lái),我將就狀態(tài)機的應用,結合流程圖、狀態(tài)遷移圖和狀態(tài)遷移,舉一個(gè)實(shí)際例子。下面這張圖是一個(gè)時(shí)鐘程序的狀態(tài)遷移圖,如圖2所示。
評論