基于状态机State Machine的程序设计技巧②状态转移图和简单通信协议

        上一节定义了状态机的概念,状态机由两个重要的部分组成,一个是状态转移关系,另一个就是驱动源。状态转移关系可以由状态转移图定义,下面会说到。驱动源则是驱动状态机运行的动力源。我总结了两种最常用的状态机驱动源第一个是时间驱动,第二个是事件驱动。时间驱动源就是第一节中描述的,状态机使用100Hz的定时器中断作为状态机的驱动源,每发生一次定时器中断执行一次状态转移。事件驱动源就是使用事件来驱动状态机,说白了就是每次事件发生的时候执行一次状态转移而不是使用一个固定的时间中断来执行状态转移。下面就介绍一种以事件为驱动源的状态机实例。

        基于状态机进行程序设计的第一步是要设计状态机的状态设计,然后基于设计的状态画状态转移图,所谓状态转移图就是用于描述说明状态机中各个状态之间的转移条件以及操作。下面使用状态机设计一个之前常用的通信协议,之前大量使用标志位的技巧,虽然也能实现给定的通信协议,但是稳定性、可移植性和可维护性较差,这里使用状态机的方式重写这个通信协议。

        首先介绍一下这个通信协议,T作为帧起始字符,Q作为帧结束字符,\作为转义字符,这个是参考网络协议栈中的好像是PPP协议做的。下面是协议的状态转移图:


这个协议一共只有三个状态,默认处于状态0,且数据就绪标志位为假表示数据未就绪,当收到帧起始字符T的时候进入状态1,在状态1中收到非T、Q、\的字节则将该字节输入到输入缓冲区并自增接收计数。在状态1下如果收到帧结束字符时进入状态0并且置位数据就绪标志位为真表示数据就绪。在状态1下如果收到转义字符\,则进入到状态2。具体的状态转移方式在状态转移图上有详细说明。

        下面是使用C语言实现的协议程序:

u8 WifiBuff[20];
u8 WifiBuffLen;
bool IsDataReady = false;
void InputData(u8 data)
{
	static int state = 0;
	static int count = 0;
	if(state == 0)
	{
		if(IsDataReady == false)
		{
			if(data == 'T')
			{
				state = 1;
				count = 0;
			}
		}
	}
	else if(state == 1)
	{
		if(data == '\\')
		{
			state = 2;
		}
		else if(data == 'Q')
		{
			state = 0;
			IsDataReady = true;
			WifiBuffLen = count;
			printf("data ready:%d\r\n",count);
		}
		else
		{
			WifiBuff[count++] = data;
		}
	}
	else if(state == 2)
	{
		state = 1;
		WifiBuff[count++] = data;
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值