电子说
之前写过一篇状态机的实用文章,很多朋友说有几个地方有点难度不易理解,今天给大家换种简单写法,使用函数指针的方法实现状态机。
状态机简介
有限状态机FSM是有限个状态及在这些状态之间的转移和动作等行为的数学模型,是一种逻辑单元内部的高效编程方法,可以根据不同状态或者消息类型进行相应的处理逻辑,使得程序逻辑清晰易懂。
函数指针实现FSM
使用函数指针实现FSM可以分为3个步骤
建立相应的状态表和动作查询表
根据状态表、事件、动作表定位相应的动作处理函数
执行完成后再进行状态的切换
代码实现步骤
定义状态数据的枚举类型
typedef enum { state_1=1, state_2, state_3, state_4 }State;
定义事件的枚举类型
typedef enum{ event_1=1, event_2, event_3, event_4, event_5 }EventID;
定义状态表的数据类型
typedef struct { int event; //事件 int CurState; //当前状态 void (*eventActFun)(); //函数指针 int NextState; //下一个状态 }StateTable;
定义处理函数及建立状态表
void f121() { printf("this is f121 "); } void f221() { printf("this is f221 "); } void f321() { printf("this is f321 "); } void f122() { printf("this is f122 "); } StateTable fTable[] = { //{到来的事件,当前的状态,将要要执行的函数,下一个状态} { 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 }, //add your code here };
状态机类型,及状态机接口函数
/*状态机类型*/ typedef struct { int curState;//当前状态 StateTable * stateTable;//状态表 int size;//表的项数 }fsmType; /*状态机注册,给它一个状态表*/ void fsmRegist(fsmType* pFsm, StateTable* pTable) { pFsm->stateTable = pTable; } /*状态迁移*/ void fsmStateTransfer(fsmType* pFsm, int state) { pFsm->curState = state; } /*事件处理*/ void fsmEventHandle(fsmType* pFsm, int event) { StateTable* pActTable = pFsm->stateTable; void (*eventActFun)() = NULL; //函数指针初始化为空 int NextState; int CurState = pFsm->curState; int maxNum = pFsm->size; int flag = 0; //标识是否满足条件 /*获取当前动作函数*/ for (int i = 0; i
附代码
代码直接复制过去就行啦,本想打包的,太麻烦了。
测试程序
//编译器:http://www.dooccn.com/cpp/ //来源:技术让梦想更伟大 //作者:李肖遥 #include
编译结果
总结
使用函数指针实现的FSM的过程还是比较费时费力的,但是这一切相对一大堆的if/else、switch/case来说都是值得的,当你的程序规模变得越来越大的时候,基于这种表结构的状态机,维护程序起来会清晰很多。
原文标题:【编程之美】函数指针方法实现简单状态机(附代码)
文章出处:【微信公众号:玩转单片机】欢迎添加关注!文章转载请注明出处。
责任编辑:haq
全部0条评论
快来发表一下你的评论吧 !