0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

浅谈状态机的要素、分类

Q4MP_gh_c472c21 来源:嵌入式ARM 作者:嵌入式ARM 2020-10-20 17:27 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

说到单片机编程,不得不说到状态机,状态机做为软件编程的主要架构已经在各种语言中应用,当然包括C语言,在一个思路清晰而且高效的程序中,必然有状态机的身影浮现。灵活的应用状态机不仅是程序更高效,而且可读性和扩展性也很好。状态无处不在,状态中有状态,只要掌握了这种思维,让它成为您编程中的一种习惯,相信您会受益匪浅。

状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳,主要是出于对状态机的内在因果联系的考虑。“现态”和“条件”是因,“动作”和“次态”是果。详解如下:

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

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

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

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

如果我们进一步归纳,把“现态”和“次态”统一起来,而把“动作”忽略(降格处理),则只剩下两个最关键的要素,即:状态、迁移条件。

状态机的表示要领有许多种,我们可以用文字、图形或表格的形式来表示一个状态机。

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

也许有人觉得状态机把问题复杂化了,其实做过软件设计的人无形之中已经在用状态机,下面就总结介绍几种状态机。

第一种:switch case结构状态机

switch()。

case1:。

if(not反复执行状态1)。

进入1状态前要做的准备。

进入1状态的过程。

if(not反复执行状态1)。

离开状态1的过程。

case2:。

...。

但这种方式不能很有效预定义所有的状态,也不能把这些状态之间的切换过程合理的定义出来,“状态”本身没有一个合理的定义,几乎是一种面向过程的方式,只过这种方式足够简单,也最容易让人接受,缺点就没有“状态”的定义和指派功能,导致状态的混乱,出现状态处理重复代码,甚至处理不一致的问题,按照OO的观念,状态描述本来就应该是一种实体。

第二种状态机:ifelse语句结构状态机

这种状态机相对灵活一点,但对于一些大的项目,系统软件设计会相对复杂。

以上2种状态机是是大家接触最多的,也是经常用到的,这里不多说了。下面重点谈谈第三种状态机。

第三种状态机:消息触发状态机

该类型的状态机实现方式也是很多的,形态多样,但万变不离其宗的就是状态机的4要素及现态、条件、动作、次态。

下面介绍一种消息触发类型的状态机。

基于消息驱动的状态机机制

原理:一旦有消息触发,系统服务函数立即寻找所在状态的消息与消息处理函数对,找到后执行消息处理函数

步骤:

1.添加消息与消息映射

BEGIN_MESSAGE_ MAP(Name,Count) :状态机名,消息数

ADD_NEW_MSG_ITEM (Msg,OnMsg) :消息与消息处理函数

END_MESSAGE_MAP:结束

2.在这里注册

BEGIN_Register_Task:头

...

ADD_Register_Task(Name,Count):状态机名,消息数

...

END_Register_Task:尾

1.划分电子秤状态,完成以上步骤后,完成OnMsg消息处理函数

Void OnMsg(void)

{

}

说明:以上用宏完成,具体宏是如下定义:

#defineBEGIN_MESSAGE_MAP(Name,Count) constMSG_NODE_TYP MSG_node_Array_##Name[(Count)]={

#define ADD_NEW_MSG_ITEM(Msg,OnMsg) {Msg,OnMsg},

#define END_MESSAGE_MAP };

#define BEGIN_Register_Task const MSG_MAP TaskMap[TotalTask]={

#define ADD_Register_Task(Name,Count) {(MSG_NODE_TYP*)MSG_node_Array_##Name,Count},

#define END_Register_Task };

从以上代码可知:

1. 添加消息与消息映射实际上是定义消息与消息处理函数对的数组,以形成一个表

2. 注册状态机实际上是把所有消息对数组的入口定义成一个数组,以形成一个表

消息是如何被执行的?

分发消息

void Default_DisposeMessage(unsigned char *pMsg)

{

unsigned chari;

unsigned charcount=TaskMap[g_Status].cItemCount;//定位到状态表

for(i=0;i

{

if(*pMsg==TaskMap[g_Status].pMsgItems.msg)//看能否匹配消息

{

TaskMap[g_Status].pMsgItems.pMsgFunc();//找到就执行消息处理函数

return;

}

}

}

void DispatchMessage(unsigned char*pMsg)

{

if(*pMsg)

{

Default_DisposeMessage(pMsg);

}

}

核心函数:消息处理中心

void Message_Dispose_Central(void)

{

BYTE Msg;

while(GetMessage(&Msg)) //获取消息

{

TranslateMessage(&Msg); //解释消息

DispatchMessage(&Msg); //分发消息

}

}

责任编辑:PSY

原文标题:单片机裸奔之状态机浅谈

文章出处:【微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6074

    文章

    45340

    浏览量

    663456
  • 状态机
    +关注

    关注

    2

    文章

    497

    浏览量

    28845

原文标题:单片机裸奔之状态机浅谈

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    睿远研究院丨IO-Link规范解读(十一):ISDU状态机与EVENT事件

    上篇我们介绍了ISDU的典型编码格式和应用案例,本篇我们就来详细介绍下,ISDU的状态机,并把EVENT事件的逻辑,给大家好好解析下。 1主站ISDU状态机 如上图所示,ISDU的状态机的核心
    的头像 发表于 11-29 18:28 2651次阅读
    睿远研究院丨IO-Link规范解读(十一):ISDU<b class='flag-5'>状态机</b>与EVENT事件

    什么是状态机

    什么是状态机状态机(state machine)有5个要素状态(state) 迁移(transition) 事件(event) 动作(action) 条件(guard)
    发表于 11-27 08:15

    嵌入式开发为何经常用到状态机架构

    状态机写的程序要好很多,拿一张标准的UML状态转换图,再配上一些简明的文字说明,程序中的各个要素一览无余。 程序中有哪些状态,会发生哪些事件,状态机
    发表于 11-25 07:08

    睿远研究院丨IO-Link规范解读(八):M-Sequence Type 与消息处理状态机

    丢弃,减少后端工作量。 那么今天我们就来深入研究下,消息处理模块中提到的各类M-Sequence,以及主从站的消息处理状态机!   1 M-Sequence Type 上回讲到主站发出来的MC和CKT
    的头像 发表于 11-07 16:18 5601次阅读
    睿远研究院丨IO-Link规范解读(八):M-Sequence Type 与消息处理<b class='flag-5'>状态机</b>

    睿远研究院丨IO-Link规范解读(六):主从站状态机解析

    前言 书接上文,今天我们就来好好聊聊主从站的DL-Mode状态机,还请各位童鞋前排坐好! 1主站状态机解析 主站的DL-Mode状态机有5个大状态,也是我们很熟悉的 建立通信、开始、预
    的头像 发表于 10-28 17:34 5752次阅读
    睿远研究院丨IO-Link规范解读(六):主从站<b class='flag-5'>状态机</b>解析

    JTAG标准的状态机实现

    JTAG作为一项国际标准测试协议(IEEE1149.1兼容),主要用于芯片内部测试和调试。目前的主流芯片均支持JTAG协议,如DSP、FPGA、ARM、部分单片等。标准的JTAG接口是20Pin,但JTAG实际使用的只有4根信号线,再配合电源、地。
    的头像 发表于 08-21 15:12 2053次阅读
    JTAG标准的<b class='flag-5'>状态机</b>实现

    请问如何在FX10上使用GPIF III状态机 *.h 文件?

    LVCMOS 2 位 SlaveFIFO GPIF III 状态机的演示中有一个 cy_gpif_header_lvcmos.h 文件。 我想知道如何使用.h文件,只需放入.h文件放入 FX10 项目? 您有它的用户指南文档吗?
    发表于 07-16 08:17

    NVMe高速传输之摆脱XDMA设计之十:NVMe初始化状态机设计

    1为NVMe配置初始化状态机状态转移图。各状态的说明如下: 图1NVMe初始化状态转移图 IDLE:空闲状态,复位后的初始
    发表于 07-05 22:03

    NVMe高速传输之摆脱XDMA设计之八:PCIe初始化状态机设计

    PCIe配置初始化状态机实现PCIe设备枚举和配置空间初始化过程,在完成链路训练后,使用DFS(深度优先搜索)算法枚举PCIe总线上的设备,完成PCIe总线域的地址分配和设备的初始化。PCIe配置
    发表于 07-05 22:00

    有可能在 FX3 GPIF2 中创建两个独立的状态机吗?

    我想,如果我想通过 FX3 GPIF2 创建两个独立的传输流接口,我需要在 GPIF2 设计器中创建两个独立的状态机,我是否有可能在 GPIF2 设计器中创建两个独立的状态机
    发表于 05-20 06:14

    cypress3014视频格式改变的话,GPIF状态机需不需要重新配置?

    你好,请问视频格式改变的话,GPIF状态机需不需要重新配置
    发表于 05-14 07:28

    求助,关于srammaster.cydsn中状态机的问题求解

    晚上好。 我目前正在学习 GPIF II。 查看..EZ-USB FX3 SDK1.3firmwaregpif_examplescyfxsrammastersrammaster.cydsn中的状态机,有状态START和START1。 这意味着什么?
    发表于 05-12 06:20

    高速ssd存储系统中数据缓存控制器流程控制设计

    高速SSD系统中流程控制模块设计。该模块主要由寄存器、读状态机、写状态机和命令生成模块组成,系统介绍各模块功能。
    的头像 发表于 04-14 10:43 646次阅读
    高速ssd存储系统中数据缓存控制器流程控制设计

    光刻分类与原理

    本文主要介绍光刻分类与原理。   光刻分类 光刻分类方式很多。按半导体制造工序
    的头像 发表于 01-16 09:29 5720次阅读
    光刻<b class='flag-5'>机</b>的<b class='flag-5'>分类</b>与原理

    Simulink中的状态机建模方法 Simulink数据可视化与分析功能

    1. Simulink中的状态机建模方法 1.1 理解状态机的基本概念 在开始建模之前,了解状态机的基本概念是必要的。状态机由以下几个部分组成:
    的头像 发表于 12-12 09:27 4273次阅读