第1章:Stateflow基础(上)——从状态机到闪烁灯

各位同学,咱们今天聊聊Stateflow。说实话,我刚接触这东西的时候,心里也犯嘀咕——这不就是个画框框、连箭头的工具吗?后来做项目做多了才发现,这里面的门道还真不少。

1.1 Stateflow是什么?

Stateflow,说白了就是Simulink里的状态机工具箱。你想想看,很多控制逻辑用普通Simulink模块搭起来,那连线密密麻麻的,看着就头疼。Stateflow不一样,它用状态(State)和转移(Transition)来描述系统行为,直观得多。

我个人习惯把Stateflow看作一个“智能开关”。它根据当前状态和输入条件,决定下一步该干什么。比如一个电机控制,是正转、反转还是停止?用Stateflow画三个状态,连几条线,逻辑清清楚楚。

核心要点:Stateflow适合描述“事件驱动”或“模式切换”的逻辑。如果你的系统有明确的工作模式,用Stateflow准没错。

1.2 状态(State)与转移(Transition)

这两个概念是Stateflow的基石。咱们一个一个说。

1.2.1 状态(State)

状态就是系统在某个时刻所处的“模式”或“情况”。比如一个灯,要么亮着,要么灭着。这就是两个状态。

在Stateflow里,状态用一个圆角矩形表示。每个状态可以有自己的名字,还可以定义进入、持续、退出时要执行的动作。

状态元素 说明 我踩过的坑
状态名称 唯一标识,建议用有意义的英文 别用中文,代码生成会报错
entry动作 进入状态时执行一次 常用于初始化变量
during动作 在状态中每个时间步执行 别放耗时操作,影响实时性
exit动作 离开状态时执行一次 记得清理资源

1.2.2 转移(Transition)

转移就是状态之间的连线,表示从当前状态切换到另一个状态的条件。箭头指向目标状态,箭身上可以写条件。

举个例子:灯亮着的时候,如果按下开关,就转移到灯灭。这个“按下开关”就是转移条件。

小技巧:转移条件可以用C语言表达式,比如 button == 1。我习惯把条件写得简单明了,太复杂的逻辑拆成多个转移。

1.3 状态动作:entry, during, exit

这三个动作是Stateflow的精髓。很多新手搞不清楚它们什么时候执行,我当年也迷糊过。

  • entry动作:进入状态时,只执行一次。适合做初始化,比如给变量赋初值、打开某个设备。
  • during动作:只要还在这个状态,每个仿真步长都会执行。适合做持续的控制,比如输出PWM波。
  • exit动作:离开状态时,只执行一次。适合做清理,比如关闭设备、保存数据。

我曾经在一个项目中,把定时器复位写在了during动作里。结果每次步长都复位,定时器永远跑不起来。后来改成entry动作,问题就解决了。嗯,这种细节不注意,调试起来真要命。

1.4 实战:画一个闪烁灯状态机

光说不练假把式。咱们来画一个最简单的闪烁灯状态机。需求是这样的:灯以1秒为周期闪烁,亮0.5秒,灭0.5秒。

首先,定义两个状态:ON(亮)和OFF(灭)。

然后,用定时器控制切换。Stateflow里可以用 after(0.5, sec) 这样的时间条件。

状态机逻辑如下:

  • 初始状态:OFF,灯灭
  • OFF状态,等待0.5秒后转移到ON
  • ON状态,等待0.5秒后转移到OFF

代码实现很简单:

// 状态 OFF 的 entry 动作
led = 0;

// 状态 OFF 的转移条件
after(0.5, sec)

// 状态 ON 的 entry 动作
led = 1;

// 状态 ON 的转移条件
after(0.5, sec)

注意:时间条件 after(0.5, sec) 依赖于仿真步长。如果步长太大,时间精度会受影响。我一般把步长设成0.01秒,够用。

下面我用一张图来展示这个状态机的结构:

OFF entry: led = 0 ON entry: led = 1 after(0.5, sec) after(0.5, sec) 默认

这张图很直观吧?两个状态来回切换,每个状态进入时设置LED的电平。这就是一个完整的闪烁灯状态机。

1.5 避坑指南

做Stateflow开发这几年,我总结了几条经验,分享给大家:

  • 状态不要太多:一个状态机超过10个状态,可读性就差了。我习惯用层次化状态来管理复杂逻辑。
  • 转移条件要互斥:同一个状态出发的多个转移,条件不能同时为真。否则Stateflow会报错。
  • 动作别太复杂:entry/during/exit里尽量写简单的赋值或函数调用。复杂的计算放到Simulink里做。
  • 仿真步长要合适:时间条件依赖步长,步长太大精度不够,步长太小仿真慢。我一般取0.01秒。

个人建议:刚开始学Stateflow,先画简单的2-3个状态的状态机。跑通了再慢慢加功能。别一上来就搞复杂的,容易把自己绕进去。

好了,这一章的内容就到这里。Stateflow的基础概念和闪烁灯的例子,大家回去可以动手试试。记住,状态机就是“当前状态 + 输入条件 → 下一个状态”的循环。把这个逻辑理清了,后面学什么都很轻松。


公众号:蓝海资料掘金营,微信deep3321