6520浏览
查看: 6520|回复: 0

[教程] Mind+状态机编程入门

[复制链接]
本帖最后由 云天 于 2022-9-7 08:38 编辑

【教程背景】
之前有位网友Hans_林立提了一个问题:
  1. 两个按钮B1,控制LED1灯;B2,控制LED2灯;
  2. B1按下LED1交替闪烁1秒;
  3. B2按下LED2交替闪烁2秒;
  4. 两个LED灯使用同一个时间轴,不是LED1执行完再执行LED2,而是同步的,独立输出,请问这个程序怎么写;
复制代码
当时我给编写一段程序,并录制了视频。但依然将这件事放在心上,想通过更系统介绍来讲解这个问题。首先,我们来了解一下“状态机编程”
【状态机编程】
什么是状态机
有限状态机(finite state machine,简称状态机)是嵌入式开发中最重要,且最常用的编程模式之一。状态机(state machine)有 5 个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)。其设定了这样一种系统:
1.系统具备数量有限的状态,例如开关有“开”、“关”两种状态。在某一时刻,系统总是处于一种状态之下;
2.系统的状态会根据某些事件条件进行迁移
3.每个状态下,系统都会执行相应的动作
状态机的编程思想在之前的章节也有体现,如开关灯示例(以下均使用Mind+编程演示):Mind+状态机编程入门图1
按钮接在扩展板P8引脚
Mind+状态机编程入门图2

演示视频

在这个示例中,设备具备开和关两种状态,使用了一个变量“灯状态”存放当前状态,会根据当前状态进行对应的开关灯操作。
现在请思考,当设备具备更多状态时,应该如何扩展这个程序?如何让灯可以进入闪烁或呼吸的状态?
以现有的这个程序写法来说,很难,因为程序大部分时间都在等待按键状态的变化,处于“等待直到……”这个循环中。
现在将以状态机的编程模式,重构该项目。在此过程中,即可学习到状态机编程的方法,体会到使用该模式的优势。
【状态机编程方法】
状态机编程基本分为如下几个步骤:  
1. 总结设备状态  
本项目中,设备具备两种状态,开灯状态和关灯状态。
为了之后能支持更多的状态,这里用一个变量“状态”记录其状态:  

Mind+状态机编程入门图3
2. 确定状态切换条件
设备连接的按键每点击一次,就会切换一次开关状态,通过循环检测按键状态变化(按下按键到松开,电平从低电平变为高电平),确定按键是否被点击。这里创建一个状态检查函数“检查状态”,将其放在“循环执行”中,不断地检测当前设备处于的状态。  

Mind+状态机编程入门图6
3. 确定状态对应的动作
当设备会执行的动作有二:开灯和关灯,这里编写出对应的动作函数
Mind+状态机编程入门图4
4. 判断当前状态,并执行相应的动作:
有了状态检查和对应的动作函数后,通过判断语句将两者联系起来,从而实现设备根据状态,执行对应的动作的功能。  
Mind+状态机编程入门图5
使用状态机编程的完整开关灯程序如下:
Mind+状态机编程入门图7
【扩展更多状态】
状态机编程的最大优势,是能让程序逻辑更清晰,逻辑清晰也使得程序,具备了更好的扩展性。
例如,在这个框架基础上,给设备增加闪烁和呼吸两种状态:闪烁状态下,灯每隔1秒,切换一次开关状态;呼吸状态下,会呈现出呼吸灯效果。
Mind+状态机编程入门图8

演示视频
【状态机编程注意事项】
在基本掌握了状态机编程方法后,还应该了解如下事项:
    状态机编程应该尽可能的提高MCU的使用效率,让系统能更积极的响应外部输入的变化,并即时做出相应的动作。
    大部分MCU都不具备多个核心,其同一时刻,只能执行一条指令。如果使用“等待”进行延时,或使用之前例程中的“等待直到”一类的判断方式,将导致整个程序阻塞,影响此后的其他操作。
    因此在状态机程序中,需避免进行耗时较长的操作,常见的解决办法是,通过“系统运行时间”多次读取时间,判断时间间隔是否达标,再执行对应的程序。除此以外,还可以使用硬件本身具备的中断功能,对条件参数的进行实时的改变。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail