首页 > 其他分享 >c语言状态机

c语言状态机

时间:2023-02-21 19:57:36浏览次数:35  
标签:MAP 语言 void 状态机 STATE printf pfsm EVENT

引自:https://blog.csdn.net/qq_36969264/article/details/105865099

// state_machine.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
* 1. 确定状态机状态数 State(枚举)
* 2. 确定引起状态转化的事件类型数 Event(枚举)
* 3. 初始化各个状态下的动作表与事件表
* 4. 建立状态机属性结构体,包括:当前状态 current state ;下一状态 next state;动作表: action[];事件表:event[]
* 
* 6. 状态机的初始化
* 7. 状态转换函数
* 8. 动作执行函数
*/
/*例如:以下4状态状态机
*  -----状态1 --事件1-->状态2
*  |      /\               |
*  |       |               |
* 事件5   事件4          事件2
*  |       |               |
*  |       |               \/
*  ----->状态4<--事件3--状态3
* 
*/

#include <iostream>

using namespace std;

//定义枚举类型STATES_t 表示状态机状态数
typedef enum {
    STATE1 = 0,
    STATE2,
    STATE3,
    STATE4,
    STATE_IDLE
} STATE_t;

//定义枚举类型EVENT_t表示事件
typedef enum {
    EVENT1 = 0,
    EVENT2,
    EVENT3,
    EVENT4,
    EVENT5,
    EVENT_MAP_END //其他事件
}EVENT_t;

//定义函数指针,指向当前状态机动作
typedef void (*STATE_ACTION)(void);

//定义ACTION_MAP_t,记录当前状态下的动作
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("state2_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");
}

void stateIDLE(void)
{
    printf("idle time\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},
    {STATE_IDLE,stateIDLE,stateIDLE,stateIDLE},
};
//定义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,STATE1,STATE1}
};

//建立状态属性结构体
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, ACTION_MAP_t* pActionMap, EVENT_MAP_t* peventMap) {
    pfsm->stCurState = pfsm->stCurState;
    pfsm->stNextState = STATE_IDLE;
    pfsm->pActionMap = pActionMap;
    pfsm->peventMap = peventMap;
}
//定义状态机转换函数,根据事件类型与当前状态判断下一状态指向
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++)
    {   //同时判断事件ID号与当前状态状态,避免事件类型相同时发生误判
        if ((stEventID == pfsm->peventMap[i].stCurState)
            && (pfsm->stCurState == pfsm->peventMap[i].stCurState))
        {
            pfsm->stNextState = pfsm->peventMap[i].stNextState;//确定下一个状态
            return;
        }
    }
}

//动作执行函数
void action_perfrom(FSM_t* pfsm)
{
    if (STATE_IDLE != pfsm->stNextState)
    {
        pfsm->pActionMap[pfsm->stCurState].ExitAct();
        pfsm->pActionMap[pfsm->stNextState].EnterAct();

        pfsm->stCurState = pfsm->stNextState;
        pfsm->stNextState = STATE_IDLE;
    }
    else
    {
        pfsm->pActionMap[pfsm->stCurState].RunningAct();
    }
}


int main()
{
    int i = 0;
    FSM_t stFsmWeather;    //定义状态机
    stFsmWeather.stCurState = STATE1;//定义启动状态
    //结构体中的动作指针与事件指针指向 建立的动作表与事件表
    FSM_INIT(&stFsmWeather, actionMap, eventMap);
    while (1)
    {
        printf("i = %d\n",i++);
        action_perfrom(&stFsmWeather);
        if (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);
        }
    }
    

    system("pause");
    return 0;
}

 

标签:MAP,语言,void,状态机,STATE,printf,pfsm,EVENT
From: https://www.cnblogs.com/ysyyrps-hhl/p/17142184.html

相关文章