状态机基础篇_第1页
状态机基础篇_第2页
状态机基础篇_第3页
状态机基础篇_第4页
状态机基础篇_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

不用怀疑,单片机的万能语言就是状态机。还希望大家不要条件反射式的看到状态机就

以为我要讲什么VHDL的东西——状态机是一种思维模式,是计算机理论的立足之本(不

相信请参考清华大学出版社的《自动机理论与应用》)——因此状态机的实现与语言本

身关系并不是绝对的。本文要讨论的状态机,从实现方式上更类似于Java中常用的那种

思维模式,而与VHDL相去甚远。

路要一步一步走,饭要一口一口吃,为了不把后来人吓跑,状态机理论中更多复杂的部

分,我会在以后专门写文章讨论,这里我先找一个切入点,从我常用的2种状态机编写

方式为大家慢慢展开。

首先,关于几个问题,比如:什么地方用状态机?状态机究竟有几种写法?状态机效率

到底高不高?是不是把简单问题弄复杂了?这类问题统统不在本文讨论之列,简而言之

——谁用谁知道。其实,还不能简单的就这么下了结论,套八股文而不求甚解的也大有

人在————因此我要说:关于状态机的各种问题“谁思考谁实践谁坚持谁知道”。

状态机入门第一式:switch

case一线到底

要点:

用switch结构配合一个状态变量,通过修改状态变量的值来切换状态。

范例:

//!

定义状态名称与状态值之间的关系,增加可读性

#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;

//!<

定义状态变量

switch

(

s_chFSMState

)

{

case

FSM_START:

//!

这里添加状态机初始化代码

s_chFSMState

=

FSM_STATE_A;

//!<

进入下一状态

break;

case

FSM_STATE_A:

//!

这里添加状态机A进入下一状态的检测代码

if

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

{

//!

这里做一些进入下一状态时要做的准备工作

s_chFSMState

=

FSM_STATE_B;

//!<

进入下一状态

}

break;

case

FSM_STATE_B:

//!

这里添加状态机A进入下一状态的检测代码

if

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

{

//!

这里做一些进入下一状态时要做的准备工作

s_chFSMState

=

FSM_STATE_A;

//!<

进入下一状态

}

else

if

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

{

}

else

if

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

{

}

else

{

}

break;

case

FSM_STOP:

case

FSM_RESET:

default:

//!

这里添加状态机复位相关的代码

chFSMState

=

FSM_START;

//!<

状态机复位

//!

返回false表示状态机已经不需要继续运行了

return

false;

}

//!

返回true表示状态机正在运行

return

true;

}

总结:

从范例可知,这种状态机就是一根筋……并不是说他走不出什么分支来,而

是说通常他没有办法让多个状态同时处于激活状态。

状态机入门第二式:if

判断变化无穷

要点:

用if

else…else

if结构的组合来描述状态流程图。

什么是状态流程图?我不想多解释,因为就那么个简单的东西,说多了反而神秘兮兮的。

状态流程图你可以简单粗暴的认为,他就是流程图,等你用得多了,你就渐渐明白为啥

多了“状态”二字;如果你后来或者先前学过状态图,那么很快你就会明白状态流程图

比状态图“高级”了多少。

1、

不管怎么说,你可以先为你要处理的事物画一个流程图。如果流程图都不会画,就

不用凑热闹了。

2、

接下来,把流程图上每一个方框或者判断筐都“简单粗暴”地看成一个状态。

3、

将每一个状态用if结构表示出来

if

(<</span>状态标志>)

{

//!

状态代码

}

4、

自己看着办,合并多余的状态,优化优化代码。

范例:

//!

首先将布尔量的状态标志压缩在一个字节里面以节省内存开支

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};

//!<

定义状态变量

if

(FSM_START)

{

//!<

起始状态

//!

这里放置状态机初始化的代码

FSM_STATE_A

=

true;

//!<

进入状态B,start装台自动结束

}

if

(FSM_STATE_A)

{

//!<

一个典型的简单状态

//!

这里放置状态A的代码或者

//!

这里放置某些条件以开启别的状态

if

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

{

//!

这里做一些“进入”下一个状态之前的准备工作

FSM_STATE_B

=

true;

//!<

开启下一个状态

FSM_STATE_A

=

false;

//!<

结束当前状态

}

}

if

(FSM_STATE_B)

{

//!<

一个典型的监视状态

//!

这里检测某些条件

if

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

{

//!

这里做一些“开启”某个状态的准备工作

FSM_STATE_C

=

true;

//!<

开启某一个状态而不结束当前状态

FSM_STATE_D

=

true;

//!<

你当然可以一次触发多个状态

}

else

if

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

{

//!

满足某些条件以后关闭当前状态

FSM_STATE_B

=

false;

}

}

if

(FSM_STATE_F)

{

//!<

一个典型的子状态机调用

if

(!fsm_example_a(<</span>实参列表>))

{

//!<

等待子状态机返回false

//!子状态机运行完成,进入下一状态

FSM_STATE_F

=

false;

//!<

结束当前状态

FSM_STATE_x

=

true;

//!<

进入下一状态x代表某个字母

}

}

if

(FSM_STATE_H)

{

//!<

一个典型的中止状态

//!<

某些状态机的操作,比如释放某些资源

FSM_STOP_ALL_ACTIONS();

//!<

复位状态机

return

false;

//!<

返回false表示状态机结束

}

return

true;

//!<

返回true表示状态机保持运行

}

总结:

从范例可知,这种状态机非常灵活,通过布尔变量的开启和关闭,你可以自

由的控制某些状态的开启。同一时刻可能有多个状态是激活的。这种结构几乎可以翻译

任何流程图。具体还有很多好处,可以在使用中体会。

状态机入门第三式:状态在心中,无态也变态

要点:

所有的函数都可以看作是状态机,只不过普通的函数是一个只有单一状态的

状态机。如果函数有返回值,且这个返回值能表征至少两种以上不同的状态(比如返回

是一个指针,那么NULL和非NULL就是两种状态;比如返回是一个布尔变量,那么true和

false就是两种状态;比如返回的是一个整数,并且整数的某

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论