<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 單片機之狀態(tài)機淺談

單片機之狀態(tài)機淺談

作者: 時(shí)間:2019-05-28 來(lái)源:網(wǎng)絡(luò ) 收藏

說(shuō)到編程,不得不說(shuō)到,做為軟件編程的主要架構已經(jīng)在各種語(yǔ)言中應用,當然包括C語(yǔ)言,在一個(gè)思路清晰而且高效的程序中,必然有的身影浮現。靈活的應用狀態(tài)機不僅是程序更高效,而且可讀性和擴展性也很好。狀態(tài)無(wú)處不在,狀態(tài)中有狀態(tài),只要掌握了這種思維,讓它成為您編程中的一種習慣,相信您會(huì )受益匪淺。

本文引用地址:http://dyxdggzs.com/article/201905/400945.htm

狀態(tài)機可歸納為4個(gè)要素,即現態(tài)、條件、動(dòng)作、次態(tài)。這樣的歸納,主要是出于對狀態(tài)機的內在因果聯(lián)系的考慮?!艾F態(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)?!按螒B(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)機的表示

狀態(tài)機的表示要領(lǐng)有許多種,我們可以用文字、圖形或表格的形式來(lái)表示一個(gè)狀態(tài)機。

舉個(gè)簡(jiǎn)單的例子:就按鍵處理來(lái)說(shuō),擊鍵動(dòng)作本身也可以看做一個(gè)狀態(tài)機。一個(gè)細小的擊鍵動(dòng)作包含了:釋放、抖動(dòng)、閉合、抖動(dòng)和重新釋放等狀態(tài)。

當我們打開(kāi)思路,把狀態(tài)機作為一種思想導入到程序中去時(shí),就會(huì )找到處理疑問(wèn)的一條有效的捷徑。有時(shí)候用狀態(tài)機的思維去思考程序該干什么,比用控制流程的思維去思考,可能會(huì )更有效。這樣一來(lái)狀態(tài)機便有了更實(shí)際的功用。廢話(huà)不多說(shuō),實(shí)踐才是檢驗真理的唯一標準。

幾種狀態(tài)機介紹

也許有人覺(jué)得狀態(tài)機把問(wèn)題復雜化了,其實(shí)做過(guò)軟件設計的人無(wú)形之中已經(jīng)在用狀態(tài)機,下面就總結介紹幾種狀態(tài)機。

1、switch case結構狀態(tài)機

switch( )

case1:

if(not反復執行狀態(tài)1)

進(jìn)入1狀態(tài)前要做的準備

進(jìn)入1狀態(tài)的過(guò)程

if(not反復執行狀態(tài)1)

離開(kāi)狀態(tài)1的過(guò)程

case2:

但這種方式不能很有效預定義所有的狀態(tài),也不能把這些狀態(tài)之間的切換過(guò)程合理的定義出來(lái),“狀態(tài)”本身沒(méi)有一個(gè)合理的定義,幾乎是一種面向過(guò)程的方式,只過(guò)這種方式足夠簡(jiǎn)單,也最容易讓人接受,缺點(diǎn)就沒(méi)有“狀態(tài)”的定義和指派功能,導致?tīng)顟B(tài)的混亂,出現狀態(tài)處理重復代碼,甚至處理不一致的問(wèn)題,按照OO的觀(guān)念,狀態(tài)描述本來(lái)就應該是一種實(shí)體。

2、ifelse語(yǔ)句結構狀態(tài)機

這種狀態(tài)機相對靈活一點(diǎn),但對于一些大的項目,系統軟件設計會(huì )相對復雜。

3、消息觸發(fā)狀態(tài)機

該類(lèi)型的狀態(tài)機實(shí)現方式也是很多的,形態(tài)多樣,但萬(wàn)變不離其宗的就是狀態(tài)機的4要素及現態(tài)、條件、動(dòng)作、次態(tài)。

原理:一旦有消息觸發(fā),系統服務(wù)函數立即尋找所在狀態(tài)的消息與消息處理函數對,找到后執行消息處理函數

步驟:

(1)添加消息與消息映射

BEGIN_MESSAGE_ MAP(Name,Count) :狀態(tài)機名,消息數

ADD_NEW_MSG_ITEM (Msg,OnMsg) :消息與消息處理函數

END_MESSAGE_MAP:結束

(2)在這里注冊

BEGIN_Register_Task:頭

...

ADD_Register_Task(Name,Count):狀態(tài)機名,消息數

...

END_Register_Task:尾

(3)劃分電子秤狀態(tài),完成以上步驟后,完成OnMsg消息處理函數。

Void OnMsg(void)

{

}

說(shuō)明:以上用宏完成,具體宏是如下定義:

#defineBEGIN_MESSAGE_MAP(Name,Count)constMSG_NODE_TYP MSG_node_Array_##Name[(Count)]={

#defineADD_NEW_MSG_ITEM(Msg,OnMsg){Msg,OnMsg},

#define END_MESSAGE_MAP };

#define BEGIN_Register_Task const MSG_MAP TaskMap[TotalTask]={

#defineADD_Register_Task(Name,Count) {(MSG_NODE_TYP*)MSG_node_Array_##Name,Count},

#define END_Register_Task };

從以上代碼可知:添加消息與消息映射實(shí)際上是定義消息與消息處理函數對的數組,以形成一個(gè)表;注冊狀態(tài)機實(shí)際上是把所有消息對數組的入口定義成一個(gè)數組,以形成一個(gè)表。

消息如何被執行

1.分發(fā)消息

void Default_DisposeMessage(unsigned char *pMsg)

{

unsigned chari;

unsigned charcount=TaskMap[g_Status].cItemCount;

//定位到狀態(tài)表

for(i=0;i<count;i++)

{

if(*pMsg==TaskMap[g_Status].pMsgItems.msg)

//看能否匹配消息

{

TaskMap[g_Status].pMsgItems.pMsgFunc();

//找到就執行消息處理函數

return;

}

}

}

void DispatchMessage(unsigned char*pMsg)

{

if(*pMsg)

{

Default_DisposeMessage(pMsg);

}

}

2.核心函數:消息處理中心

void Message_Dispose_Central(void)

{

BYTE Msg;

while(GetMessage(&Msg)) //獲取消息

{

TranslateMessage(&Msg); //解釋消息

DispatchMessage(&Msg); //分發(fā)消息

}

}



關(guān)鍵詞: 單片機 狀態(tài)機

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>