万事万物都有其状态

什么是状态

状态是人或事物表现出来的形态。是指现实(或虚拟)事物处于生成、生存、发展、消亡时期或各转化临界点时的形态或事物态势。

通过上面那句话,我们知道了状态就是一个对象在不同情况下对应的各种形态


做产品的时候,如果我们如果要对这个对象所有的形态进行描述,在一些对象复杂的逻辑状态下,比较复杂的逻辑问题,普通的流程图,或时序图对于对象和状态的解读缺乏直观的描述。

这个时候就需要状态机来对对象的各个形态进行描述,将对象的全部工作方式,分成几个场景,这些场景的工作方式不同,然后将这些场景通过数学模型表示出来


比方说一个小灯泡的开关,就是一个最基本的小型状态机

这里就是两个状态:①打开开关,灯泡亮,②关闭开关,灯泡灭

对应的状态机图:


这就是最简单的一个状态机

状态机方便的地方是,如果现在我们只有两种状态,这两个状态打开开关/关闭开关两个条件之间跳转,如果我们要加上一个新的条件,比方说我们设定了定时开关灯,多了一个跳转条件,如果灯泡开了超过8个小时就自动关闭,除非再次做打开开关,否则灯泡一致处于关闭状态,这个状态图如下:

是不是很方便

再举个最简单的例子。人有三个状态健康,感冒,康复中
触发的条件有淋雨(t1),吃药(t2),打针(t3),休息(t4)
所以状态机就是健康->(t4)->健康;健康->(t1)->感冒;感冒->(t3)->健康;感冒->(t2)->康复中;康复中->(t4)->健康,等等。就是这样状态在不同的条件下跳转到自己或不同状态的情况,就叫做状态机。

状态机要素

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

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

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

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

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

状态机是一种编程思路。是现实事物运行规则抽象而成的一个数学模型。

有限状态机

有限状态机简称就是状态机,因为一般的状态机的状态都是离散和可举的,即为有限,所以后面的介绍都不加有限二字**。状态机表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型**。通俗的描述状态机就是定义了一套状态変更的流程:

状态机包含一个状态集合,定义当状态机处于某一个状态的时候它所能接收的事件以及可执行的行为,执行完成后,状态机所处的状态。

状态迁移图(STD)

  • (1)状态框:用方框表示状态,包括所谓的“现态”和“次态”;
  • (2)条件及迁移箭头:用箭头表示状态迁移的方向,并在该箭头上标注触发条件;
  • (3)节点圆圈:当多个箭头指向一个状态时,可以用节点符号(小圆圈)连接汇总;
  • (4)动作框:用椭圆框表示;
  • (5)附加条件判断框:用六角菱形框表示;

状态表:

STM32中的状态机

举个简单的例子:就按键处理来说,按键动作本身也可以看做一个状态机。一个细小的击键动作包含了:释放、抖动、按下、抖动和重新释放等状态。  当我们打开思路,把状态机作为一种思想导入到程序中去时,就会找到处理疑问的一条有效的捷径。有时候用状态机的思维去思考程序该干什么,比用控制流程的思维去思考,可能会更有效。这样一来状态机便有了更实际的功用。废话不多说,实践才是检验真理的唯一标准。

也许有人觉得状态机把问题复杂化了,其实我们在编写代码的时候在无形之中已经使用了状态机的思想,比方说我们的if else 判断

if else语句结构状态机

if 条件1else if  条件2else if   条件3...else  条件n

我们知道C语言的if else if语句是从第一条开始判断的,如果符合条件的那一行永远在后面几行,那么就要每次多执行很多次的if …而if是判断语句,括号内的判断是要执行运算的,即使是单周期指令的MCU,在进行乘除运算等都需要消耗多个时钟周期,因此,每次多执行1次判断至少浪费一个时钟周期甚至更多,因此,这样子的状态机无疑是效率低下的,系统软件设计会很复杂。

switch case结构状态机

 switch()。case1:。if(not反复执行状态1)。进入1状态前要做的准备。进入1状态的过程。if(not反复执行状态1)。离开状态1的过程。case2:。...。

使用Switch case 相较于if else的好处就是可以清楚的看到所有的状态,然后代码架构更清楚点,但是实际的运行效率还是没有提高


再说一下使用Switch编写状态机的两种写法

我们假设状态机的状态转换由下表所示:当处于State0时发生event0 则执行action0并将状态变成state1,当state1状态下发生event2则执行action6并将状态变成state2。以此类推。

下面描述下实现上述状态机的两种不同的写法:
1)竖着写:在状态中判断事件,并执行相应的操作,完成相应的状态转换。
2)横着写:在事件中根据当前的状态,执行相应的操作,完成相应的状态转换。

//竖着写
switch(cur_state)
{case State0:if(event1){action0;cur_state = State1;}else if(event2){action4;cur_state = State1;}else if(event3){action5;cur_state = State2;}break;case State1:if(event1){action1;cur_state = State2;}else if(event3){action6;cur_state = State0;}break;case State2:if(event1){action3;cur_state = State0;}break;default:break;
}
//横着写
void event0func(void)
{switch(cur_state){case State0:action0;cur_state = State1;break;case State1:action1;cur_state = State2;break;case State2:action1;cur_state = State0;break;default:break;}
}void event1func(void)
{switch(cur_state){case State0:action4;cur_state = State1;break;default:break;}
}void event2func(void)
{switch(cur_state){case State0:action5;cur_state = State2;break;case State1:action6;cur_state = State0;break;default:break;}
}

上述两种写法实现的功能完全相同,对比两种写法:

1)写法1(竖着写)使用了if -else if语句隐含了优先级,破坏可事件间的原有关系(各个时间应该同优先级)
2)写法1(竖着写)在结构上是顺序查询方式(查询事件),浪费大量的时间,而且时间不可估算。
写法2(横着写)因为在某个时间点上状态是唯一确定的,在时间处理函数中通过switch语句可直接定位到相同状态,执行时间也可以估算。
3)写法2(横着写)比较直观,程序执行效率较高。
总体来说:写法2要优于写法1。

但是不论是在事件中判断状态,在状态中判断事件,横竖两种写法的代码都比较冗长,看起来呢也不大好,一旦增减,就又要动脑子重新梳理一遍,实际编写我们并不采用这两种写法


那么下一节我们将用STM32实现LED的状态机编程,用状态机的4个要素,让您了解下状态机编程的方便之处。

STM32状态机编程----什么是状态机?相关推荐

  1. STM32状态机编程实例——全自动洗衣机(上)

    前面几篇文章,以按键功能,介绍了状态机的原理与按键状态机实例,实现按键单击.双击.长按等状态的检测. 本篇,继续使用状态机编程,来实现一个更有趣的功能--全自动洗衣机. 1 全自动洗衣机功能分析 下面 ...

  2. C语言状态机编程思想

    关注.星标公众号,直达精彩内容 文章来源:头条-嵌入式在左C语言在右 链接:https://www.toutiao.com/i6843028812112855564/ 有限状态机概念 有限状态机是一种 ...

  3. 嵌入式状态机编程简介

    不知道大家有没有这样一种感觉,就是感觉自己玩单片机还可以,各个功能模块也都会驱动,但是如果让你完整地写一套代码,却无逻辑与框架可言,上来就是开始写!东抄抄西抄抄,说明编程还处于比较低的水平.那么,如何 ...

  4. 【智能车竞赛】状态机编程在智能车竞速赛道中的应用 - 编程小记

    我曾试图通过一些代码上的小技巧,优化智能车竞速赛道的元素处理逻辑. 后来学长告诉我这叫做 "状态机" . --2022.07.20 一.我们为什么需要状态机? 定宽的白色赛道,在深 ...

  5. 博途PLC 1200/1500PLC MODBUS-RTU通讯优化(状态机编程)

    博途MODBUS-RTU通信详细设置可以参看下面这篇文章,本篇文章给出MODBUS轮询的优化写法(基于状态机编程).限于本人能力和水平,文中难免出现错误和不足之处,诚恳的欢迎大家批评指正,同时感谢大家 ...

  6. c语言按键状态机,C语言状态机编程思想

    原标题:C语言状态机编程思想 有限状态机概念 有限状态机是一种概念思想,把复杂的控制逻辑分解成有限个稳定状态,组成闭环系统,通过事件触发,让状态机按设定的顺序处理事务.单片机C语言的状态机编程,是利用 ...

  7. 博途PLC 1200/1500PLC ModbusTcp通信之状态机编程

    状态机的详细讲解大家可以参看专栏的其他文章,这里不在赘述.这篇博文直接给出状态机编程的代码和讲解. PLC面向对象编程系列之状态机(FSM)详解_RXXW_Dor的博客-CSDN博客_plc 状态机编 ...

  8. 排线电机运行控制(梯形图状态机编程)

    这篇博客主要分析排线电机的逻辑时序动作控制,有关排线电机的速度控制(比例随动编程应用)可以参看相关的文章,有详细算法和源代码分析: 绕线机-排线伺服速度解算FC(比例随动编程应用)_RXXW_Dor的 ...

  9. 大一电赛:51单片机(状态机编程)——控制外部开关(继电器)达到自定义输出波

    题目来源于某双流一大学第八届"电协杯"电子设计(校赛) 大一C组:自定义信号发生器 队伍名称:摆烂三人组 下文有对相应软件和硬件的实现进行介绍 复盘电赛(软件部分) 读题方面 定时 ...

  10. STM32按键消抖——入门状态机思维

    在嵌入式软件开发中,状态机编程是一个十分重要的编程思想,它也是嵌入式开发中一个常用的编程框架.掌握了状态机编程思想,可以更加逻辑清晰的实现复杂的业务逻辑功能. 1 状态机思想 状态机,或称有限状态机F ...

最新文章

  1. OCA读书笔记(9) - 管理数据同步
  2. 时间字符串与当前时间比較
  3. html追加行clone,调用clone()方法后就可以将复制的节点追加到body元素内。( ) 答案:√...
  4. 将C1Chart数据导出到Excel
  5. jquery-confirm
  6. springboot 使用interceptor 返回前端http状态码为0
  7. c语言中1B是多少,C语言1、C语言中,运算对象必须是整型的运算符是【】A./B-查字典问答网...
  8. java 8 集合分组_Java 8:按集合分组
  9. Win10 安装 MongoDB 3.6.5 失败的问题及解决方法
  10. 【jQuery学习】—实现弹幕效果
  11. 【CVTE Web后台开发实习生2019.12.05在线笔试】总结
  12. javascript获取元素样式值
  13. ggplot2 多个柱状图比较_15. 再论ggplot2作图的图形元素组成
  14. grub引导程序适用范围
  15. 排序算法专题-基数排序
  16. java性能调试命令_性能测试--十个命令迅速发现性能问题
  17. linux php oauth安装,Linux安装phpmyadmin
  18. 使用并行计算大幅提升递归算法效率
  19. WPS 表格中单元格文字后插入公式
  20. 你在项目中做过哪些安全防范措施?

热门文章

  1. r语言跟python哪个适合数据分析_R语言 vs Python对比:数据分析哪家强?
  2. 启动3Dmax到初始化..界面卡住然后闪退解决办法
  3. ApiPost使用教程
  4. oracle中一个月的最后一天,SQL和Oracle获取每周、每月、每年第一天和最后一天
  5. 在线浏览stp(step)文件(一)
  6. 推荐一个清理自己电脑磁盘的磁盘容量图形化软件--WinDirStat
  7. 【CV-Learning】线性分类器(SVM基础)
  8. AD20中PCB设计流程
  9. IDEA设置方法注释模板
  10. R语言回归及混合效应模型及贝叶斯实现