作为经常跟单片打交道的选手,对状态应该都不陌生,尤其是会涉及ECU的状态,初始化、运行、休眠等。
而实现这种方式,一般都会用Switch case去完成
switch(EcuState)
{
case EcuInit:
break;
case EcuRun:
break;
case EcuSleep:
break;
default:
break;
}
然后在每个状态里实现对应的 if 逻辑。做出相应的动作。
这种方式是通用的大家比较熟悉的方式。
其实还可以用状态机编程的思想去实现状态的管理。啥也不说,上测试代码:
定义用到的数据类型
typedef enum
{
INIT = 0,
IDLE = 1,
BUSY = 2,
DONE = 3,
}eSTATE;
typedef enum
{
EVENT_0 = 0,
EVENT_1 = 1,
EVENT_2 = 2,
EVENT_3 = 3,
}eEVENT;
typedef struct
{
eSTATE Cur_state;
eEVENT event;
void( *pAction)(void);
u8 next_state;
}strMachine;
#define NUM_MAX 3
strMachine MachineTable[NUM_MAX] =
{
{INIT,EVENT_0,func_event0,BUSY },
{BUSY,EVENT_1,func_event1,DONE },
{DONE,EVENT_2,func_event2,INIT },
};
eSTATE p_currentstate = INIT;
void Machine_Run(eEVENT ev)
{
u8 num = 0;
for (num = 0;num < 3;num++)
{
if (ev == MachineTable[num].event)
{
if (p_currentstate == MachineTable[num].Cur_state)
{
if (MachineTable[num].pAction != NULL)
{
MachineTable[num].pAction();
}
p_currentstate = MachineTable[num].next_state;
}
}
}
}
void func_event0(void)
{
printf(" event 0 action:\n\r");
}
void func_event1(void)
{
printf(" event 1 action:\n\r");
}
void func_event2(void)
{
printf(" event 2 action:\n\r");
}
在主函数中调用MachineRun即可。看效果:
while (1)
{
printf("input event num:");
scanf_s("%d", &input);
Machine_Run(input);
}
用状态表编程的好处,程序结构会比较清晰。如果你能看到这里,说明我们有共鸣,有什么想法,也可以交流。