狀態(tài)機基礎篇_第1頁
狀態(tài)機基礎篇_第2頁
狀態(tài)機基礎篇_第3頁
狀態(tài)機基礎篇_第4頁
狀態(tài)機基礎篇_第5頁
全文預覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

不用懷疑,單片機的萬能語言就是狀態(tài)機。還希望大家不要條件反射式的看到狀態(tài)機就

以為我要講什么VHDL的東西——狀態(tài)機是一種思維模式,是計算機理論的立足之本(不

相信請參考清華大學出版社的《自動機理論與應用》)——因此狀態(tài)機的實現(xiàn)與語言本

身關(guān)系并不是絕對的。本文要討論的狀態(tài)機,從實現(xiàn)方式上更類似于Java中常用的那種

思維模式,而與VHDL相去甚遠。

路要一步一步走,飯要一口一口吃,為了不把后來人嚇跑,狀態(tài)機理論中更多復雜的部

分,我會在以后專門寫文章討論,這里我先找一個切入點,從我常用的2種狀態(tài)機編寫

方式為大家慢慢展開。

首先,關(guān)于幾個問題,比如:什么地方用狀態(tài)機?狀態(tài)機究竟有幾種寫法?狀態(tài)機效率

到底高不高?是不是把簡單問題弄復雜了?這類問題統(tǒng)統(tǒng)不在本文討論之列,簡而言之

——誰用誰知道。其實,還不能簡單的就這么下了結(jié)論,套八股文而不求甚解的也大有

人在————因此我要說:關(guān)于狀態(tài)機的各種問題“誰思考誰實踐誰堅持誰知道”。

狀態(tài)機入門第一式:switch

case一線到底

要點:

用switch結(jié)構(gòu)配合一個狀態(tài)變量,通過修改狀態(tài)變量的值來切換狀態(tài)。

范例:

//!

定義狀態(tài)名稱與狀態(tài)值之間的關(guān)系,增加可讀性

#define

FSM_START

0x00

#define

FSM_STATE_A

0x01

#define

FSM_STATE_B

0x02

#define

FSM_RESET

0xFF

bool

fsm_example_A(

<</span>形參列表>

)

{

static

uint8_t

s_chFSMState

=

FSM_START;

//!<

定義狀態(tài)變量

switch

(

s_chFSMState

)

{

case

FSM_START:

//!

這里添加狀態(tài)機初始化代碼

s_chFSMState

=

FSM_STATE_A;

//!<

進入下一狀態(tài)

break;

case

FSM_STATE_A:

//!

這里添加狀態(tài)機A進入下一狀態(tài)的檢測代碼

if

(<</span>某某條件>)

{

//!

這里做一些進入下一狀態(tài)時要做的準備工作

s_chFSMState

=

FSM_STATE_B;

//!<

進入下一狀態(tài)

}

break;

case

FSM_STATE_B:

//!

這里添加狀態(tài)機A進入下一狀態(tài)的檢測代碼

if

(<</span>某某條件>)

{

//!

這里做一些進入下一狀態(tài)時要做的準備工作

s_chFSMState

=

FSM_STATE_A;

//!<

進入下一狀態(tài)

}

else

if

(<</span>某某條件>)

{

}

else

if

(<</span>某某條件>)

{

}

else

{

}

break;

case

FSM_STOP:

case

FSM_RESET:

default:

//!

這里添加狀態(tài)機復位相關(guān)的代碼

chFSMState

=

FSM_START;

//!<

狀態(tài)機復位

//!

返回false表示狀態(tài)機已經(jīng)不需要繼續(xù)運行了

return

false;

}

//!

返回true表示狀態(tài)機正在運行

return

true;

}

總結(jié):

從范例可知,這種狀態(tài)機就是一根筋……并不是說他走不出什么分支來,而

是說通常他沒有辦法讓多個狀態(tài)同時處于激活狀態(tài)。

狀態(tài)機入門第二式:if

判斷變化無窮

要點:

用if

else…else

if結(jié)構(gòu)的組合來描述狀態(tài)流程圖。

什么是狀態(tài)流程圖?我不想多解釋,因為就那么個簡單的東西,說多了反而神秘兮兮的。

狀態(tài)流程圖你可以簡單粗暴的認為,他就是流程圖,等你用得多了,你就漸漸明白為啥

多了“狀態(tài)”二字;如果你后來或者先前學過狀態(tài)圖,那么很快你就會明白狀態(tài)流程圖

比狀態(tài)圖“高級”了多少。

1、

不管怎么說,你可以先為你要處理的事物畫一個流程圖。如果流程圖都不會畫,就

不用湊熱鬧了。

2、

接下來,把流程圖上每一個方框或者判斷筐都“簡單粗暴”地看成一個狀態(tài)。

3、

將每一個狀態(tài)用if結(jié)構(gòu)表示出來

if

(<</span>狀態(tài)標志>)

{

//!

狀態(tài)代碼

}

4、

自己看著辦,合并多余的狀態(tài),優(yōu)化優(yōu)化代碼。

范例:

//!

首先將布爾量的狀態(tài)標志壓縮在一個字節(jié)里面以節(jié)省內(nèi)存開支

typedef

union

{

uint8_t

Value;

uint8_t

Byte;

struct

{

unsigned

BIT0:1;

unsigned

BIT1:1;

unsigned

BIT2:1;

unsigned

BIT3:1;

unsigned

BIT4:1;

unsigned

BIT5:1;

unsigned

BIT6:1;

unsigned

BIT7:1;

}

Bits;

}byte_t;

#define

FSM_ACTION_FLAG

s_tbState.Bits

#define

FSM_STOP_ALL_ACTIONS()

do

{s_tbState.Value

=

0;}while(0)

#define

FSM_START

(0

==

s_tbState.Value)

#define

FSM_STATE_A

FSM_ACTION_FLAG.BIT0

#define

FSM_STATE_B

FSM_ACTION_FLAG.BIT1

#define

FSM_STATE_H

FSM_ACTION_FLAG.BIT7

bool

fsm_example_B(

<</span>形參列表>

)

{

static

byte_t

s_tbState

=

{0};

//!<

定義狀態(tài)變量

if

(FSM_START)

{

//!<

起始狀態(tài)

//!

這里放置狀態(tài)機初始化的代碼

FSM_STATE_A

=

true;

//!<

進入狀態(tài)B,start裝臺自動結(jié)束

}

if

(FSM_STATE_A)

{

//!<

一個典型的簡單狀態(tài)

//!

這里放置狀態(tài)A的代碼或者

//!

這里放置某些條件以開啟別的狀態(tài)

if

(<</span>某些條件>)

{

//!

這里做一些“進入”下一個狀態(tài)之前的準備工作

FSM_STATE_B

=

true;

//!<

開啟下一個狀態(tài)

FSM_STATE_A

=

false;

//!<

結(jié)束當前狀態(tài)

}

}

if

(FSM_STATE_B)

{

//!<

一個典型的監(jiān)視狀態(tài)

//!

這里檢測某些條件

if

(<</span>某些條件>)

{

//!

這里做一些“開啟”某個狀態(tài)的準備工作

FSM_STATE_C

=

true;

//!<

開啟某一個狀態(tài)而不結(jié)束當前狀態(tài)

FSM_STATE_D

=

true;

//!<

你當然可以一次觸發(fā)多個狀態(tài)

}

else

if

(<</span>某些條件>)

{

//!

滿足某些條件以后關(guān)閉當前狀態(tài)

FSM_STATE_B

=

false;

}

}

if

(FSM_STATE_F)

{

//!<

一個典型的子狀態(tài)機調(diào)用

if

(!fsm_example_a(<</span>實參列表>))

{

//!<

等待子狀態(tài)機返回false

//!子狀態(tài)機運行完成,進入下一狀態(tài)

FSM_STATE_F

=

false;

//!<

結(jié)束當前狀態(tài)

FSM_STATE_x

=

true;

//!<

進入下一狀態(tài)x代表某個字母

}

}

if

(FSM_STATE_H)

{

//!<

一個典型的中止狀態(tài)

//!<

某些狀態(tài)機的操作,比如釋放某些資源

FSM_STOP_ALL_ACTIONS();

//!<

復位狀態(tài)機

return

false;

//!<

返回false表示狀態(tài)機結(jié)束

}

return

true;

//!<

返回true表示狀態(tài)機保持運行

}

總結(jié):

從范例可知,這種狀態(tài)機非常靈活,通過布爾變量的開啟和關(guān)閉,你可以自

由的控制某些狀態(tài)的開啟。同一時刻可能有多個狀態(tài)是激活的。這種結(jié)構(gòu)幾乎可以翻譯

任何流程圖。具體還有很多好處,可以在使用中體會。

狀態(tài)機入門第三式:狀態(tài)在心中,無態(tài)也變態(tài)

要點:

所有的函數(shù)都可以看作是狀態(tài)機,只不過普通的函數(shù)是一個只有單一狀態(tài)的

狀態(tài)機。如果函數(shù)有返回值,且這個返回值能表征至少兩種以上不同的狀態(tài)(比如返回

是一個指針,那么NULL和非NULL就是兩種狀態(tài);比如返回是一個布爾變量,那么true和

false就是兩種狀態(tài);比如返回的是一個整數(shù),并且整數(shù)的某

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論