状态机简介及其思路在单片机程序设计中的应用

发布者:SereneHarmony最新更新时间:2012-09-19 来源: 21ic 关键字:状态机  单片机程序设计  状态迁移表 手机看文章 扫描二维码
随时随地手机看文章

状态机的概念
状态机是软件编程中的一个重要概念。比这个概念更重要的是对它的灵活应用。在一个思路清晰而且高效的程序中,必然有状态机的身影浮现。


比如说一个按键命令解析程序,就可以被看做状态机:本来在A状态下,触发一个按键后切换到了B状态;再触发另一个键后切换到C状态,或者返回到A状态。这就是最简单的按键状态机例子。实际的按键解析程序会比这更复杂些,但这不影响我们对状态机的认识。


进一步看,击键动作本身也可以看做一个状态机。一个细小的击键动作包含了:释放、抖动、闭合、抖动和重新释放等状态。


同样,一个串行通信的时序(不管它是遵循何种协议,标准串口也好、I2C也好;也不管它是有线的、还是红外的、无线的)也都可以看做由一系列有限的状态构成。


显示扫描程序也是状态机;通信命令解析程序也是状态机;甚至连继电器的吸合/释放控制、发光管(LED)的亮/灭控制又何尝不是个状态机。


当我们打开思路,把状态机作为一种思想导入到程序中去时,就会找到解决问题的一条有效的捷径。有时候用状态机的思维去思考程序该干什么,比用控制流程的思维去思考,可能会更有效。这样一来状态机便有了更实际的功用。


程序其实就是状态机。


也许你还不理解上面这句话。请想想看,计算机的大厦不就是建立在“0”和“1”两个基本状态的地基之上么?

状态机的要素
状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳,主要是出于对状态机的内在因果关系的考虑。“现态”和“条件”是因,“动作”和“次态”是果。详解如下:


①现态:是指当前所处的状态。


②条件:又称为“事件”。当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。


③动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。


④次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。


如果我们进一步归纳,把“现态”和“次态”统一起来,而把“动作”忽略(降格处理),则只剩下两个最关键的要素,即:状态、迁移条件。


状态机的表示方法有许多种,我们可以用文字、图形或表格的形式来表示一个状态机。


纯粹用文字描述是很低效的,所以就不介绍了。接下来先介绍图形的方式。

状态迁移图(STD)
状态迁移图(STD),是一种描述系统的状态、以及相互转化关系的图形方式。状态迁移图的画法有许多种,不过一般都大同小异。我们结合一个例子来说明一下它的画法,如图1所示。

图1 状态迁移图


①状态框:用方框表示状态,包括所谓的“现态”和“次态”。

②条件及迁移箭头:用箭头表示状态迁移的方向,并在该箭头上标注触发条件。


③节点圆圈:当多个箭头指向一个状态时,可以用节点符号(小圆圈)连接汇总。


④动作框:用椭圆框表示。


⑤附加条件判断框:用六角菱形框表示。


状态迁移图和我们常见的流程图相比有着本质的区别,具体体现为:在流程图中,箭头代表了程序PC指针的跳转;而在状态迁移图中,箭头代表的是状态的改变。


我们会发现,这种状态迁移图比普通程序流程图更简练、直观、易懂。这正是我们需要达到的目的。

状态迁移表
除了状态迁移图,我们还可以用表格的形式来表示状态之间的关系。这种表一般称为状态迁移表。


表1就是前面介绍的那张状态迁移图的另一种描述形式。

表1 状态迁移表


①采用表格方式来描述状态机,优点是可容纳更多的文字信息。例如,我们不但可以在状态迁移表中描述状态的迁移关系,还可以把每个状态的特征描述也包含在内。


②如果表格内容较多,过于臃肿不利于阅读,我们也可以将状态迁移表进行拆分。经过拆分后的表格根据其具体内容,表格名称也有所变化。


③比如,我们可以把状态特征和迁移关系分开列表。被单独拆分出来的描述状态特征的表格,也可以称为“状态真值表”。这其中比较常见的就是把每个状态的显示内容单独列表。这种描述每个状态显示内容的表称之为“显示真值表”。同样,我们把单独表述基于按键的状态迁移表称为“按键功能真值表”。另外,如果每一个状态包含的信息量过多,我们也可以把每个状态单独列表。


④由此可见,状态迁移表作为状态迁移图的有益补充,它的表现形式是灵活的。[page]


⑤状态迁移表优点是信息涵盖面大,缺点是视觉上不够直观,因此它并不能取代状态迁移图。比较理想的是将图形和表格结合应用。用图形展现宏观,用表格说明细节。二者互为参照,相得益彰。

用状态机思路实现一个时钟程序
接下来,我将就状态机的应用,结合流程图、状态迁移图和状态迁移,举一个实际例子。下面这张图是一个时钟程序的状态迁移图,如图2所示。

图2 时钟程序状态迁移图


把这张图稍做归纳,就可以得到它的另一种表现形式——状态迁移表,如表2所示。

表2 时钟程序状态迁移表

状态机应用的注意事项
基于状态机的程序调度机制,其应用的难点并不在于对状态机概念的理解,而在于对系统工作状态的合理划分。


初学者往往会把某个“程序动作”当作是一种“状态”来处理。我称之为“伪态”。那么如何区分“动作”和“状态”。本匠人的心得是看二者的本质:“动作”是不稳定的,即使没有条件的触发,“动作”一旦执行完毕就结束了;而“状态”是相对稳定的,如果没有外部条件的触发,一个状态会一直持续下去。


初学者的另一种比较致命的错误,就是在状态划分时漏掉一些状态。我称之为“漏态”。


“伪态”和“漏态”这两种错误的存在,将会导致程序结构的涣散。因此要特别小心避免。

更复杂的状态机
前面介绍的是一种简单的状态结构。它只有一级,并且只有一维,如图3所示。

图3  线性状态机结构


如果有必要,我们可以建立更复杂的状态机模型。


1 多级状态结构
状态机可以是多级的。在分层的多级状态机系统里面,一个“父状态”下可以划分多个“子状态”,这些子状态共同拥有上级父状态的某些共性,同时又各自拥有自己的一些个性。


在某些状态下,还可以进一步划分子状态。比如,我们可以把前面的时钟例子修改如下:
把所有和时钟功能有关的状态,合并成1个一级状态。在这个状态下,又可以划分出3个二级子状态,分别为显示时间、设置小时、设置分钟;


同样,我们也可以把所有和闹钟功能有关的状态,合并成1个一级状态。在这个状态下,再划分出4个二级子状态,分别为显示闹钟、设置“时”、设置“分”、设置鸣叫时间。


我们需要用另一个状态变量(寄存器)来表示这些子状态。


子状态下面当然还可以有更低一级的孙状态(子子孙孙无穷尽也),从而将整个状态体系变成了树状多级状态结构,如图4所示。

图4 树状多级状态结构


2 多维状态结构
状态结构也可以是多维的。从不同的角度对系统进行状态的划分,这些状态的某些特性是交叉的。比如,在按照按键和显示划分状态的同时,又按照系统的工作进程做出另一种状态划分。这两种状态划分同时存在,相互交叉,从而构成了二维的状态结构空间。


举一个这方面的例子,如:空调遥控器,如图5所示。

图5 多维状态机结构


同样,我们也可以构建三维、四维甚至更多维的状态结构。每一维的状态都需要用一个状态变量(寄存器)来表示。


无论多级状态结构和多维状态结构看上去多么迷人,匠人的忠告是:我们依然要尽可能地简化状态结构,能用单级、单维的结构,就不要给自己找事,去玩那噩梦般的复杂结构。


简单的才是最有效的。

结束语
对状态机的理解需要一个由浅入深的过程。这个过程应该是与实践应用和具体案例思考相结合的。当一种良好的思路成为设计的习惯,它就能给设计者带来回报。愿这篇手记里介绍的基于状态机的编程思路能给新手们带来一些启迪,帮助大家找到“程序设计”的感觉。

关键字:状态机  单片机程序设计  状态迁移表 引用地址:状态机简介及其思路在单片机程序设计中的应用

上一篇:电脑与单片机串口通信—猜数字
下一篇:基于单片机的智能开发平台解决方案介绍

推荐阅读最新更新时间:2024-03-16 13:08

MCS-51单片机驱动步进电机的程序设计
  1.实验设计 定时器1于方式1,16位,10ms中断一次 40H 10ms计数单元 41H 秒计数单元 42H 分计数单元 43H 时计数单元 定时方式1为10MS:THX=0ECH,TLX=78H 方式0为10MS: THX=63H,TLX=18H 步进电机驱动实验 定时中断程序 正转后反转,显示计数值 步进电机按三相六拍的工作方式运动 X轴 C B A P1.2 P1.1 P1.0 用键盘上方的发光二极管(3FH)对应指示: D2 D1 D0 正转:A-AB-B-BC-C-CA-A 反转:A-CA-C-BC-B-
[单片机]
PIC单片机C语言程序设计(15)
  本文是讲座《单片机C 语言程序设计》的结束篇,为了帮助大家更好地掌握前面所学的知识,我们将归纳性地介绍初学者用C 语言编辑PIC 单片机实用程序时应具备的思维方法和基本知识,并通过下面的实例进行一次小结,以期对大家今后深入学习PIC 单片机C 语言程序设计有所帮助。   十六、PIC单片机C语言程序的组成   一个完整的PIC 单片机C 语言源程序应包括:包含头文件、变量定义、常量说明、函数定义、主函数main( )、若干个其他功能函数、各种功能C 语句,以及已定义的函数和函数体、注释等部分组成。   说明:对PIC 单片机中级或中级以下的产品,其头文件是#include pic.h 和#include pic1687x.
[单片机]
PIC<font color='red'>单片机</font>C语言<font color='red'>程序设计</font>(15)
51单片机状态机消抖代码
#include enum State {Init, Press, Free}; //定义按键状态的枚举类型 enum State Key_State; //按键状态 sbit Key1 = P2^4; sbit Key2 = P2^5; sbit Key3 = P2^6; sbit Key4 = P2^7; void Delay_ms(unsigned int x) { int i,j; for(i=0; i 110; i++) for(j=0; j ; } //============================================================================
[单片机]
AT89C51单片机频率计的C源程序设计
本文是基于AT89C51单片机的频率计的C源程序。该频率计主要实现的功能有如下几个: 1. 测试功能 它表明数字频率计所具备的全部测试功能,一般包括测频,周期,累计脉冲数,频率比,时间间隔及自较等功能。 2. 测量范围 它说明不同功能的有效测量范围。如测频率时,测量范围是数字频率计处于正常工作条件下,被测信号的频率范围,一般用频率的上,下限值表示,低端大部分从10Hz开始;高端因不同的频率计而异。因此高端频率是确定低,中,高速计数器的依据。在测量周期时,测量范围常用周期的最大值,最小值表示。 3. 输入特性 数字频率计一般有2~3个输入通道,测试不同项目时,被测信号可经不同的通道输入仪器。输入特性是表明数字式频率计于被
[单片机]
基于Verilog的顺序状态逻辑FSM设计与仿真
  硬件描述语言Verilog为数字系统设计人员提供了一种在广泛抽象层次上描述数字系统的方式,同时,为计算机辅助设计工具在工程设计中的应用提供了方法。该语言支持早期的行为结构设计的概念,以及其后层次化结构设计的实现。这在设计过程中,进行逻辑结构部分设计时可以将行为结构和层次化结构混合起来;为确认正确性还可以将描述进行模拟,并提供一些用于自动设计的综合工具。因而Verilog语言为设计者进行大型复杂数字系统的设计提供了途径。超大规模集成电路设计的典型流程如图1所示。   本文将以顺序状态逻辑有限状态机的设计为例介绍用Verilog语言设计数字电路的一般过程。    1 设计规范与设计构思   电子设计工程师在设计过程中不可避免
[工业控制]
基于Verilog的顺序<font color='red'>状态</font>逻辑FSM设计与仿真
FPGA/CPLD状态机的稳定性设计
  随着大规模和超大规模FPGA/CPLD器件的诞生和发展,以HDL(硬件描述语言)为工具、FPGA/CPLD器件为载体的EDA技术的应用越来越广泛.从小型电子系统到大规模SOC(Systemonachip)设计,已经无处不在.在FPGA/CPLD设计中,状态机是最典型、应用最广泛的时序电路模块,如何设计一个稳定可靠的状态机是我们必须面对的问题.    1、状态机的特点和常见问题   标准状态机分为摩尔(Moore)状态机和米立(Mealy)状态机两类.Moore状态机的输出仅与当前状态值有关,且只在时钟边沿到来时才会有状态变化.Mealy状态机的输出不仅与当前状态值有关,而且与当前输入值有关,这一特点使其控制和输出更加灵活,
[嵌入式]
FPGA/CPLD<font color='red'>状态机</font>的稳定性设计
MCS51单片机程序设计时堆栈的计算方法解析
用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己的特点。本文介绍的是Cx51程序设计时堆栈的计算方法。 1.堆栈的溢出问题。MCS51系列单片机将堆栈设置在片内RAM中,由于片内RAM资源有限,堆栈区的范围也是有限的。堆栈区留得太大,会减少其他数据的存放空间,留得太少则很容易溢出。所谓堆栈溢出,是指在堆栈区已经满了的时候还要进行新的压栈操作,这时只好将压栈的内容存放到非堆栈区的特殊功能寄存器(SFR)中或者堆栈外的数据区中。特殊功能寄存器的内容
[单片机]
MCS51<font color='red'>单片机</font><font color='red'>程序设计</font>时堆栈的计算方法解析
LabVIEW程序设计模式(三)—消息队列型状态机模式
针对基本状态机模式的第(1~3)个问题,需要对模式进行改进。本节将一一分析这些问题对应的解决方案,并最终形成一种新的状态机模式 消息队列型状态机模式。 状态的分类不清晰。 这是一个涉及各个状态分类管理的问题,是一个组织问题。我们可以做一个类比,在一个书桌上有许多种类的书籍(通信、计算机、机械、法律等),这些书都摆放在书桌上很整齐。但是我们在寻找一本书时并不会觉得很迅速和随意,因为书籍的摆放是无序的,每次寻找书籍我们不得不从第一本开始浏览直至找到我们想要的书籍。或许可以做一些改变,我们设置一些书立,将不同种类的书使用书立分开。并且在书立上标明这些书籍表示的种类。这样我们在寻找某一种书籍时就不需要从第一本书开始寻找了,只需要找到对
[测试测量]
LabVIEW<font color='red'>程序设计</font>模式(三)—消息队列型<font color='red'>状态机</font>模式
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved