0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于状态机的程序设计

CHANBAEK 来源:木南创智 作者:尹家军 2022-12-13 14:33 次阅读

在编码实现的过程中,我们会经常使用到条件判断结构,而且使用起来很方便。但是在需要转移的状态比较多,或是条件比较复杂时,我们就可能需要很长的条件判断结构来处理。不过,过于复杂的条件判断结构会给代码的编写和维护带来很大的困扰,所以我们希望探索其他的方法来简化这类条件结构。

1、原理概述

  条件判断在代码实现中非常有用,有时候甚至是必不可少的。但过于复杂的条件结构却会让程序逻辑变得冗长而繁琐,而在某些情况下我们希望采取方法避免这一情况出现。

1.1、问题提出

  在项目开发中经常会遇到if/esle语句以及switch/case语句之类,或者是嵌套的多分支条件判断的结构。这类结构一旦过于复杂或冗长就会使程序的逻辑结构非常繁琐。所以很多时候我们希望避免使用过于复杂的条件结构。基于这一目的,我们希望探索一些方法来简化这类问题。

  在我们实践的过程中,我们发现有些复杂的条件结构实际控制的是同一事物在不同状态下的转换。这就让我们想到了状态机,那么是否可以借用状态机的机制来解决这一类的问题呢?在这一篇中我们就来分析和实现这一议题。

1.2、什么是状态机

  我们先来看看什么是状态机。一般来说,状态机(state machine)包含有5个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)。我们来具体看看这5个要素都是什么。

  • 状态:一个系统在某一时刻所存在的稳定的工作情况,系统在整个工作周期中可能有多个状态。一个状态机需要在状态集合中选取一个状态作为初始状态。
  • 迁移:系统从一个状态转移到另一个状态的过程称作迁移,迁移不是自动发生的,需要外界对系统施加影响。
  • 事件:某一时刻发生的对系统有意义的事情,状态机之所以发生状态迁移,就是因为出现了事件。
  • 动作:在状态机的迁移过程中,状态机会做出一些其它的行为,这些行为就是动作,动作是状态机对事件的响应。
  • 条件:状态机对事件并不是有求必应的,状态机还要满足一定的条件才能发生状态迁移并实现对事件的响应。

  对于状态机,我们的理解是,一个事物存在多个状态,这些状态可以相互转换,有些可能是双向的,有些可能是单向的。当一定的外部事件发生时,会促使事物的状态发生转变,这一过程就是发生了状态的迁移。当事物的状态发生转换后会执行一定的动作。但这些动作有可能是在状态转换进入时执行,也可能是状态持续过程中执行,这就要看动作执行的前提条件。

2、分析设计

  接下来我们将以BLDC操作面板的实际操作项目来分析如何实现通过状态机机制简化条件结构。在这个BLDC操作面板项目中,我们使用按键操作来实现BLDC的操作控制以及LED显示菜单的切换。

  首先我们来看一看BLDC的操作控制实现。对于BLDC的操作的操作,我们希望按下启动停止按钮时,BLDC启动并按设定的速度持续运行。在BLDC正常运行的过程中,如果长按启动停止按钮则进入全速状态,如果是短按启动停止按钮则停止。如果是在全速状态,如果长按启动停止按钮则停止,如果是短按启动停止按钮则回到常规速度状态。

  对于这个需求如果我们使用条件结构则需要使用if/else语句或者switch/case语句来判断状态,然后在各个分支中通过条件判断按钮的动作以实现对应的操作。在这一方式下,我们需要使用条件结构的嵌套来实现这个过程,从逻辑结构上来说过于复杂而且不同功能模块的耦合比较紧密。

  接下来,我们以状态机的机制来分析一下。我们注意到BLDC实际有3种状态,分别是停止状态、常速运行状态、全速运行状态。而这3种状态之间可以相互转化,但并无直接关联,在不同的状态下将执行不同的操作。它们之间将根据按钮的事件产生转换。对比前面我们对状态机的要素的表述,实际上已经完全具备了状态机的全部要素,所以我们将其状态转化过程表述如下图:

  接下来我们看一看菜单的切换问题。菜单的切换更复杂一点,就是在不同的情况下,会有不同的显示。我们将其归为5类,也就是5个菜单,这些菜单根据按键的不同显示不同的菜单。我们将每个显示菜单定义为一种状态,那么其实就已经具备了状态机的全部5个要素,具体状态转换过程如下图所示:

  我们将BLDC的控制以及显示菜单的切换抽象为状态机,以避免冗长的条件选择结构,简化程序逻辑结构,使得程序更为清晰。

3、软件实现

  前述,我们已经分析了将BLDC的控制及显示菜单的切换使用状态机来实现的方法。接下来我们就来考虑其具体的实现方式。

  首先,我们来分析BLDC的控制。我们已经知道BLDC的控制要求有3个状态:停止状态、常速状态、全速状态。通过按键事件来控制状态产生迁移并执行动作。我们需要一个变量来记录按键事件对BLDC产生的命令,这个命令变量取值0、1、2以对应3个状态的迁移命令。之所以去这样的3个值并没有什么特殊之处,仅仅只是为了我们在后续的处理中方便使用而已。同样我们需要变量来记录当前所处的状态,取值也用0、1、2对应3个状态。当然我们还需要定义每种状态下所对应的动作,为了操作方便我们将每种状态下的动作定义为一个单独的函数,也就是每种状态有一个响应函数。至于响应函数的实现则根据需求而定,函数中包括相应条件。具体如下:

void (*BldcControl[3])(void)={BldcStopHandler,
                 BldcNormalSpeedHandler,
                 BldcFullSpeedHandler};

BldcControl[aPara.phyPara.pumpStartStop]();

  其中aPara.phyPara.pumpStartStop变量记录的是对按键事件的记录,状态机根据变量的值来调用状态响应函数来迁移并维持在指定的状态。三个函数对应三种状态下的响应函数。这样就实现了不同的事件迁移到不同的状态的状态机结构,相比于条件分支判断结构要简化很多。

  接下来,我们再来看看菜单显示状态的实现。前面我们已经描述过菜单显示划分为5种状态,我们使用一个变量来记录状态及迁移。这个变量取值0、1、2、3、4分别对应当前速度显示状态、量程显示状态、全速设定显示状态、系数设定显示状态、速度设定显示状态。具体如下:

void (*LedDisPlay[5])(void)={SpeedCurrentDisplay,
              SpeedUpperDisplay,
              SpeedFullDisplay,
              SpeedFactorDisplay,
              SpeedSettingDisplay};

LedDisPlay[aPara.phyPara.menuIndex]();

  同样的aPara.phyPara.menuIndex是状态迁移及状态记录变量,而5个函数则对应不同状态下的响应函数。

4、小结

  在这一篇中,我们以一个BLDC驱动控制板的实例描述了使用状态机代替复杂的条件分支判断结构的过程及方法。我们实现了使用状态机机制编码BLDC的驱动控制和菜单显示切换的功能。这一实例已经应用于多个项目之中,效果良好。

  这一方式其实适用于很多需要条件判断来切换控制的场合。事实上,我们在多个电机控制、流程控制等应用场合都是用了类似的方法,而且应用的结果都比较满意。当然,我们并不是建议读者使用此法,只是提供一种思路,我们认为所谓结构优化本就是见仁见智的事情。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • BLDC
    +关注

    关注

    194

    文章

    730

    浏览量

    95857
  • 状态机
    +关注

    关注

    2

    文章

    486

    浏览量

    27184
  • 程序设计
    +关注

    关注

    3

    文章

    258

    浏览量

    30210
收藏 人收藏

    评论

    相关推荐

    状态机编程

    等待一段时间后,光标的位置就会右移,表示对最后输入字符的确认。因此,按键输入接口设计和实现的核心,更多的体现在软件接口处理程序的设计中。下面将以此为例,介绍有限状态机的分析设计原理,以及基于状态机思想进行
    发表于 07-10 18:00

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

    状态机思路在单片程序设计中的应用
    发表于 08-17 16:18

    单片程序中融入状态机思想

    干的事情进行划分,将互相独立的事情分为任务设计。3.软件各任务程序设计,如果任务复杂,需要不同的设备按照流程进行有序工作,采用状态机的思想执行。CASE语句比较实用。因此,就涉及到CASE中流程的划分
    发表于 03-10 13:08

    请教状态机程序设计的优化问题

    图示的状态机中设计了一个独立的Update状态用于更新UI界面的文本显示为什么不直接在每个状态动作分支直接将更新的文本直接输出到显示控件?或者说图示的编程方式相较于上述思路而言有什么好处?萌新求教
    发表于 07-19 09:40

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

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

    【设计技巧】LabVIEW程序设计模式(二)—基本状态机模式

    状态机是一种最为经典的程序设计模式,在LabVIEW 7.1(含)之前它几乎包揽了大部分的LabVIEW主程序。最基本的状态机结构如图 1所示。状态
    发表于 08-06 08:30

    什么是状态机状态机是如何编程的?

    什么是状态机状态机是如何编程的?
    发表于 10-20 07:43

    如何去实现有限状态机FSM的程序设计

    什么是有限状态机FSM呢?如何去实现有限状态机FSM的程序设计呢?
    发表于 01-21 07:04

    ARM7嵌入式系统在车辆调度中的应用

    本文设计并实现了车辆监控调度系统,在系统设计中采用S3C44B0X做为处理器,并对嵌入式系统中开发中的几个关键技术进行了分析:操作系统内核调度机理,基于状态机程序设计
    发表于 08-15 08:10 16次下载

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

    状态机思路在单片机程序设计中的应用 状态机的概念状态机是软件编程中的一个重要概念。比这个概念更重要的是对它的灵活应用。在一个思路清晰而且高效的程序
    发表于 02-09 11:25 1w次阅读
    <b class='flag-5'>状态机</b>思路在单片机<b class='flag-5'>程序设计</b>中的应用

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

    状态机思路在单片机程序设计中的应用 状态机的概念       状态机是软件编程中的一个重要概念。比这个概念更重要的是对
    发表于 03-18 15:00 1136次阅读
    <b class='flag-5'>状态机</b>思路在单片机<b class='flag-5'>程序设计</b>中的应用

    利用状态机的按键消抖程序

    利用状态机的按键消抖程序讲解,很好的资料下载吧。
    发表于 01-11 09:32 30次下载

    状态机原理在控制程序设计中的应用

    计算机控制系统的控制程序具有有限状态自动机的特征 可以用有限状态机理论来描述。利用状态转移图和条件编码可以更直观和清晰地描述程序的转移与条件
    发表于 03-22 15:30 1次下载

    状态机VHDL程序

    状态机VHDL程序,感兴趣的小伙伴们可以瞧一瞧。
    发表于 11-11 15:51 5次下载

    状态机如何简化PLC程序的编写

    在PLC程序的编写过程中,可以使用状态机的控制思路,将一些复杂的控制过程使用状态机的方法处理。这里简单给大家介绍一下什么是状态机?如下图所示,为一个
    的头像 发表于 09-10 14:44 3200次阅读
    <b class='flag-5'>状态机</b>如何简化PLC<b class='flag-5'>程序</b>的编写