c语言状态机
引自: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; }