本文来说一下情状机编程。
什么是情状机?
情状机(state machine)有5个因素:
情状(state)迁徙(transition)事件(event)动作(action)条目(guard)
情状:一个系统在某一时辰所存在的踏实的责任情况,系统在通盘责任周期中可能有多个情状。举例一部电动机共有正转、回转、停转这 3 种情状。
一个情状机需要在情状结合中选取一个情状手脚运奇迹态。
迁徙:系统从一个情状转化到另一个情状的流程称作迁徙,迁徙不是自动发生的,需要外界对系统施加影响。停转的电动机我方不会转起来,让它转起来必须上电。
事件:某一时辰发生的对系统特道理道理的事情,情状机之是以发生情状迁徙,即是因为出现了事件。对电动机来讲,加正电压、加负电压、断电即是事件。
动作:在情状机的迁徙流程中,情状契机作念出一些其它的活动,这些活动即是动作,动作是情状机对事件的反应。给停转的电动机加正电压,电动机由停转情状迁徙到正转情状,同期会启动电机,这个启动流程不错看作念是动作,也即是对上电事件的反应。
条目:情状机对事件并不是有问必答的,有了事件,情状机还要昂扬一定的条目智力发生情状迁徙。还是以停转情状的电动机为例,诚然合闸上电了,可是要是供电败露有问题的话,电动机还是不成转起来。
举个例子
要贬责的问题
电路如下图:
器件包括单片机MCU、一按键K0、LED灯L1和L2。
完结功能形容:
L1L2情状妥洽章程OFF/OFF--->ON/OFF--->ON/ON--->OFF/ON--->OFF/OFF通过按键截止L1L2的情状,每次情状妥洽需相连按键5次L1L2的运奇迹态OFF/OFF
情状妥洽图
在情状机编程中,正确的章程应该是先有情状妥洽图,后有要领,要领应该是字据贪图好的情状图写出来的。
底下这张按键截止活水灯情状妥洽图,是用UML(斡旋建模言语)的语法元素画出来的,语法不是很设施,但拿来泄漏问题弥漫了。
上图中,圆角矩形代表情状机的各个情状,内部标注着情状的称呼。
带箭头的直线或曲线代表情状迁徙,起于初态,止于次态。
图中的笔墨骨子是对迁徙的阐发,形势是:事件[条目]/动作列表(后两项可选)。
“事件[条目]/动作列表”要阐发的道理是:要是在某个情状下发生了“事件”,何况情状机
昂扬“[条目]”,那么就要现实这次情状转化,同期要产生一系列“动作”,以反应事件。在这个例子里,我用“KEY”默示击键事件。
图中有一个玄色实心圆点,默示情状机在责任之前所处的一种不可知的情状,在运行之前情状机必须强制地由这个情状迁徙到运奇迹态,这个迁徙不错有动作列表(如图1所示),但不需要事件触发。
图中还有一个包含玄色实心圆点的圆圈,默示情状机人命周期的扫尾,这个例子中的情状机生生握住,是以莫得情状指向该圆圈。
要领代码
底下是字据上述情状妥洽图写成的代码:
void main(void)
先看一下fsm_active()这个函数,g_stFSM.u8KeyCnt = 0;这个语句在switch—case里共出现了 5 次,前 4 次是手脚各个情状迁徙的动作出现的。从代码简化晋升遵循的角度来看,咱们统共不错把这 5 次吞并为 1 次放在 switch—case 语句之前,两者的恶果是统斡旋样的,代码里之是以这么啰嗦,是为了了了地标明每次情状迁徙中通盘的动作细节,这种方法和上头情状妥洽图所要抒发的意图是统斡旋致的。
再看一下g_stFSM这个情状机结构体变量,它有两个成员:u8LedStat和 u8KeyCnt。用这个结构体来作念情状机大要有点儿啰嗦,咱们能不成只用一个像 u8LedStat 这么的整型变量来作念情状机呢?
天然不错!咱们把上图中的这 4 个情状各自拆分红 5 个小情状,这么用 20 个情状雷同能完结这个情状机,而且只需要一个 unsigned char 型的变量就弥漫了,每次击键皆会激勉情状迁徙, 每迁徙 5 次就能改变一次 LED 灯的情状,从外面看两种方法的恶果统斡旋样。
假定我把功能要求改一下,把相连击键5次改变L1L2的情状改为相连击键100次智力改变L1L2的情状。这么的话第二种方法需要4X100=400个情状!而且函数fsm_active()中的switch—case语句里要有400个case,这么的要领还有法儿写么?!
雷同的功能窜改,要是用g_stFSM这个结构体来完结情状机的话,函数fsm_active()只需要将if(g_stFSM.u8KeyCnt>3)改为if(g_stFSM.u8KeyCnt > 98)就不错了!
g_stFSM结构体的两个成员中,u8LedStat不错看作是质变因子,十分于主变量;u8KeyCnt不错看作是量变因子,十分于援救变量。量变因子的冉冉蚁集会激勉质变因子的变化。
像g_stFSM这么的情状机被称作Extended State Machine开云体育(中国)官方网站。