文章目录
一、状态机实现
1. 事件入栈
uint8_t Fsm_EventPost(FSM_st *p_Fsm,uint8_t Event)
{
if(NULL == p_Fsm)
{
return FALSE;
}
p_Fsm->EventQueue[p_Fsm->EventWrite] = Event;
p_Fsm->EventWrite = (p_Fsm->EventWrite+1)% FSM_MAX_EVENT;
return TRUE;
}
2. 事件出栈,一般在事件执行时调用
static uchar Fsm_EventGet(FSM_st *p_Fsm)
{
uint8_t RetEvent = FSM_EVENT_NONE;
if(NULL == p_Fsm)
{
return FSM_EVENT_NONE;
}
if(p_Fsm->EventRead == p_Fsm->EventWrite)
{
return FSM_EVENT_NONE;
}
else
{
RetEvent = p_Fsm->EventQueue[p_Fsm->EventRead];
p_Fsm->EventRead++;
p_Fsm->EventRead %= FSM_MAX_EVENT;
return u8_RetEvent;
}
}
3. 事件执行
void Fsm_Execute(FSM_st *p_Fsm, const state_handle_st *ptbl)
{
uint8_t Ret =FSM_RET_IGNORED;
uint8_t Event = FSM_EVENT_NONE;
if ((NULL == p_Fsm) || ( NULL == ptbl))
{
return;
}
Event = Fsm_EventGet(p_Fsm);
if(NULL != p_Fsm->p_GlobalHandle)
{
Ret = p_Fsm->p_GlobalHandle(Event);
if(FSM_RET_TRAN == Ret)
{
ptbl[p_Fsm->CurState].p_Handle(FSM_EVENT_EXIT);
ptbl[p_Fsm->u8_NextState].p_Handle(FSM_EVENT_ENTER);
p_Fsm->CurState = p_Fsm->NextState;
return;
}
else if (FSM_RET_IGNORED != Ret)
{
return;
}
}
Ret = ptbl[p_Fsm->CurState].p_Handle(Event);
if(FSM_RET_TRAN == Ret)
{
ptbl[p_Fsm->CurState].p_Handle(FSM_EVENT_EXIT);
ptbl[p_Fsm->u8_NextState].p_Handle(FSM_EVENT_ENTER);
p_Fsm->CurState = p_Fsm->NextState;
return;
}
}
4. 状态切换
uint8_t Fsm_StateTrans(FSM_st *p_Fsm, uint8_t State)
{
if(NULL == p_Fsm)
{
return FSM_EVENT_NONE;
}
p_Fsm->NextState = State;
return (FSM_RET_TRAN);
}
二、状态机应用-实例化状态机
举例: 针对闹钟功能
1. 列出所有状态
typedef enum
{
STATE_SETTING, //闹钟时间设置
STATE_TICK //倒计时中
}State_type;
2. 列出所有事件
typedef enum
{
//进入和退出 一般是执行完当前状态的事件后进入下一个状态时调用
EVENT_ENTER,
EVENT_EXIT,
EVENT_UP, //按键加 计时加一小时
EVENT_DOWN, //按键减 计时减一小时
EVENT_ENTER //确认键
}Event_type;
3. 定义状态列表
typedef struct
{
uint8_t State; //状态
uint8_t (*p_Handle)(uint8_t Event); //状态执行函数 参数是事件
}state_handle_st;
const state_handle_st Func_tbl[2] =
{
{STATE_SETTING, Setting_Handle},
{STATE_TICK , Tick_Handle},
};
static uint8_t Setting_Handle(uint8_t Event)
{
switch
}
static uint8_t Tick_Handle(uint8_t Event)
{
}