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

    文章

    3623

    浏览量

    93797
  • 函数
    +关注

    关注

    3

    文章

    4333

    浏览量

    62721
  • 指针
    +关注

    关注

    1

    文章

    480

    浏览量

    70580

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

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

收藏 人收藏

    评论

    相关推荐

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

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

    触发器和状态机的关系是什么

    触发器和状态机在数字威廉希尔官方网站 设计中有着紧密的关系,它们共同构成了时序逻辑威廉希尔官方网站 的基础,用于实现数据的存储、处理和传输。
    的头像 发表于 08-12 11:24 480次阅读

    面试常考+1:函数指针指针函数、数组指针指针数组

    在嵌入式开发领域,函数指针指针函数、数组指针指针数组是一些非常重要但又容易混淆的概念。理解它
    的头像 发表于 08-10 08:11 912次阅读
    面试常考+1:<b class='flag-5'>函数</b><b class='flag-5'>指针</b>与<b class='flag-5'>指针</b><b class='flag-5'>函数</b>、数组<b class='flag-5'>指针</b>与<b class='flag-5'>指针</b>数组

    如何在FPGA中实现状态机

    在FPGA(现场可编程门阵列)中实现状态机是一种常见的做法,用于控制复杂的数字系统行为。状态机能够根据当前的输入和系统状态,决定下一步的动作和新的状态。这里,我们将详细探讨如何在FPG
    的头像 发表于 07-18 15:57 637次阅读

    玩转Spring状态机

    说起Spring状态机,大家很容易联想到这个状态机和设计模式中状态模式的区别是啥呢?没错,Spring状态机就是状态模式的一种
    的头像 发表于 06-25 14:21 968次阅读
    玩转Spring<b class='flag-5'>状态机</b>

    关于SMU状态机的问题求解

    我有一些关于 SMU 状态机的问题。 假设由于某种原因,SMU 已进入故障状态。 手册指出,要返回运行状态并将 FSP 恢复到无故障状态,应调用IfxSmu_releaseFSP()。
    发表于 05-29 08:18

    在Verilog中实现Moore型和Mealy型状态机方法简析

    编写能够被综合工具识别的状态机,首先需要理解状态机的基本概念和分类。状态机(FSM)是表示有限个状态以及在这些状态之间转换的逻辑结构。
    的头像 发表于 05-01 11:38 1679次阅读

    C语言函数指针六大应用场景详解

    函数指针是一种非常强大的编程工具,它可以让我们以更加灵活的方式编写程序。在本文中,我们将介绍 6 个函数指针的高级应用场景,并贴出相应的代码案例和解释。
    的头像 发表于 04-23 18:19 903次阅读

    嵌入式编程,如何用 C 语言实现状态机设计?

    状态机模式是一种行为模式,通过多态实现不同状态的调转行为的确是一种很好的方法,只可惜在嵌入式环境下,有时只能写纯C代码,并且还需要考虑代码的重入和多任务请求跳转等情形,因此
    发表于 04-23 11:00

    求助LabVIEW,状态机里面反馈节点如何初始化问题

    求助labview,状态机里面反馈节点如何初始化,下次执行这个状态的时候初始化一次!谢谢谢谢!
    发表于 03-25 18:17

    如何采用“状态机”解析UART数据帧

    如果一个系统接收上述“不定长度”的协议帧,将会有一个挑战--如何高效接收与解析。 为简化系统设计,我们强烈建议您采用“状态机”来解析UART数据帧。
    的头像 发表于 03-25 14:29 727次阅读
    如何采用“<b class='flag-5'>状态机</b>”解析UART数据帧

    函数指针与回调函数的应用实例

    通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数函数指针
    的头像 发表于 03-07 11:13 411次阅读
    <b class='flag-5'>函数</b><b class='flag-5'>指针</b>与回调<b class='flag-5'>函数</b>的应用实例

    什么是有限状态机?如何解决传统有限状态机状态爆炸」问题?

    有限状态机(Finite State Machine,简称FSM)是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列以及如何响应来自外界的各种事件。
    的头像 发表于 02-17 16:09 6279次阅读
    什么是有限<b class='flag-5'>状态机</b>?如何解决传统有限<b class='flag-5'>状态机</b>「<b class='flag-5'>状态</b>爆炸」问题?

    Verilog状态机+设计实例

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

    状态机该怎么监控

    状态机卡住的场景——通过状态跳转条件的DFX信号去判断卡住的原因
    的头像 发表于 01-15 10:03 425次阅读
    <b class='flag-5'>状态机</b>该怎么监控