造价通

反馈
取消

热门搜词

造价通

取消 发送 反馈意见

状态机两种写法

2022/07/1681 作者:佚名
导读:思想广泛应用于硬件控制电路设计,也是软件上常用的一种处理方法(软 件上称为FMM--有限消息机)。它把复杂的控制逻辑分解成有限个稳定状态,在每个状态上判断事件,变连续处理为离散数字处理,符合计算机的工作特点。同时,因为有限状态机具有有限个状态,所以可以在实际的工程上实现。但这并不意味着其只能进行有限次的处理,相反,有限状态机是闭环系统,有限无穷,可以用有限的状态,处理无穷的事务。 有限状态机的工作

思想广泛应用于硬件控制电路设计,也是软件上常用的一种处理方法(软 件上称为FMM--有限消息机)。它把复杂的控制逻辑分解成有限个稳定状态,在每个状态上判断事件,变连续处理为离散数字处理,符合计算机的工作特点。同时,因为有限状态机具有有限个状态,所以可以在实际的工程上实现。但这并不意味着其只能进行有限次的处理,相反,有限状态机是闭环系统,有限无穷,可以用有限的状态,处理无穷的事务。

有限状态机的工作原理如图1所示,发生事件(event)后,根据当前状态(cur_state) ,决定执行的动作(action),并设置下一个状态号(nxt_state)。

表1 图2状态机实例的二维表格表示(动作/下一状态)

图2为一个状态机实例的状态转移图,它的含义是:

在s0状态,如果发生e0事件,那么就执行a0动作,并保持状态不变;

如果发生e1事件,那么就执行a1动作,并将状态转移到s1态;

如果发生e2事件,那么就执行a2动作,并将状态转移到s2态;

在s1状态,如果发生e2事件,那么就执行a2动作,并将状态转移到s2态;

在s2状态,如果发生e0事件,那么就执行a0动作,并将状态转移到s0态;

有限状态机不仅能够用状态转移图表示,还可以用二维的表格代表。一般将当前状 态号写在横行上,将事件写在纵列上,如表1所示。其中“--”表示空(不执行动作,也 不进行状态转移),“an/sn”表示执行动作an,同时将下一状态设置为sn。表1和图2表示 的含义是完全相同的。

观察表1可知,状态机可以用两种方法实现:竖着写(在状态中判断事件)和横着写( 在事件中判断状态)。这两种实现在本质上是完全等效的,但在实际操作中,效果却截然 不同。

状态机竖着写C代码片段

cur_state = nxt_state;

switch(cur_state){ //在当前状态中判断事件

case s0: //在s0状态

if(e0_event){ //如果发生e0事件,那么就执行a0动作,

并保持状态不变;

执行a0动作;

//nxt_state = s0; //因为状态号是自身,所以可以删除此句

,以提高运行速度。

}

else if(e1_event){ //如果发生e1事件,那么就执行a1动作,

并将状态转移到s1态;

执行a1动作;

nxt_state = s1;

}

else if(e2_event){ //如果发生e2事件,那么就执行a2动作,

并将状态转移到s2态;

执行a2动作;

nxt_state = s2;

}

break;

case s1: //在s1状态

if(e2_event){ //如果发生e2事件,那么就执行a2动作,

并将状态转移到s2态;

执行a2动作;

nxt_state = s2;

}

break;

case s2: //在s2状态

if(e0_event){ //如果发生e0事件,那么就执行a0动作,

并将状态转移到s0态;

执行a0动作;

nxt_state = s0;

}

}

状态机横着写C代码片段

//e0事件发生时,执行的函数

void e0_event_function(int * nxt_state)

{

int cur_state;

cur_state = *nxt_state;

switch(cur_state){

case s0: //观察表1,在e0事件发生时,s1处为空

case s2:

执行a0动作;

*nxt_state = s0;

}

}

//e1事件发生时,执行的函数

void e1_event_function(int * nxt_state)

{

int cur_state;

cur_state = *nxt_state;

switch(cur_state){

case s0: //观察表1,在e1事件发生时,s1和s2处为

执行a1动作;

*nxt_state = s1;

}

}

//e2事件发生时,执行的函数

void e2_event_function(int * nxt_state)

{

int cur_state;

cur_state = *nxt_state;

switch(cur_state){

case s0: //观察表1,在e2事件发生时,s2处为空

case s1:

执行a2动作;

*nxt_state = s2;

}

}

*文章为作者独立观点,不代表造价通立场,除来源是“造价通”外。
关注微信公众号造价通(zjtcn_Largedata),获取建设行业第一手资讯

热门推荐

相关阅读