状态机原理

状态机有4个要素:

  • 现态:是指当前所处的状态。
  • 条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
  • 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
  • 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了

举例:

STATE1是现态,STATE2是次态,EVENT是条件,action是动作。当产生EVENT时,触发action,action执行完毕后从STATE1迁移到STATE2,此时,STATE2为现态。

在这个例子中,action只是一个瞬时执行的动作,它只在现态迁移到次态的过程中执行,当迁移完成后,action不再执行。

对以上状态机模型进行改进:

STATE1是现态,STATE2是次态,EVENT是条件,动作分为entry、do、exit三步,而且STATE1和STATE2都有动作entry、do、exit(注意:STATE1中的entry、do、exit和STATE2中的entry、do、exit不是同一个东西,可以将STATE1理解为一个结构体变量,而entry、do、exit是结构体的元素)。假设现在没有触发条件EVENT,现态STATE1持续执行do动作(注意:持续执行的意思不止执行一次),直到触发条件EVENT产生,此时STATE1不再执行do动作,而是执行exit动作,执行完后执行STATE2中的entry动作,并将现态更新为STATE2,STATE2持续执行do动作。

改进后的状态机模型有很多好处,举个例子:如在STATE1这个状态下对计数器COUNT进行计数,使用改进后的状态机模式可以这样做:
(1)在STATE1的entry里面对COUNT进行初始化
(2)在STATE1的do里面对COUNT进行计数
(3)在STATE1的exit里面对COUNT进行复位

C语言实现状态机

假设有状态机流程图如图:


定义枚举类型STATE_t表示状态机状态:

typedef enum{STATE1 = 0,STATE2,STATE3,STATE4,
}STATE_t;

定义ACTION_MAP_t结构体类型,表示状态机状态属性:

typedef void (*STATE_ACTION)(void);
typedef struct ACTION_MAP
{STATE_t        stStateID;STATE_ACTION  EnterAct;   STATE_ACTION    RunningAct; STATE_ACTION    ExitAct;
}ACTION_MAP_t;

建立“动作”表:

void state1_entry(void)
{printf("state1_entry\n");
}
void state1_do(void)
{printf("state1_do\n");
}
void state1_exit(void)
{printf("state1_exit\n");
}void state2_entry(void)
{printf("state2_entry\n");
}
void state2_do(void)
{printf("state2_do\n");
}
void state2_exit(void)
{printf("state1_exit\n");
}void state3_entry(void)
{printf("state3_entry\n");
}
void state3_do(void)
{printf("state3_do\n");
}
void state3_exit(void)
{printf("state3_exit\n");
}void state4_entry(void)
{printf("state4_entry\n");
}
void state4_do(void)
{printf("state4_do\n");
}
void state4_exit(void)
{printf("state4_exit\n");
}
ACTION_MAP_t actionMap[] =
{{STATE1,   state1_entry,   state1_do,  state1_exit},{STATE2,   state2_entry,   state2_do,  state2_exit},{STATE3,   state3_entry,   state3_do,  state3_exit},{STATE4,   state4_entry,   state4_do,  state4_exit},
};

定义枚举类型EVENT_t表示事件:

typedef enum
{EVENT1 = 0,EVENT2,EVENT3,EVENT4,EVENT5,EVENT_MAP_END
}EVENT_t;

注:定义EVENT_MAP_END的目的是为了方便查表。

定义EVENT_MAP_t结构体类型,表示事件表属性:

typedef struct EVENT_MAP
{EVENT_t    stEventID;STATE_t stCurState;STATE_t stNextState;
}EVENT_MAP_t;

根据状态机流程图建立事件表:

EVENT_MAP_t eventMap[] =
{{EVENT1,   STATE1, STATE2},{EVENT2,    STATE2, STATE3},    {EVENT3,    STATE3, STATE4},{EVENT4,    STATE4, STATE1},{EVENT5,    STATE1, STATE4},{EVENT_MAP_END, 0,  0},
};

定义状态机结构体类型:

typedef struct FSM
{STATE_t stCurState;STATE_t stNextState;ACTION_MAP_t *pActionMap;EVENT_MAP_t *pEventMap;
}FSM_t;

定义状态机注册函数:

void fsm_init(FSM_t* pFsm,EVENT_MAP_t* pEventMap,ACTION_MAP_t *pActionMap)
{pFsm->stCurState = 0;pFsm->stNextState = EVENT_MAP_END;pFsm->pEventMap = pEventMap;pFsm->pActionMap = pActionMap;
}

定义状态机转换函数:

void fsm_state_transfer(FSM_t* pFsm, EVENT_t stEventID)
{uint8_t i = 0;for(i=0; pFsm->pEventMap[i].stEventID<EVENT_MAP_END; i++){if((stEventID == pFsm->pEventMap[i].stEventID) && (pFsm->stCurState == pFsm->pEventMap[i].stCurState)){pFsm->stNextState = pFsm->pEventMap[i].stNextState;return;}}
}

定义动作执行函数:

void action_perfrom(FSM_t* pFsm)
{if(EVENT_MAP_END != pFsm->stNextState){pFsm->pActionMap[pFsm->stCurState].ExitAct();pFsm->pActionMap[pFsm->stNextState].EnterAct();pFsm->stCurState = pFsm->stNextState;pFsm->stNextState = EVENT_MAP_END;}else{pFsm->pActionMap[pFsm->stCurState].RunningAct();}
}

测试:

int main(void)
{int i = 0;        FSM_t stFsmWeather; //定义状态机fsm_init(&stFsmWeather,eventMap,actionMap);  //注册状态机while(1){usleep(10);printf("i = %d\n",i++);action_perfrom(&stFsmWeather);//利用i产生EVENT1~EVENT5if(0 == (i%11)){fsm_state_transfer(&stFsmWeather,EVENT1);}if(0 == (i%31)){fsm_state_transfer(&stFsmWeather,EVENT2);}if(0 == (i%74)){fsm_state_transfer(&stFsmWeather,EVENT3);}if(0 == (i%13)){fsm_state_transfer(&stFsmWeather,EVENT4);}   if(0 == (i%19)){fsm_state_transfer(&stFsmWeather,EVENT5);}}return 0;
}

https://blog.csdn.net/qq_36969264/article/details/122365696

C语言实现状态机(一)相关推荐

  1. 设计模式的C语言应用-状态机模式-第二章

    模式介绍 状态(state)模式是C语言实现相当常用的模式,也是能够在C语言***现出来的最显性的模式之一.在面向对象里,状态模式允许一个对象在内部状态改变的时候改变其行为. 状态用法很多,最常见的是 ...

  2. C语言实现状态机(二)

    前言 对于之前的一篇博客<C语言实现状态机>(链接:https://blog.csdn.net/qq_36969264/article/details/105865099?spm=1001 ...

  3. 基于VHDL语言的状态机设计

    基于VHDL语言的状态机(FSM)设计 状态机(Finite State Machine,FSM) 状态机的组成:如图所示 状态机的种类: Mealy型:当前状态.当前输入相关 Moore型:仅当前状 ...

  4. c语言按键状态机,C语言状态机编程思想

    原标题:C语言状态机编程思想 有限状态机概念 有限状态机是一种概念思想,把复杂的控制逻辑分解成有限个稳定状态,组成闭环系统,通过事件触发,让状态机按设定的顺序处理事务.单片机C语言的状态机编程,是利用 ...

  5. <C语言>C语言实现状态机

    C语言实现状态机 ​ 状态机模式适用于有限状态下程序按照逻辑循环执行,相较于在while循环中通过if else判断状态标志来执行相应的动作,状态机模式能够灵活的增加.减少状态,程序逻辑更为清晰 ​ ...

  6. C语言用状态机来实现简单的密码开锁

    功能描述:用户连续输入正确的密码则会开锁,如果密码输入过程错误则锁会退回到初始状态,重新键入密码,即:用户只需要连续输入正确的密码即可开锁(输入错误不用撤销.也不用删除) 以上的分析和下面的代码来自& ...

  7. 语言用加法实现加饭运算_「编程之美」用C语言实现状态机(超实用)

    关于状态机,基础的知识点可以自行理解,讲解的很多,这里主要是想写一个有限状态机FSM通用的写法,目的在于更好理解,移植,节省代码阅读与调试时间,体现出编程之美. 传统的实现方案 if...else : ...

  8. c语言中状态机的作用,C语言中的状态机

    用C编写状态机的最佳方法是什么? 我通常在for(;;)中编写一个大的switch-case语句,并使用回调在外部操作完成后重新进入状态机. 您知道更有效的方法吗? 这似乎是一种非常标准的实现方法. ...

  9. C语言--实现状态机

    关于状态机,基础的知识点可以自行理解,讲解的很多,这里主要是想写一个有限状态机FSM通用的写法,目的在于更好理解,移植,节省代码阅读与调试时间,体现出编程之美. 传统的实现方案 if...else : ...

最新文章

  1. Assembly and diploid architecture of an individual human genome via single-molecule technologies
  2. ASP.NET MVC WebAPI实现文件批量上传
  3. 设置TextField内文字距左边框的距离
  4. 【树莓派】树莓派(Debian)- root用户无法使用SSH登录
  5. Java 多线程 通信 通道 (猫狗赛跑)
  6. 伏安特性曲线实验报告_【鼎阳硬件智库原创 | 测试测量】动手测量电解电容器的阻抗频率特性...
  7. python编程入门书籍-编程小白的第一本 Python 入门书
  8. eclipse创建测试apk文件的测试工程,报错java.lang.NullPointerException
  9. 【倒计时】用JS写出京东倒计时效果
  10. android 自动打开钉钉,安卓定时自动打开钉钉考勤打卡
  11. 自然语言处理中的伪数据 by哈工大教授车万翔
  12. USB接口类型及引脚定义-usb1.0,usb2.0,usb3.0,Type-c
  13. 奇异值分解推导详解以及几何意义
  14. win10计算机升级系统,微软Win10升级助手
  15. 电子计算机显示屏不亮了,手把手教你电脑显示器不亮怎么办
  16. KVM-1、Linux 操作系统及虚拟化
  17. 代码写一半感觉无从下手,写不下去了,怎么办?
  18. Apsara Clouder基础技能认证:阿里巴巴编码规范相关问题总结
  19. python使用163邮箱发送邮件
  20. 复制文件或文件夹时出错(无法复制***:没有足够的可用磁盘空间。) .

热门文章

  1. BCJC43:发展到遍地开花的实验室将何去何从
  2. CFA是什么证书?有什么用?
  3. 【易购管理系统】路由界面基础搭建
  4. 搜书利器 -- 壹搜网
  5. 【预测模型-ELM预测】基于布谷鸟算法优化极限学习机预测matlab代码
  6. 天猫618收官之时,马云张勇在哪?
  7. 【12】linux命令每日分享——echo命令为用户添加密码
  8. 弧度 和 角度的理解, 以及相互转换
  9. 【Android】技巧之像素换算
  10. 画论70 华琳《南宗抉秘》