基于状态机State Machine的程序设计技巧①

        第一次接触到状态机这个词是在学习FPGA的过程中,传统的CPU在处理任务的时候是进行串行工作的,而FPGA内部则是并行处理任务,所以进行FPGA的程序设计是十分注重同步,这里说的同步不是同时做事情,而是有纪律地做事情,引用百度百科上对同步的解释:同步指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系使用最多的同步方式就是状态机State Machine,虽然我对FPGA只有很浅薄的理解,但是我发现了FPGA上使用的状态机的伟大之处,因为说白了整个CPU就是一个十分复杂的状态机,其包括指令获取、指令解码、指令执行、数据写回等等状态,需要一个相当庞大的状态机来完成所有工作的同步。再者我们使用的操作系统也是一个状态机,只是这个状态机是基于软件的状态机,而不是硬件电路上的状态机,但是原理都是一样的,例如创建一个任务,这个任务有挂起、运行、死亡、睡眠等状态,管理这些状态就需要一个完整的状态机实现,以保证何时、在何种条件下从当前状态跳转到另一个状态。

        说到这里就会发现原来状态机在软件上早已有用到,事实上我们在正常的程序设计过程中多多少少会用到状态机,只是不知道这是个状态机,例如我们建立一个标志,如果发生了一个事件将这个标志被置为1则执行某些操作,如果发生另外一个事件将这个标志被置为2则执行其他一些操作,这其实就是一个小的状态机。由于状态机在程序设计上的优势所在,有必要好好规范状态机在程序设计中的使用方法。

        在FPGA的状态机上一般使用一个时钟源,在这个时钟源的上升沿PoseEdge时触发状态机的程序,注意这里说的程序是“硬件程序”,也就是说是电路。所以类似的我们在程序中进行状态机设计的话也需要一个时钟源,我们不能像FPGA一样使用一个50MHz的时钟源作为状态机的处理时钟,太快了的话大部分处理器处理不过来,我们可以妥协,使用低频的像100Hz的时钟作为状态机的处理时钟,这个时钟可以使用处理器的定时器中断来实现,其实我们使用的嵌入式操作系统就是使用的定时器来作为系统时间基准以及任务调度的,也就是作为了操作系统的状态机的驱动时钟源。这样一来我们有了驱动状态机的时钟源,下面就可以开始状态机式的程序设计了。

        下面的程序是定时器的中断服务程序:

void TIM3_IRQHandler(void)
{
	TIM3->SR &= ~(1<<0);	//清除中断标志位
	
	StateMachine_Test();
}
在这个函数里面做了两件事情,清除中断标志以及调用StateMachine_Test函数,在这个函数里面完成一个状态机的功能,下面是这个StateMachine_Test函数的实现:

void StateMachine_Test(void)
{
	static int state = 0;
	static int count = 0;
	
	if(state == 0)
	{
		if(count++ == 10)
		{
			count = 0;
			printf("change state to 1");
			state = 1;
		}
	}
	else if(state == 1)
	{
		if(count++ == 10)
		{
			count = 0;
			printf("change state to 2");
			state = 2;
		}
	}
	else if(state == 2)
	{
		if(count++ == 10)
		{
			count = 0;
			printf("change state to 0");
			state = 0;
		}
	}
}
添加内容之后的状态机变得复杂起来但其实也是很简单,这个状态机的驱动时钟源为100Hz,则每隔10ms调用一次这个状态机函数StateMachine_Test,一开始state为0,count也为0,这时候状态机处于状态0,则程序进行if(state == 0)的分支,在这里面进行count的自增操作,当count大于10也就是过了100ms之后就会将状态机的状态切换到状态1,这时候当下一次状态机运算开始时程序就会跳入if(state == 1)的分支,类似的也会从状态1调到状态2,然后从状态2跳回到状态0。这是一个简单的状态机程序,整个状态机只有三个状态,而且每个状态中的任务都十分简单,但是可以在这种状态机的思想上完成十分复杂程序设计。







  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值