嵌入式C语言表驱动状态机
嵌入式中比较经常使用状态机模式,使用if else 和 switch case 出现比较多的状态时,这种方法实现的状态机可读性和可塑性比较差
本章使用表驱动方法解决上述的问题
以下代码参考博主:大白白
https://zhuanlan.zhihu.com/p/530280333
一维数组表驱动状态机实现
把 current state – event – operation() – next state 的组合作为一个对象,用StateProcessor驱动状态迁移
main.c文件
#include <stdio.h>
#include "led_stata_machine.h"
int main() {
StateProcessor(OpenState, LongPressButton);
StateProcessor(CloseState, ShortPressButton);
StateProcessor(OpenState, FreeOver5Mins);
StateProcessor(SleepState, ShortPressButton);
return 0;
}
led_stata_machine.c文件
#include <stdio.h>
#include "led_stata_machine.h"
void closeing(void)
{
printf("正在关灯\n");
}
void opening(void)
{
printf("正在开灯\n");
}
void sleeping(void)
{
printf("正在熄灯\n");
}
struct State g_fsm[] = {
{
OpenState, //当前状态
LongPressButton, //事件
closeing, //实现函数
CloseState //下一个状态
},
{
CloseState,
ShortPressButton,
opening,
OpenState,
},
{
OpenState,
FreeOver5Mins,
sleeping,
SleepState,
},
{
SleepState,
ShortPressButton,
opening,
OpenState,
},
};
#define G_FSM_ITEM_NUM sizeof(g_fsm)/sizeof(g_fsm[0])
// 定义StateProcessor(),驱动状态迁移
int StateProcessor(int currentState, int event)
{
for (int i = 0; i < G_FSM_ITEM_NUM; i++)
{
if ((currentState == g_fsm[i].currentState) && (event == g_fsm[i].event))
{
g_fsm[i].Operation();
return g_fsm[i].nextState;
}
}
// 状态切换失败,保持当前状态
return currentState;
}
led_stata_machine.h
#ifndef LED_STATA_MACHINE_H
#define LED_STATA_MACHINE_H
/**
* 状态
*
*/
enum StateEnum
{
OpenState,
CloseState,
SleepState,
};
/**
* 事件
*/
enum EventEnum
{
LongPressButton,
ShortPressButton,
FreeOver5Mins,
};
/**
* 当前状态
* 事件
* 实现功能函数
* 下一个状态
*/
struct State
{
int currentState; // enum StateEnum
int event; // enum EventEnum
void (*Operation)();
int nextState; // enum StateEnum
};
void closeing(void);
void opening(void);
void sleeping(void);
extern int StateProcessor(int currentState, int event);
#endif