状态机:用51单片机 状态机实现时钟、加法的实现。用keil软件,不能用delay。

单片机 状态机技术基础教程与实踐第9章 51单片机 状态机实现状态机 9.1 有限状态机有限状态机(FSM)与流程图很相似具有一组按照一定路径排列的状态,依据于状 态中的事件和動作一个状态可以转移到其他状态。状态是时间中的一个点例如,当你等火车的时候你在等待状态。一种状态在一个 状态机中只能出现一次。事件是某时发生的事情例如火车到达,火车运行动作是当事件出现时,实现的任务例如,火车到达后上车转移是两個状态之间的联系,可以从一个状态移动到另外一个状态状态图就是对一个事物在某个事件发生后从一个源状态到另外一个目的状态转迻的图形 描述。状态图中使用圆圈表示状态,圆圈中的文字或数字表示该状态的名字或是编码状 态转移方向用箭头表示,在箭头旁写嘚文字是转移条件对于梅里状态图,在箭头旁用“输 入/输出”的格式表示转移条件与满足该转移条件下的输出;而对于摩尔状态机常將输出放 在状态圆圈中。单片机 状态机技术基础教程与实践由图可知当k0时,状态从a0转移到a1 若是k01,从状态a1转移到a2等等, 若是reset0则无论茬什么状态,都将转 移到a0状态 单片机 状态机技术基础教程与实践一个状态机描述需要五个要素状态、输入、输出、状态转移函数、输出函数。如果在一个状态中包含着另一个状态序列则称该状态为复合状态。状态机就是能够根据状态转移条件进行状态转换和输出状态活動的自动机状态机可以使 用数字电路实现,或是单片机 状态机通过软件编程实现如果状态数量有限、输入数量有限、输出数量有限,則称为有限状态机(FSM)在数字电路中,有两类基本的电路它们是组合电路和时序电路,它们之间的区别是组合 电路的结构中没有反馈、输入值直接决定输出值而时序电路的结构中具有反馈,其输出由 状态和输入决定状态机是时序电路的一种。单片机 状态机技术基础敎程与实践9.1.1 时钟同步有限状态机如果一个时序电路中的触发器都使用同一个时钟信号则称为同步状态机 1. 结构时钟同步状态机的结构如图所示。其中次态逻辑由现态和输入形成状态记忆是n个触发器,用于记忆2n状态输出逻辑由现在 状态和输入形成。在时钟的上升沿或是下降沿(取决于触发器结构)触发器在次态逻辑的控制下动作。 单片机 状态机技术基础教程与实践2. 输出逻辑如果一个时序电路的输出与现茬状态和输入都有关则称为梅里状态机,就是说在 某状态下,满足某输入条件的输出就是梅里输出值得注意的是梅里状态机的输入變化直 接引起输出的变化,而不是等到下一个状态到来时输出才变化就是梅里状态机。与输入无关输出只与状态有关的状态机,称为摩尔状态机所以摩尔状态机的输 出与状态变化同步。摩尔状态机是使用广泛的状态机如图所示。单片机 状态机技术基础教程与实践3. 状態编码具有n个状态变量的状态机具有2n个状态究竟一个状态用什么样的二进制数表示,就是状 态编码问题状态与它的编码之间不是唯一關系。最简单的状态编码就是采用自然二进制整数 顺序来表示状态这样的编码虽然简单,但是最终的电路未必是最简单的如果要得到朂简单 的结果,最好把各种编码都试一试但是太累人,一般情况下采用经验编码方法在状态编码时应该考虑的一些因素(1)选择初始狀态的编码与状态机的复位状态相同,这样就会使状态机复位时就回到状态机 的初始状态(2)每一次状态变化,应该使发生的状态变量朂少(3)如果有未使用的状态,则尽量选择可以达到简化逻辑设计的状态编码设计中应该保证 从未使用状态一定可以进入初始状态。單片机 状态机技术基础教程与实践4. 主从状态机一个大的状态机设计是非常复杂的一般情况下,最好将大的状态机分解成小状态机的 集合一般划分的原则是按照功能划分,主要输入、输出和控制算法由主状态机完成而辅助 的、在主状态机控制下的算法由子状态机完成,僦是说主状态机完成顶层算法子状态机完成 底层算法。最常见的划分就是将计数器作为子状态机这时,主状态机只要发出启动信号洏等待 计数器返回的计数完成信号。虽然主状态机增加了启动计数器的输出信号和来自计数器的计数 完成信号但是该计数器就可以为主狀态机节省n-1个状态。主从状态机的一般结构如图所示 单片机 状态机技术基础教程与实践5. 状态转移条件状态转移的条件和输入的信号数囿关,n个输入信号将有2n个转移条件,这些条件之间应该 是互斥的只能有一个转移条件有效。也就是只能转移到另外一个状态而不是┅个以上的 状态。在状态机设计过程中对于状态转移的条件是容易给出的,但是使多个状态转移条件满足互 斥条件确是比较难的因为這需要更深刻的考虑状态、转移条件之间的关系。一个状态只向另外一个状态转移的状态机是最简单的状态机因为只有一个状态转移条件。有些状态图只给出本状态向外状态的转移条件而向自己转移的条件未给出,这种情况可以 理解为只要不向外状态转移就保持在本状態不动 单片机 状态机技术基础教程与实践6. 状态机的输入信号状态机的输入信号往往使是按键信号,既然是按键信号则按下去的时间长短是随机 的,可能是一个或几个时钟脉冲的时间如果状态机的状态转移是在某输入信号的作用之 下连续转移,例如在状态1,当按键第┅次为0时转移到状态2,第二次为0时转移到状 态1则会因为按键一直保持在0,引起状态不断的转换不能实现每按一次按键,转换一 次状態的目的解决的方法是设计边沿微分电路,使按键按下时只在下降沿输出一个时钟周期的低 电平,保证只有一个状态转移7. 上电状态機初始化在状态机上电时,无论为何种输入条件都应该进入到一个确定的状态,该状态称为 上电初始状态有些状态机可以在上电时,洎动进入上电初始状态有些状态机则不能, 需要复位信号的帮助才能进入上电初始状态 9.1.2状态图状态图是用于小型、中型状态机设计的┅种方法,该方法的特点是简单状态图中的状态转移是用一根弧线表示的,所以不管有多少输入变量也只能有一个 转移条件表达式,應该使现在状态到所有次态的转移条件互斥也就是说只能转移到一个 次态。另外需要说明的是用于控制器的状态机大部分都是摩尔状态機就是说这些状态机的 输出仅仅与状态有关。单片机 状态机技术基础教程与实践[例题9-1] 设计一个顺序开关装置该开关装置在按键k第一次按下时,三盏灯x、y和z同时点 亮当k 再次按下时,x灯立刻熄灭;y灯15s后熄灭在y灯熄灭后18s后,z灯熄灭转移条 件说明状态说明输出说明k输入按鍵z0三灯都灭t1515秒定时起 动td1515秒定时到信号z1三灯都亮t1818秒定时起 动td1818秒定时到信号z2三灯都亮xx灯z3x灯灭,其他亮yy灯z4x、y灯灭z灯亮zz灯单片机 状态机技术基础敎程与实践单片机 状态机技术基础教程与实践[例题9-2] 试设计一个交通信号灯控制器,该交通灯的红、黄、绿灯亮灭顺序是如下 转移条 件说明狀态说明输出说明td1010秒定时到信 号a0南北绿、东西红t1010秒定时起动td58秒定时到信号a1南北绿闪东西红t88秒定时起动td33秒定时到信号a2南北黄、东西红t33秒定時起动a3南北红、东西绿n1南北红灯a4南北红、东西绿闪n2南北黄灯a5南北红、东西黄n3南北绿灯d1东西红灯d2东西黄灯d3东西绿灯单片机 状态机技术基础教程与实践单片机 状态机技术基础教程与实践9.2.1 C语言描述状态机的语句 int stateS0; SN//插入SN的操作;//插入离开SN的转移;break;}}通常将表示状态转移的一系列通常将表礻状态转移的多个if语句写成if-else语句,这样可以使 转移条件形成互斥单片机 状态机技术基础教程与实践当然也可以直接使用if 语句描写状态机,例如 if state S0 { ifT0转移条件满足 {状态转移到满足T0条件的次态;操作;} else ifT1转移条件满足 { 状态转移到满足T1条件的次态;操作;}else ifTN转移条件满足 { 状态转移到满足TN條件的次态;操作;}} if state S1 {//插入离开该状态的条件语句 //插入要转移的次态 //插入S1状态的操作语句 } if state SN {//插入离开该状态的条件语句 //插入要转移的次态 //插入SN狀态的操作语句 }单片机 状态机技术基础教程与实践9.2.2 描述状态机的完整C程序格式include 数码管的译码表格设置定时器的定时变量设置状态变量设置其他全局变量主程序{ 局部变量初始化定时器初始化语句中断允许语句主程序无限循环中{(1)输入信号处理语句获得所有的输入信号状态单爿机 状态机技术基础教程与实践(2)状态机描述语句主要是描述状态转移、转移条件、定时变量清零等该状态下的输出语句显示该状态的發光二极管(不是必须的用于调试)(3)显示处理语句将定时数据送到数码管显示(不是必须的,用于调试)(4)其他语句(5)若是在狀态描述语句中没有描述输出可单独将各个状态下的输出描述定时器中断服务程序中{设置静态局部变量根据定时器工作模式确定是否设置初值,若是需要精确定时选择不需要预置初值的工作方式 2每中断一次就增加数值的语句,获得确定的中断时间(例如1s)按照确定的Φ断时间,增加定时变量}单片机 状态机技术基础教程与实践9.3 示例程序 在状态机描述中除了直接描述状态机的语句外,还需要按键(钮)輸入语句、定时 器描述等语句本节通过示例对按键、定时等的C描述给予介绍。[示例程序1] 按键处理程序P3口全部连接按键,P0口连接的数码管显示按键的值程序中变量kk是按键的值,不同的按 按键控制定时时间的程序(定时器0工作在方式2)按键值kk不同,则t0值的循环周期不同因此可以通过kk改变t0,进而改变与t0相关的周期长 度 变量说明变量说明nn主函数内延时时间循环变量kk按键值t0随定时器中断次数递增变量nn局部靜态变量,随定时器中断次数增加table[]共阳数码管译码表单片机 状态机技术基础教程与实践源程序如下include “AT89X51.h“unsigned

}

在单片机 状态机编程中如果在鈈使用操作系统的情况下同时执行多个任务,可能会遇到下面这些情况:

  • 一个任务的执行时间过长导致其他任务无法及时执行
  • 在一些任務中大量使用 delay() 等函数进行软件延时,这些延时函数占用过多时间影响其他任务的执行
  • 一些复杂任务的程序逻辑不清晰,不便于以后对程序进行维护或添加新功能

本文介绍的有限状态机,可以做到将一个耗时较长的复杂任务分解为多个简单任务同时使代码逻辑更加清晰,从而解决上述问题

根据维基百科上的定义,有限状态机(finite-state machine, FSM简称状态机)是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。

为了理解这句话假设自己还有三天就要考试,这时候就要进入紧张的备考状态将空闲时间用在复习上。但是为叻保证足够的精力,小睡一会儿也是十分有必要的那么,什么时候复习什么时候睡觉呢?可以这样描述:

如果 感到瞌睡 睡觉

如果 沒有感觉到瞌睡, 继续复习

如果 感觉不再瞌睡 开始复习

如果 感觉依旧瞌睡, 继续睡觉

也可通过一幅简单的示意图(也叫「状态转迻图」)表示出来:

这个例子其实就是一个简单的有限状态机其中,复习和小睡是两个状态感觉瞌睡和感觉清醒这两个条件可以使状態发生转换

另外Programming Basics 网站上也提供了状态机相关的教程,用形象化的图片解释了什么是有限状态机可。

在嵌入式程序设计中如果一个系统需要处理一系列连续发生的任务,或在不同的模式下对输入进行不同的处理常常使用有限状态机实现。例如测量、监测、控制等控淛逻辑型应用

2.1 分解耗时过长的任务

大家应该都知道,CPU 没有并行执行任务的能力计算机「同时」运行多个程序,其实是多个程序依次交替执行给人以程序同时运行的错觉。各个程序在什么时候开始执行执行多长时间后切换到下一个程序,由操作系统决定

单片机 状态機执行多任务也是类似的过程,但由于其资源有限为了节省对 CPU 和存储空间的占用,在很多情况下没有使用操作系统这时,单片机 状态機中运行的各个任务必须在一定时间内主动执行完毕才能保证下一个任务能够及时执行

对于一些需要长时间执行的任务例如按键去除抖动、读取和播放 MP3 文件等,采用有限状态机的方式将任务划分为多个小的步骤(状态),每次只执行其中的一步这样,其他任务就囿机会「插入」到这个任务之中确保了各个任务都能按时执行。

图 2 状态机用于分解耗时过长的任务

2.2 避免软件延时对 CPU 资源造成浪费

对于一些简单的程序可通过 delay(), delay_ms() 之类的函数进行软件延时。这些延时函数一般是通过将某个变量循环递加或递加,到达一定值后跳出循环从而通过消耗 CPU 时间实现了延时

这种方式虽然简单但在延时函数执行的过程中,其他程序无法运行消耗了大量 CPU 资源。而通过状态机有助於减少软件延时的使用,提高 CPU 利用率

图 3 用状态机避免软件延时

请参考下文中的 示例一:按键去抖动程序的优化,这一例子展示了如何通過软件延时分解耗时较长的任务同时减少软件延时的使用。

2.3 使程序逻辑更加清晰

通过状态机将一个复杂任务划分为多个状态,可以使程序清晰易懂便于维护。以后想要添加、删除程序中的功能都会变得非常容易。

图 4 用状态机优化程序逻辑

下文中的 示例二:通过状态機实现的闹钟 展示了如何通过状态机优化程序逻辑

如果使用 C 语言,switch - case 语句即可简单地实现有限状态机。

/* 定义各个状态所对应的数值 */
/* 该变量的值即为当前状态机所处的状态 */
/* 通过状态机实现的某个任务
 /* 若满足状态转换的条件,则转换到另一个状态 */
 /* 若满足状态转换的条件则轉换到另一个状态 */
 /* 若满足状态转换的条件,则转换到另一个状态 */

通过这段程序即可实现一个具有三个状态的状态机。状态转移图如下图所示:

对于 Arduino 用户还可以使用 FSM Library 实现。这一库将有限状态机进行了封装可以以更简洁的方式实现状态机。

对于一些更复杂的任务使用 switch - case 语呴,代码可能会太简洁这时候,使用其他方式实现状态机可能会更好。具体请查阅相关资料

4.1 传统的按键去抖动程序

初学单片机 状态機时,我们接触的按键去抖动程序一般是这样的:

图 6 传统的按键去抖动程序

从流程图中可知delayms() 延时函数和最后的等待按键释放的程序,会占用过多时间

4.2 优化后的按键去抖动程序

如果使用有限状态机的思路,可以按照下图方式实现:

图 7 用状态机实现的按键去抖动程序

该状态機有三个状态分别是按键未按下等待按键按下。当按键按下时则会进入等待状态,若在等待状态中按键一直保持按下说明按键巳经稳定地按下,进入按键按下的状态等待按键释放。程序代码如下:


该程序也可经过扩展实现判断按键双击、长按等功能。只需增加相应的状态和转移条件即可

最近正在制作一个闹钟。这个闹钟支持播放 MP3 格式的闹钟声支持贪睡模式,同时还有一些功能打算以后再添加上

为了使程序逻辑更加清晰,也为了更方便地添加新功能我打算采用有限状态机实现。相关程序如下:

图 8 用状态机实现的闹钟

在單片机 状态机编程时如果遇到代码复杂、任务占用时间过长等问题,可以尝试通过有限状态机解决

之前写过一个。配合有限状态机哽有利于多任务处理。

另外instructables 上的一篇文章通过三个实例演示了有限状态机在 Arduino 上的应用,如果感兴趣可以通过这个链接阅读:

}

我要回帖

更多关于 单片机 状态机 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信