2014-02-16 有限状态机——管中窥豹

来源:互联网 发布:sql with cte as 编辑:程序博客网 时间:2024/04/26 15:40

         在编程过程中经常使用有限状态机(FSM)解决逻辑问题。状态机不仅仅是VHDL的东西,可以说它是嵌入式编程的万能语言,更是一种可以用于各个方面的思维方式。使用状态机可以解耦各个逻辑模块,使编程思路清晰。一个典型的有限状态机结构如下:

[FSM.h]

#ifndef __FSM_H__#define __FSM_H__#include "evmdm6437.h"#include "stdio.h"#include "string.h"#define DEBUG_PRINT_FSM#ifndef TRUE#define TRUE1#endif#ifndef FALSE#define FALSE0#endif#define SCREEM_STATE_TIMEOUT10000#define FRONT_STATE_TIMEOUT60000typedef enum _FSM_Return{    FSM_Run = 1,    FSM_Stop = 0,    FSM_Timeout = 2}FSM_Return;//使用联合体减小内存,MISRA C标准不建议这样使用,可以修改为“移位”typedef union _FSM_Flag{    Uint32     iValue;    struct {        unsigned FSM_STATE_A:1;        unsigned FSM_STATE_B:1;        unsigned FSM_STATE_C:1;    }Bits_Flag;}FSM_Flag;typedef struct _Timeout{    unsigned long TimeStart;    Uint32 iTimeFlag;}Timeout;typedef enum _FSM_Result{    FSM_IDLE = 0,FSM_A,    FSM_B,    FSM_C}FSM_Result;#endif

[FSM.c]

#include "FSM.h"#define FSM_STOP_ALL_ACTIONS()do {unState_Flag.Value = 0;}while(0)static FSM_Result FSM = FSM_A;Uint32 FSM_EX(FSM_Input* Input){    static FSM_Flag unState_Flag = {0};static Timeout FSM_D_Timeout = {0};static Timeout FSM_A_Timeout = {0};static Uint32 FSM_Start = 0;/* 获取输入,根据输入信息判断状态切换 */...    /* 状态机初始化*/if (!FSM_Start){   ...   unState_Flag.Bits_Flag.FSM_STATE_SCREEM = TRUE;    }if(unState_Flag.Bits_Flag.FSM_STATE_A)    {        FSM_Start = TRUE;FSM = FSM_C;if(/* 判断条件 */)        {unState_Flag.Bits_Flag.FSM_STATE_B = TRUE;unState_Flag.Bits_Flag.FSM_STATE_C = TRUE;        }        else if(/* 判断条件 */){unState_Flag.Bits_Flag.FSM_STATE_A = FALSE;}    }    if (unState_Flag.Bits_Flag.FSM_STATE_B)    {        FSM = FSM_B;        if (/* 判断条件 */){            FSM_STOP_ALL_ACTIONS();            unState_Flag.Bits_Flag.FSM_STATE_C = TRUE;}    }    if (unState_Flag.Bits_Flag.FSM_STATE_C)    {        FSM = FSM_C;        if(/* 判断条件 */){unState_Flag.Bits_Flag.FSM_STATE_A = TRUE;}        else if(/* 判断条件 */){FSM_STOP_ALL_ACTIONS();            unState_Flag.Bits_Flag.FSM_STATE_STOP = TRUE;}    }.../* 退出状态机 */    if (unState_Flag.Bits_Flag.FSM_STATE_STOP)    {        FSM_STOP_ALL_ACTIONS();        return FSM_Stop;    }    return FSM_Run;}FSM_Result * Get_FSM_Result(){return &FSM;}

注:上边的代码只是为了说明一种思路,不保证在任何平台都能编译通过

与使用switch case相比,使用if esle设计状态机会更加灵活,可以自由的控制多种状态开启或关闭。

0 0
原创粉丝点击