博客
关于我
基于状态机State Machine的程序设计技巧②状态转移图和简单通信协议
阅读量:336 次
发布时间:2019-03-04

本文共 1218 字,大约阅读时间需要 4 分钟。

        上一节定义了状态机的概念,状态机由两个重要的部分组成,一个是状态转移关系,另一个就是驱动源。状态转移关系可以由状态转移图定义,下面会说到。驱动源则是驱动状态机运行的动力源。我总结了两种最常用的状态机驱动源第一个是时间驱动,第二个是事件驱动。时间驱动源就是第一节中描述的,状态机使用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;	}}

你可能感兴趣的文章
Node.js 函数计算如何突破启动瓶颈,优化启动速度
查看>>
Node.js 切近实战(七) 之Excel在线(文件&文件组)
查看>>
node.js 初体验
查看>>
Node.js 历史
查看>>
Node.js 回调函数的原理、使用方法
查看>>
Node.js 在个推的微服务实践:基于容器的一站式命令行工具链
查看>>
Node.js 实现类似于.php,.jsp的服务器页面技术,自动路由
查看>>
Node.js 异步模式浅析
查看>>
node.js 怎么新建一个站点端口
查看>>
Node.js 文件系统的各种用法和常见场景
查看>>
Node.js 模块系统的原理、使用方式和一些常见的应用场景
查看>>
Node.js 的事件循环(Event Loop)详解
查看>>
node.js 简易聊天室
查看>>
Node.js 线程你理解的可能是错的
查看>>
Node.js 调用微信公众号 API 添加自定义菜单报错的解决方法
查看>>
node.js 配置首页打开页面
查看>>
node.js+react写的一个登录注册 demo测试
查看>>
Node.js中环境变量process.env详解
查看>>
Node.js中的EventEmitter模块:基本概念、使用方法和常见应用场景
查看>>
Node.js之async_hooks
查看>>