2.4 STM32_FSM状态机的编写

这就是需要完成的动作
如上图,如何用状态机去实现。
方法1:可以用switch case语句实现

enum state { s_stop, s_play, s_forward, s_backward, s_pause, s_record  };
enum message { play, stop, forward, backward, record, pause };


void state_change(enum message m)
{
 static enum state s=s_stop;
 switch (s)
 {
	case s_play:
    	if(m==stop)
       {
			s = s_stop;
		    printf("stop.\n");        
       }
       else if (m==pause)
       {
            s = s_pause;
			printf("pause");
       }
       break;
	case s_pause:
		if(m==pause)
		{
			s = s_play;
			printf("play.\n");        
		}
		else if(m==stop)
		{
			s = s_stop;
			printf("stop.\n");        
		}
		break;
    case s_stop:
		if(m==play)
		{
			s = s_play;
			printf("play.\n");        
		}
		if(m==backward)
		{
			s = s_backward;
			printf("backward.\n");        
		}
		if(m==forward)
		{
			s = s_forward;
			printf("forward.\n");        
		}
		if(m==record)
		{
			s = s_record;
			printf("record.\n");        
		}
		break;
	case s_forward:
		if(m==stop)
		{
			s = s_stop;
			printf("stop.\n"); 
		}
		break;
	case s_backward:
		if(m==stop)
		{
			s = s_stop;
			printf("stop.\n"); 
		}
		break;
	case s_record:
		if(m==stop)
		{
			s = s_stop;
			printf("stop.\n"); 
		}
		break;     
 }  
}


int main(int argc, char *argv[])
{
    char c=0x00;
    while(1)
    {
        c = getchar();
        switch(c)
        {
            case ' ': state_change(pause); break;
            case 'p':  state_change(play); break;
            case 'r': state_change(record); break;
            case 's': state_change(stop); break;
            case 'f': state_change(forward); break;
            case 'b': state_change(backward); break;
            case 'q':     return EXIT_SUCCESS;
        }

        
    }
    
    return EXIT_SUCCESS;
}

方法二:使用列表

#define transition_num  11
#define state_num 6

typedef void (*action_foo)() ;

enum state { s_stop='s', s_play='p', s_forward='f', s_backward='b', s_pause='_', s_record='r'  };
enum message { play, stop, forward, backward, record, pause };

/* action starts */
void do_stop() {printf ("I am in state stop and should doing something here.\n");}
void do_play() {printf ("I am in state play and should doing something here.\n");}
void do_forward() {printf ("I am in state forward and should doing something here.\n");}
void do_backward() {printf ("I am in state backward and should doing something here.\n");}
void do_pause() {printf ("I am in state pause and should doing something here.\n");}
void do_record() {printf ("I am in state record and should doing something here.\n");}
struct state_action {
    enum state m_state;
    action_foo foo;
};
//列表,到达了该步骤需要做什么
struct state_action state_action_map[state_num] = 
{
    {s_stop, do_stop},
    {s_play, do_play},
    {s_forward, do_forward},
    {s_backward, do_backward},
    {s_pause, do_pause},
    {s_record, do_record}
};

action_foo ACTION_NOT_FOUND = NULL;
action_foo lookup_action(enum state s, struct state_action* a)
{
    action_foo ret = ACTION_NOT_FOUND;
    int i=0;
    for (i=0;i<state_num;++i)
    {
        if(s == a[i].m_state)
        {
            ret = a[i].foo;
        }
    }
    return ret;
}
/*  action ends. */

/* transition starts*/
struct transition {
    enum state current;
    enum message m;
    enum state next;
};

//列表列出所有状态:当前状态,对应收到的消息,对应的下要给状态
struct transition fsm[transition_num] = {
/* current_state, message/event, next_state*/
    {s_play,	stop,		s_stop},
    {s_play,	pause,		s_pause},
    {s_pause,	pause,		s_play},
    {s_pause,	stop,		s_stop},
    {s_stop,	forward,	s_forward},
    {s_stop,	play,		s_play},
    {s_stop,	backward,	s_backward},
    {s_stop,	record,		s_record},
    {s_forward,	stop,		s_stop},
    {s_backward,	stop,		s_stop},
    {s_record,	stop,		s_stop} };

int const ERR = -1;
int lookup_transition (enum state s, enum message m, struct transition * t)
{
    int ret=ERR;
    int i;
    for(i=0;i<transition_num;++i)
    {
        if(t[i].current == s && t[i].m == m)
        {
            ret = i;
        }
    }
    return ret;
}
/* transition ends*/

void state_change(enum message m)
{
    static state state = s_stop;
    enum state next;
    int index = 0;

    index = lookup_transition(state, m, fsm);//查FSM表单
    if(index!=ERR)
    {
        state = fsm[index].next;
        lookup_action(state, state_action_map)();//查寻到结果后对应需要执行的函数
    }
    return;
}


int main(int argc, char *argv[])
{
    char c=0x00;
    while(1)
    {
        c = getchar();
        printf ("%c input.\n", c);
        switch(c)
        {
            case ' ': state_change(pause); break;
            case 'p':  state_change(play); break;
            case 'r': state_change(record); break;
            case 's': state_change(stop); break;
            case 'f': state_change(forward); break;
            case 'b': state_change(backward); break;
            case 'q': return EXIT_SUCCESS;
        }

        
    }
    
    return EXIT_SUCCESS;
}
摘一段别人的话
“使用列表的好处在于,他始终如一,不管遇到的情形是多么糟糕多么恶劣,他始终没有变化。这个世界上,总须要一些因素,一些承诺,不随不论什么易变的感情、不论什么旁人不能承受的痛苦或诱惑而变化,稳定地坚持。
这才让我们对这个世界保留一丝希望。未来才可以和值得期待。”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值