嵌入式C语言实现状态机

一.状态机

状态机的实现的三个要素:状态、事件、响应。

二.c语言代码实现

1.一般实现方式

if...else : 大堆if else, 一个函数写很长很长......

swich...case : 搞一大堆一个函数写很长很长......

如果说时间比较少(5个以内),还是基本可控的,还是可以用的。

但如果事件超过十个,再加上超过三个状态的切换,那代码逻辑看起来就会非常混乱

2.表驱动法

  这种方式把状态和事件进行模块化分离,同时用一张表再连接起来,就从根本上解决了这个问题,而且时间和状态也多越能发挥出优势来,

几乎可以说是没有上限限制。

代码实现:

这里我们首先定义一个结构体如下:

typedef struct {

  State curState;//当前状态

  EventID eventId;//事件ID

  State nextState;//下个状态

  Action action;//具体表现

  }

StateTransform;

我们假设有3种状态,这里可以随意增加,状态枚举如下:

typedef enum {

  state_1=1,

  state_2,

  state_3}

State;

我们假设有5个事件,也可以随意增加,事件ID枚举如下:

typedef enum{

  event_1=1,

  event_2,

  event_3,

  event_4,

  event_5

  }EventID;

将其封装起来在StateMachine中:

typedef struct{

  State state;

  int transNum;

  StateTransform* transform;

}StateMachine;

具体流程:当前状态-有事件触发-跳到下个状态-具体表现,重构代码

StateTransform* findTranss(StateMachine* pSM,  const EventID evt){

  int i;

  for (i = 0; i < pSM->transNum; i++) {

    if ((pSM->transform[i].curState == pSM->state) && (pSM->transform[i].eventId == evt)) {

      return &pSM->transform[i];

    }

  }

  return NULL;

}

状态机实现如下:

    StateTransformm* pTrans;

    pTrans = findTrans(pSM, evt);

    if (pTrans == NULL)

    {

        xil_printf( "CurState= %s Do not process enent: %s\r\n", pSM->state,evt);

        return;

    }

    pSM->state = pTrans->nextState;

    Action act = pTrans->action;

    if (act == NULL) {

        xil_printf( "change state to %s. No action\r\n",pSM->state);

        return;

    }

    act(&evt);

最后我模拟一些随机事件,我们只需要弄清楚事件ID,状态切换,具体表现就可以了,在代码中就是填写 stateTran[] 这个表,一旦有增减事件,状态等等,

也不需要再去使用switch/case,特费脑,其代码如下:

int run()

{

    StateMachine stateMachine;

    stateMachine.state = state_1;

    stateMachine.transNum = 7;

    StateTransform stateTran[] = {

        {state_1,event_3,state_2,f121},

        {state_1,event_4,state_2,NULL},

        {state_2,event_1,state_3,f231},

        {state_2,event_4,state_2,f221},

        {state_3,event_2,state_1,f311},

        {state_3,event_3,state_2,f321},

        {state_3,event_5,state_3,f331}

    };

    stateMachine.transform = stateTran;

    EventID inputEvent[15] = { event_1, event_2, event_3, event_4, event_5,

        event_1, event_2, event_3, event_4, event_5,

        event_1, event_2, event_3, event_4, event_5 };

    int i;

    for (i = 0; i < 15; i++) {

        runStateMachine(&stateMachine, inputEvent[i]);

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI+程序员在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值