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

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

3天内不再提示

使用函数指针的方法实现状态机

GReq_mcu168 来源:玩转单片机 作者:玩转单片机 2020-10-19 09:36 次阅读

之前写过一篇状态机的实用文章,很多朋友说有几个地方有点难度不易理解,今天给大家换种简单写法,使用函数指针的方法实现状态机。

状态机简介

有限状态机FSM是有限个状态及在这些状态之间的转移和动作等行为的数学模型,是一种逻辑单元内部的高效编程方法,可以根据不同状态或者消息类型进行相应的处理逻辑,使得程序逻辑清晰易懂。

函数指针实现FSM

使用函数指针实现FSM可以分为3个步骤

建立相应的状态表和动作查询表

根据状态表、事件、动作表定位相应的动作处理函数

执行完成后再进行状态的切换

代码实现步骤

定义状态数据的枚举类型

typedefenum{ state_1=1, state_2, state_3, state_4 }State;

定义事件的枚举类型

typedefenum{ event_1=1, event_2, event_3, event_4, event_5 }EventID;

定义状态表的数据类型

typedefstruct { intevent;//事件 intCurState;//当前状态 void(*eventActFun)();//函数指针 intNextState;//下一个状态 }StateTable;

定义处理函数及建立状态表

voidf121() { printf("thisisf121 "); } voidf221() { printf("thisisf221 "); } voidf321() { printf("thisisf321 "); } voidf122() { printf("thisisf122 "); } StateTablefTable[]= { //{到来的事件,当前的状态,将要要执行的函数,下一个状态} {event_1,state_1,f121,event_2}, {event_2,state_2,f221,event_3}, {event_3,state_3,f321,event_4}, {event_4,state_4,f122,event_1}, //addyourcodehere };

状态机类型,及状态机接口函数

/*状态机类型*/ typedefstruct{ intcurState;//当前状态 StateTable*stateTable;//状态表 intsize;//表的项数 }fsmType; /*状态机注册,给它一个状态表*/ voidfsmRegist(fsmType*pFsm,StateTable*pTable) { pFsm->stateTable=pTable; } /*状态迁移*/ voidfsmStateTransfer(fsmType*pFsm,intstate) { pFsm->curState=state; } /*事件处理*/ voidfsmEventHandle(fsmType*pFsm,intevent) { StateTable*pActTable=pFsm->stateTable; void(*eventActFun)()=NULL;//函数指针初始化为空 intNextState; intCurState=pFsm->curState; intmaxNum=pFsm->size; intflag=0;//标识是否满足条件 /*获取当前动作函数*/ for(inti=0;i

附代码

代码直接复制过去就行啦,本想打包的,太麻烦了。

测试程序

//编译器:http://www.dooccn.com/cpp/ //来源:技术让梦想更伟大 //作者:李肖遥 #include typedefenum{ state_1=1, state_2, state_3, state_4 }State; typedefenum{ event_1=1, event_2, event_3, event_4, event_5 }EventID; typedefstruct{ intevent;//事件 intCurState;//当前状态 void(*eventActFun)();//函数指针 intNextState;//下一个状态 }StateTable; voidf121() { printf("thisisf121 "); } voidf221() { printf("thisisf221 "); } voidf321() { printf("thisisf321 "); } voidf122() { printf("thisisf122 "); } StateTablefTable[]= { //{到来的事件,当前的状态,将要要执行的函数,下一个状态} {event_1,state_1,f121,event_2}, {event_2,state_2,f221,event_3}, {event_3,state_3,f321,event_4}, {event_4,state_4,f122,event_1}, //addyourcodehere }; /*状态机类型*/ typedefstruct{ intcurState;//当前状态 StateTable*stateTable;//状态表 intsize;//表的项数 }fsmType; /*状态机注册,给它一个状态表*/ voidfsmRegist(fsmType*pFsm,StateTable*pTable) { pFsm->stateTable=pTable; } /*状态迁移*/ voidfsmStateTransfer(fsmType*pFsm,intstate) { pFsm->curState=state; } /*事件处理*/ voidfsmEventHandle(fsmType*pFsm,intevent) { StateTable*pActTable=pFsm->stateTable; void(*eventActFun)()=NULL;//函数指针初始化为空 intNextState; intCurState=pFsm->curState; intmaxNum=pFsm->size; intflag=0;//标识是否满足条件 /*获取当前动作函数*/ for(inti=0;i

编译结果

总结

使用函数指针实现的FSM的过程还是比较费时费力的,但是这一切相对一大堆的if/else、switch/case来说都是值得的,当你的程序规模变得越来越大的时候,基于这种表结构的状态机,维护程序起来会清晰很多。

原文标题:【编程之美】函数指针方法实现简单状态机(附代码)

文章出处:【微信公众号:玩转单片机】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

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

    关注

    88

    文章

    3441

    浏览量

    92412
  • 函数
    +关注

    关注

    3

    文章

    3903

    浏览量

    61310
  • 指针
    +关注

    关注

    1

    文章

    473

    浏览量

    70364

原文标题:【编程之美】函数指针方法实现简单状态机(附代码)

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Verilog状态机+设计实例

    在verilog中状态机的一种很常用的逻辑结构,学习和理解状态机的运行规律能够帮助我们更好地书写代码,同时作为一种思想方法,在别的代码设计中也会有所帮助。 一、简介 在使用过程中我们常说
    的头像 发表于 02-12 19:07 2012次阅读
    Verilog<b class='flag-5'>状态机</b>+设计实例

    函数指针指针函数是不是一个东西?

    函数指针的本质是指针,就跟整型指针、字符指针一样,函数指针
    的头像 发表于 01-03 16:35 266次阅读
    <b class='flag-5'>函数</b><b class='flag-5'>指针</b>和<b class='flag-5'>指针</b><b class='flag-5'>函数</b>是不是一个东西?

    Spring状态机实现原理和使用方法

    说起 Spring 状态机,大家很容易联想到这个状态机和设计模式中状态模式的区别是啥呢?没错,Spring 状态机就是状态模式的一种
    的头像 发表于 12-26 09:39 977次阅读
    Spring<b class='flag-5'>状态机</b>的<b class='flag-5'>实现</b>原理和使用<b class='flag-5'>方法</b>

    C语言实现状态机的主要3种方法

    事件的类型和状态机当前的状态可以让我们在图 4 的表格中迅速定位,确定该调用哪个动作封装函数, 但是动作封装函数要正确响应事件还需要知道事件的内容是什么, 这也就是形参pEvnt 的意
    的头像 发表于 11-06 12:20 856次阅读
    C语言<b class='flag-5'>实现状态机</b>的主要3种<b class='flag-5'>方法</b>

    什么是状态机状态机的种类与实现

    状态机,又称有限状态机(Finite State Machine,FSM)或米利状态机(Mealy Machine),是一种描述系统状态变化的模型。在芯片设计中,
    的头像 发表于 10-19 10:27 5063次阅读

    如何使用FSME来定制状态机

    本身相关的那些处理逻辑。在FSME中,与具体应用相关的操作称为输出(Output),它们实际上就是一些需要用户给出具体实现的虚函数,自动生成的状态机引擎负责在进入或者退出某个状态时调用
    的头像 发表于 09-13 16:57 883次阅读
    如何使用FSME来定制<b class='flag-5'>状态机</b>

    如何生成状态机框架

    生成状态机框架 使用FSME不仅能够进行可视化的状态机建模,更重要的是它还可以根据得到的模型自动生成用C++或者Python实现状态机框架。首先在FSME界面左边的树形列表中选择"R
    的头像 发表于 09-13 16:54 653次阅读
    如何生成<b class='flag-5'>状态机</b>框架

    自动生成程序状态机代码状态机建模方法

    首先运行fsme命令来启动状态机编辑器,然后单击工具栏上的“New”按钮来创建一个新的状态机。FSME中用于构建状态机的基本元素一共有五种:事件(Event)、输入(Input)、输出(Output
    的头像 发表于 09-13 16:50 733次阅读
    自动生成程序<b class='flag-5'>状态机</b>代码<b class='flag-5'>状态机</b>建模<b class='flag-5'>方法</b>

    一文详解函数指针与回调函数

    函数指针是指向函数指针变量。它允许我们将函数作为参数传递给其他函数或将
    发表于 08-22 10:36 191次阅读

    状态机的三种实现模式(C语言实现状态机的三种方法

    压缩表格驱动法的实质就是一个整数值(状态机的一个状态)到一个函数地址(动作封装函数)的一对一映射, 压缩表格驱动法的驱动表格就是全部映射关系的直接载体。在驱动表格中通过
    发表于 07-25 10:27 1658次阅读
    <b class='flag-5'>状态机</b>的三种<b class='flag-5'>实现</b>模式(C语言<b class='flag-5'>实现状态机</b>的三种<b class='flag-5'>方法</b>)

    如何在FPGA中实现状态机

    状态机往往是FPGA 开发的主力。选择合适的架构和实现方法将确保您获得一款最佳解决方案。 FPGA 常常用于执行基于序列和控制的行动, 比如实现一个简单的通信协议。对于设计人员来说,满
    的头像 发表于 07-18 16:05 602次阅读
    如何在FPGA中<b class='flag-5'>实现状态机</b>

    状态机编程实例-面向对象的状态设计模式

    本编介绍了状态机编程的第3种方法——面向对象的状态设计模式,通过C++的继承特性,以及类指针实现炸弹拆除小游戏中的
    的头像 发表于 06-28 09:04 923次阅读
    <b class='flag-5'>状态机</b>编程实例-面向对象的<b class='flag-5'>状态</b>设计模式

    状态机实现哪些内容

    状态机模式是一种行为模式,通过多态实现不同状态的调转行为的确是一种很好的方法,只可惜在嵌入式环境下,有时只能写纯C代码,并且还需要考虑代码的重入和多任务请求跳转等情形,因此
    的头像 发表于 06-22 14:26 455次阅读
    <b class='flag-5'>状态机</b>要<b class='flag-5'>实现</b>哪些内容

    状态机编程实例-状态表法

    上篇文章,使用嵌套switch-case法的状态机编程,实现了一个炸弹拆除小游戏。本篇,继续介绍状态机编程的第二种方法状态表法,来
    的头像 发表于 06-20 09:05 1262次阅读
    <b class='flag-5'>状态机</b>编程实例-<b class='flag-5'>状态</b>表法

    C语言进阶:函数指针的概念和使用方法

    函数指针是指向函数指针变量。 通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数
    发表于 05-02 06:17 5066次阅读