通信协议

  串行通信接口(如RS232、RS485等)作为计算机与单片机交互数据的主要接口,广泛用于各类仪器仪表、工业监测及自动控制领域中。

  通信协议是需要通信的双方所达成的一种约定,它对包括数据格式、同步方式、传送速度、传送步骤、检纠错方式以及控制字符定义等问题作出统一规定,在双方的通信中必须共同遵守。在实际应用系统中,如果缺少一个严格、合理、规范的串口通信协议,将无法保证数据传输的正确性及通信的可靠性。

  因此,需要提出一种基于状态机串口通信协议的设计方法:通过合理地设置数据包格式来保证了数据传输的正确性:引入了状态机方法,简化了协议的实现难度,提高了通信的可靠性,同时使通信过程具有较高的容错能力。


定义数据包格式

  串口通信中最小的的信息单元是数据帧。一个数据帧通常包括起始位、数据位、结束位,另外还可以包含用于检测传输错误的“奇偶校验位”,每个数据帧中传输的数据位可以有5、6、7、8或9个。
  实际通信过程中,数据的发送是一帧一帧地进行,当被传输的数据超过一帧时(例如浮点型数据),如果没有对数据帧进行必要的打包,发送出去的数据将会很难被数据接收方解释与分析,进而造成数据传输混乱与错误。因此,在一般应用中有必要将数据帧组装成数据包再发送。

  1. 起始标志表示开始接收一个新的数据包。
  2. 数据长度命令和附加数据共占的字节数。设置此字段,可方便接收方识别数据包的长度并能够准确地接收数据包。
  3. 命令用来说明数据包的用途。
  4. 附加数据 当命令不同时,含义不同。
  5. 校验是对命令字段与附加数据字段的所有字节数据的异或校验。
  6. 结束标志表示该数据包结束。

  另外,在多机通信中,数据包中还应增加源地址与设备地址等字段。


通信状态机

状态机简介

  状态机由事物所处的状态及引发状态变化的外部事件两部分组成。

  在软件编程中,事物所处的状态可以描述为某个程序片断或函数,而引发状态变化的处部条件可以理解为条件判断语句,当条件为真时,事物的状态发生变化。事物发生变化前的状态称为现态,变化后的状态称为次态,程序中可以通过不同的数字对不同的状态进行编号。现态到次态的变化可以通过状态变量值的改变来描述。
  在协议中需要传输的基本信息单元是数据包,数据包一般包含多个数据帧。实际传输过程中,数据的传输通常是一帧一帧地进行,数据包是被拆分成若干帧数据后再进行传输,数据接受方也是分帧接受一个数据包。

  数据接受方在解释与分析数据包时可能存在两个问题:

1.识别并接收完整的数据包

  • 对于数据接收方,一个数据包是分若干批到来,在识别包头与包尾时,也就是帧同步问题;
  • 具体编程时存在难度,特别对于已接收部分与未接收部分以及数据接收的进度及状态的处理。

2.数据传输时的容错能力

  • 数据传输过程中已经出现错误时,系统应该具有摆脱错误状态,恢复到正常状态的能力。
  • 例如,当一个数据包只传输完一部分时,因为未知故障,下一个数据包就开始传输,系统应该能识别出传输错误,抛弃前一个出错的数据包,并且能正确接收下一个数据包。
  • 实际编程时处理这种问题难度较大,结果很可能会出现将第一个数据包的前一部分与第二个数据包的前一部分拼装成一个新的数据包的情况,这就损失了两个数据包,最严重的结果可能是系统无法从错误中恢复,这就严重降低了系统的安全性与可靠性。

  为解决上面的两个问题,在协议中引入了状态机。

  在状态机中,状态的变化依赖于外部触发条件,当条件满足时,状态将发生变化。

  在协议中将数据包接收的各个阶段定义为不同的状态,将接收一帧新的数据或数据处理的结果作为外部触发条件,从而达到状态改变的目的,最终完成一个数据包的接收与校验。


串口通信状态图

  串口通信协议中,发送数据包时一般不需引入状态机,这主要是为提高发送速率和简化编程模型而考虑。

  在协议中主要针对数据接收过程建立状态机。

  


串口通信数据接收过程

  1. 当未开始接收数据包或发现数据传输出错时,系统进入空闲状态;
  2. 当数接收到数据包起始标志时,变为收到起始标志状态,如果收到的数据不为起始标志,系统继续保持空闲状态;
  3. 进入收到起始标志状态后,新接收到的任何数据将被当作数据包中命令与附加数据的总字节数(记为LEN),系统进入收到数据长度状态;
  4. 继续接收新的数据,直至接到新收到的数据总字节数达到LEN +2,进入检验结束标志状态;
  5. 这时可以检验结束标志是否为协议定义的标志值,如果是,说明传输正确,否则传输出错,出错后应查找接收缓冲区中本数据包的起始标志后有无其它起始标志,如果没有发现起始标志,系统应进入空闲状态,否则应直接进入接收到起始标志状态,这样可提高系统容错能力,方便系统从错误中恢复。
  6. 检验结柬标志正确后,进入数据校验状态;
  7. 校验结果如果正确,数据包接收完成,否则说明传输出错,系统进入空闲状态。

上位机软件编程逻辑

  上位机软件中,当接收到数据时,串口控件会触发一个事件,在事件处理代码中应及时将收到的数据存入接收冲区,同时不应该把串口通信协议接收部分的代码放置在此事件中,否则后面到来的数据可能因为前面先到的数据没有及时处理完毕而被冲掉,导致数据丢失。

  1. 在上位机软件运行时,应该启动一个Windows线程,用于不断检测接收缓冲区是否为空,不为空时则对缓冲中的数据进行处理;
  2. 线程类创建好后,应具体编写线程类执行函数的处理过程,在其中通过状态指示变量sp实现状态机机制;
  3. 数据包的接收进度依据于状态指示变量sp。

  当数据接收顺利时,sp的变化将会引导完成一个数据包的接收过程。这样处理可以简化编程的模型,使协议易于实现;数据包接收过程中,一旦发现数据传输出错,立即将sp置为0(空闲状态),也就是状态复位,使系统进入准备接收下一个数据包的状态,这样可提高通信过程的可靠性及容错能力。


状态机机制实现

{------------------------------
@功能:状态机机制实现串口通讯
@author:成鹏致远
@net:lcw.cnblogs.com
-------------------------------}
procedure TBufferThread.Execute;
var
s,a :string;
sp,mylen,oddEvenCheck,i :integer;
begin
sp :=; {指示读数据状态}
a :='';
while True do
begin {quelist为接收缓冲区}
if quelist.Count <> then {缓冲区取数}
begin
s :=quelist.Strings[];
quelist.Delete();
a :=a+s;
end;
if a='' then Continue;
{是否空闲状态}
if sp = then
begin
if ord(a[]) =0xFE then
begin
sp :=; {进入到起始标志状态}
end
else {起始标志错误}
begin end;
Delete(a,,);
end
{是否进入收到起始标志状态}
else if sp = then
begin
mylen :=Ord(a[]);
sp :=; {进入长度状态}
Delete(a,,);
end
{是否进入长度状态}
else if sp = then
begin
if Length(a) <=mylen + then Continue;
{数据结束标志:正确}
if ord(a[mylen +])=0xFD then
begin
sp :=; {进入数据校验状态}
end
else {数据结束标志:错误}
begin
sp :=; {重新进入空闲状态}
end;
end
{是否进入数据校验状态}
else if sp = then
begin
for i:= to mylen do
begin
oddEvenCheck :=a[] xor a[i];
end;
if oddEvenCheck =Ord(a[mylen +]) then
begin
sp :=; {校验正确,进入完成状态}
end
else {检验错误,进入空闲状态}
begin
sp :=;
end;
end
else if sp = then
begin
{这里省略处理命令与附加数据代码}
sp :=; {进入空闲状态}
Delete(a,,mylen+);
end;
end;
end;

【Delphi】基于状态机的串口通信的更多相关文章

  1. 基于FPGA自适应串口通信(Auto Baud Rate)

    做的课设,相当于复习了一遍verilog. 实现了 1.接收端固定模式:8N1 BAUD:921600. 2.发送端8N1,任意波特率(不取极端值). 3.数码管显示波特率(16进制). 用了 1.两 ...

  2. QT5 TK1 串口通信

    对TK1中基于QT5的串口通信过程进行总结.按照软件安装及通信实现的顺序. 1.QT5安装 较简洁方式:打开软件中心(类似A形),搜索qtcreator,点击安装即可. 2.串口通信库安装 采用上述方 ...

  3. 基于FPGA的红外遥控解码与PC串口通信

    基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...

  4. VS2008基于对话框的MFC上位机串口通信(C++实现)简单例程

    首先,在 vs2008 环境下创建 MFC 运用程序 设置项目名称为 ComTest(这个地方随意命名,根据个人习惯),点击确定后,点击下一步 出现如下界面 选择"基于对话框"模式 ...

  5. Delphi 串口通信(1)

    利用 Delphi实现串口通信的常用的方法有 3种: 一是利用控件,如 MSCOMM控件和 SPCOMM控件: 二是使用 API函数: 三是调用其他串口通信程序.其中利用 API编写串口通信程序较为复 ...

  6. [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)

    星期一, 20. 八月 2018 01:53上午 - beautifulzzzz 1.前言 做类似zigbee.ble mesh...无线网络节点性能测试的时候,手动操作然后看表象往往很难找出真正的原 ...

  7. C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序

    C#中缓存的使用   缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可:  <%@ Outp ...

  8. (转载)用vs2010开发基于VC++的MFC 串口通信一*****两台电脑同一个串口号之间的通信

    此文章以visual C++数据採集与串口通信測控应用实战为參考教程 此文章适合VC++串口通信入门 一.页面布局及加入控件 1, 安装好vs2010如图 2, 新建一个基于VC++的MFC项目com ...

  9. [stm32][ucos] 1、基于ucos操作系统的LED闪烁、串口通信简单例程

    * 内容简述: 本例程操作系统采用ucos2.86a版本, 建立了5个任务            任务名                                             优先级 ...

随机推荐

  1. Maven Package Plugins And Maven Test

    在使用Maven时候,大家避免不了使用大量插件: 1. maven-compiler-plugin 指定JDK版本和编码方式 ? ?compiler插件能解决2个问题: 第一:指定JDK版本--mav ...

  2. unix环境高级编程 读书笔记

    1.上班业余时间把书下载下来,第一章读完了,但是程序只能回家运行啦!Fighting!

  3. 【DeepLearning】UFLDL tutorial错误记录

    (一)Autoencoders and Sparsity章节公式错误: s2 应为 s3. 意为从第2层(隐藏层)i节点到输出层j节点的误差加权和. (二)Support functions for ...

  4. apache配置中ProxyPassReverse指令的含义

    apache中的mod_proxy模块主要作用就是进行url的转发,即具有代理的功能.应用此功能,可以很方便的实现同tomcat等应用服务器的整合,甚者可以很方便的实现web集群的功能. 例如使用ap ...

  5. 对于“Newtonsoft.Json”已拥有为“NETStander.Library”定义的依赖项,解决办法

    问题描述: 在使用visual studio中的NuGet包管理下载程序时,有时会出现-对于“Newtonsoft.Json”已拥有为“NETStander.Library”定义的依赖项,这样的错误. ...

  6. 【Servlet】Java Serlvet Listener 监听器

    Listener监听器 Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理 容器产生的事件分类 - 生命周期相关的事件 - 设置和删除Attribute数据 ...

  7. Sketch 使用中文字体

    对于刚接触 Sketch 的人来说,在找字体方面,可能不是那么顺手.之前用 RightFont,后来收费了.. 今天介绍个只有长得好看的人才能发现的功能.无需插件即可选择中文字体. 不信,你看: Sk ...

  8. Installation error: INSTALL_FAILED_CONFLICTING_PROVIDER 解决方案

    主要是由于调试的环境中已有一个同名的Provider存在. 解决方法是修改AndroidManifest.xml中的 <provider android:name=".apps.App ...

  9. labview中小黑点,小红点

    小黑点:在labview中每一个小黑点就代表了一次内存的分配,通过小黑点可以帮助我们分析数据变量的内存拷贝情况

  10. SeqGAN 原理简述

    1. 背景GAN在之前发的文章里已经说过了,虽然现在GAN的变种越来越多,用途广泛,但是它们的对抗思想都是没有变化的.简单来说,就是在生成的过程中加入一个可以鉴别真实数据和生成数据的鉴别器,使生成器G ...