蓝色港湾 发表于 2023-4-12 22:47:12

codesys 之 SFC探索

1 测试

在initing状态中测试(entry)进入动作,(exit)出去动作,内部动作,外部动作 四种类型的执行做了如图所示的测试;
获得结论:
1:即使initing的跳转条件一直是true,也会执行initing的入口动作,内部动作,外部动作;
2:第一次扫描得知initing的跳转条件为true,第二次扫描的时候只会执行外部动作,出去动作;
3:initing的动作执行顺序是,先执行内部动作,后执行外部动作;
4: 如果在initing 内部动作中在嵌套子状态sfc,父状态转移会执行父的exit动作,子状态如果是因为父状态转移而不执行,子状态的exit动作不会执行,类似history历史状态,下次进入子状态会继续紧接着执行;


2 隐式的变量

在创建sfc中的步和动作(内部动作,不是关联动作)的时候,隐式的创建如下类型,在对应的库中可以查看类型;
常用的是 ._x:强制下一个周期的激活状态(测试发现是改变当前周期的激活状态)。用来定义历史状态和初始状态;
隐式变量声明的语法:
:SFCStepType;
_:SFCActionType;




3 模拟

用codesys 模拟 sfc的入口 出口 内部动作,并行选择分支,用sfc也是为了满足状态机的设计需求;理解了为什么UML让选择,信号同步等叫做虚拟状态;
考虑到并行的情况:有时同时处于多个状态,所有用字的每一个表示一个状态。在跳出状态的时候,要把当前状态位置为0;
(*状态的枚举类型*)
TYPE StetaMachine :(

eMainStateInit:=16#00000001,
eMainState1:=16#00000001,
eMainState2:=16#00000002);
END_TYPE(*变量定义*)
iMainState       : StetaMachine := eMainState1 ;
iMainStateFollow : StetaMachine := eMainStateInit;
bMainStateExit   : BOOL:= FALSE;{一、状态名称}IF(iMainState OR eMainState1)<>0 THEN
   {1 entry 入口函数---------------------------------------}IF(iMainStateFollow ANDeMainState1)=0THEN(*do1*)(*do2*)(*do3*)
       iMainStateFollow :=(iMainStateFollow OR eMainState1);
       bMainStateExit := FALSE;
   END_IF
   {2 内部处理动作-----------------------------------------}
   IF bMainStateExit = FALSE THEN(*do1:处理动作   :*)(*do2:并发子状态1:*)(*do3:并发子状态2:*)

   END_IF
   {3 exit出口函数-----------------------------------------}
   IF bMainStateExit = TRUE THEN
       bMainStateExit := FALSE;(*do1*)(*do2*)(*do3*)(* jump to state2:*){IF condition1 = TRUE THEN
            iMainState :=((iMainState XOR eMainState1) OR eMainState2);
            iMainStateFollow :=(iMainStateFollow XOR eMainState1);      
            RETURN;
         END_IF}(* jump to state3:*){IF condition2 = TRUE THEN
            iMainState :=((iMainState XOR eMainState1) OR eMainState3);
            iMainStateFollow :=(iMainStateFollow XOR eMainState1);      
            RETURN;
      END_IF}
   END_IF
   
   {4 跳转条件判断-------------------------------------------}(*条件选择分支1: judge_jump_to_state1 :*){IF condition1 = TRUE THEN
         bMainStateExit := TRUE;
         RETURN;
      END_IF}(*条件选择分支2: judge_jump_to_state2 :*){IF condition2 = TRUE THEN
          bMainStateExit := TRUE;
          RETURN;
      END_IF}
END_IF



{选择分支,选择是一个虚拟状态,是一个瞬间状态}
IF iMainState =2THEN(*IF condition THEN
      jump to state3
      iMainState :=((iMainState XOR eMainState2) OR eMainState3);      
   ELSE      
      jump to state4
      iMainState :=((iMainState XOR eMainState2) OR eMainState4);   
   END_IF*)
END_IF

{3.1 并行开始,并行是一个虚拟状态,是一个瞬间状态}

IF iMainState =3 THEN
   {JUMP TO STATE4}{JUMP TO STATE5}
   iMainState :=((iMainState XOR eMainState3) OR eMainState4 OR eMainState5 );
END_IF


{3.2 并行开始,并行是一个虚拟状态,是一个瞬间状态}
IF iMainState =4THEN(*IF condition1 AND condition2 AND condition3 AND conditionN THEN
   {jump to state5}
   iMainState :=((iMainState XOR eMainState4) OR eMainState5
END_IF*)
END_IF


4 计划:理解关联动作并用代码模拟



5 计划:理解SFC的标志



6 计划:完善codesys状态机模板代码
页: [1]
查看完整版本: codesys 之 SFC探索