热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Modbus】Modbus协议

Modbus协议简介Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。标准的Modbus协议物理层接口有RS232、RS422

    1. Modbus 协议简介

Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。

标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口,采用master/slave方式通信。

      1.  在Modbus网络上转输

1异步串行通信。一般的介质有:RS-232,RS485,RS-422上,这也是工业上使用的最多的; 

2主从方式通信。一问一答.(典型的主设备:主机和可编程仪表。典型的从设备:可编程控制器。

3、广播和单独通信。主设备与从设备单1)独通信:从设备返回一消息作为回应。2)广播,从设备不作任何回应

      1. 在其它类型网络上转输

 1、对等技术通信。在单独的通信过程中,控制器既可作为主设备也可作为从设备。提供的多个内部通道可允许同时发生的传输进程。

   2主从方式通信。尽管网络通信方法是“对等”,Modbus协议仍提供了主从原则,设备发消息就是主设备,并期望从从设备得到回应。

    1. 两种传输方式(ASCII或RTU)
      1. ASCII或RTU内容

控制器能设置为两种传输模式(ASCII或RTU),设备必须支持RTU模式,ASCII只是可选。所以ASCII只做了解。

异步串行通信上,般的介质有:RS-232,RS485,RS-422,才会分 ASCII或RTU, 在其它网络上(象MAP和Modbus Plus)Modbus消息被转成与串行传输无关的帧。

ASCII模式:字符数据,用字符表示十六进制数,如0xff 就是“FF”, 错误检测域LRC

RTU  模式:二进制数数据(十六进制0xff), 错误检测域 CRC

ASCII

地址

功能代码

数据数量

数据1

...

数据n

LRC高字节

LRC低字节

回车

换行

RTU

地址

功能代码

数据数量

数据1

...

数据n

CRC低字节

CRC高字节

      1. ASCII或RTU消息帧断帧方式

1、ASCII帧

 使用ASCII模式,消息以冒号(:)字符(ASCII码 3AH)开始,以回车换行符结束(ASCII码 0DH,0AH)。

2、RTU帧

 使用RTU模式,消息发送至少要以3.5个字符时间的停顿间隔开始。

整个消息帧必须作为一连续的流转输。如果在帧完成之前有超过1.5个字符时间的停顿时间,接收设备将刷新不完整的消息并假定下一字节是一个新消息的地址域。同样地,如果一个新消息在小于3.5个字符时间内接着前个消息开始,接收的设备将认为它是前一消息的延续。

    1. Modbus网络的协议帧
      1. 帧结构

1.信息帧结构

地址码

功能码

数据区

错误校验码

8位

8位

N × 8位

16位

  

最常用的功能码:

代码

含义

操作

03

读取数据

读取当前寄存器内一个或多个二进制值

06

重置单一寄存器

把设置的二进制值写入单一寄存器

0x10

重置多寄存器

把设置的二进制值写入多个寄存器

      1. 协议帧实例
        1. 查询(功能码0x03)

功能描述:

现在我是主机,我要查询从机地址为1的数据.

主机发送: 01 03 00 00 00 01 84 0A
从机回复: 01 03 02 12 34 B5 33


*发送数据解析*/
主机发送01 03 00 00 00 01 84 0A

01-地址
03-功能码,代表查询功能,其他功能后面再说
00 00-代表查询的起始寄存器地址.说明从0x0000开始查询.
(
这里需要说明以下,Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据;)
00 01-代表查询了一个寄存器.结合前面的00 00,意思就是查询从0开始的1个寄存器值;
84 0A-CRC

/*回复解析*/
从机回复01 03 02 12 34 B5 33


01-地址
03-功能码
02-代表后面数据的字节数,因为上面说到,一个寄存器有2个字节,所以后面的字节数肯定是2*查询的寄存器个数;
12 34-寄存器的值是12 34,结合发送的数据看出,01这个寄存器的值为12 34
B5 33-CRC

简便记忆:

基本流程就是:
发送:地址 + 我要查      +(寄存器起始地址+个数)+校验
回复:地址 +(回)我要查 +(数据的字节数+数据)  +校验

        1. 修改
  1. 修改单个寄存器(功能码0x06)

主机发送01 06 00 00 00 01 48 0A
从机回复01 06 00 00 00 01 48 0A  (成功修改)

*发送数据解析*/
主机发送01 06 00 00 00 01 48 0A
01-从机地址
06-功能码:修改单个寄存器功能,修改有些不同,有修改一个寄存器和修改多个寄存器;
00 00-修改的起始寄存器地址.说明从0x0000开始.
00 01-修改的值为00 01.结合前面的00 00,意思就是修改0号寄存器值为00 01;
48 0A-CRC

/*回复解析*/
从机回复01 06 00 00 00 01 48 0A
01-从机地址
06-功能码:修改单个寄存器功能;
00 00-修改的起始寄存器地址.说明是0x0000.
00 01-修改的值为00 01.结合前面的00 00,意思就是修改0号寄存器值为00 01;
48 0A-CRC

  1. 修改多个寄存器(功能码0x10)

主机发送01 10 00 00 00 02 04 11 22 33 44 42 5A
从机回复01 10 00 00 00 02 41 C8

/*发送数据解析*/
主机发送01 10 00 00 00 02 04 11 22 33 44 42 5A
01-从机地址
10-功能码,代表修改多个寄存器功能;
00 00-代表修改的起始寄存器地址.说明从0x0000开始.
00 02代表修改的寄存器数量
04   -表示修改的总字节数,由于只修改了1个寄存器,所以数据要有两个字节;
11 22 33 44-表示修改的值,结合上面,就是从第0000寄存器开始修改2寄存器值为11 22 33 44,就是把0000寄存器改为11 22,000133 44,
 42 5A -循环冗余校验,modbus的校验公式,从首个字节开始到22前面为止;

/*回复解析*/
从机回复01 10 00 00 00 02 41 C8
01-从机地址
10-功能码
00 00-代表修改的起始寄存器地址.说明是0x0000.
00 02-代表修改的寄存器数量,只需要回复这么多久足够了,从机告诉主机修改了哪几个寄存器就足够了;
41 C8-循环冗余校验;

用修改0x10功能码修改1个寄存器:

主机发送01 10 00 00 00 01 02 11 22 2A 19
从机回复01 10 00 00 00 01 01 C9

/*发送数据解析*/
主机发送01 10 00 00 00 01 02 11 22 2A 19
01-从机地址
10-功能码,代表修改多个寄存器功能;
00 00-代表修改的起始寄存器地址.说明从0x0000开始.
00 01-代表修改的寄存器数量
02   -表示修改的总字节数,由于只修改了1个寄存器,所以数据要有两个字节;
11 22-表示修改的值,结合上面,就是从第0000寄存器开始修改一个寄存器值为11 22,就是把0000寄存器改为11 22;
2A 19-循环冗余校验,modbus的校验公式,从首个字节开始到22前面为止;

/*回复解析*/
从机回复01 10 00 00 00 01 01 C9
01-从机地址
10-功能码
00 00-代表修改的起始寄存器地址.说明是0x0000.
00 01-代表修改的寄存器数量,只需要回复这么多久足够了,从机告诉主机修改了哪几个寄存器就足够了;
01 C9-循环冗余校验;

    1. 通信方式

Modbus设备可分为主站(poll)和从站(slave)。主站只有一个,从站有多个,主站向各从站发送请求帧,从站给予响应。在使用TCP通信时,主站为client端,主动建立连接;从站为server端,等待连接。

  • 主站请求:功能码+数据
  • 从站正常响应:请求功能码+响应数据
  • 从站异常响应:异常功能码+异常码,其中异常功能码即将请求功能码的最高有效位置1,异常码指示差错类型
  • 注意:需要超时管理机制,避免无期限的等待可能不出现的应答

IANA(Internet Assigned Numbers Authority,互联网编号分配管理机构)给Modbus协议赋予TCP端口号为502,这是目前在仪表与自动化行业中唯一分配到的端口号。

通信过程

  1. connect 建立TCP连接
  2. 准备Modbus报文
  3. 使用send命令发送报文
  4. 在同一连接下等待应答
  5. 使用recv命令读取报文,完成一次数据交换
  6. 通信任务结束时,关闭TCP连接

    1. Modbus-TCP

以太网作为介质进行传输,

协议与modbus网络的区别:

modbus网络:

附件

    1. 附录

表1 ModBus功能码

功能码

名称

作用

01

读取线圈状态

取得一组逻辑线圈的当前状态(ON/OFF)

02

读取输入状态

取得一组开关输入的当前状态(ON/OFF)

03

读取保持寄存器

在一个或多个保持寄存器中取得当前的二进制值

04

读取输入寄存器

在一个或多个输入寄存器中取得当前的二进制值

05

强置单线圈

强置一个逻辑线圈的通断状态

06

预置单寄存器

把具体二进值装入一个保持寄存器

07

读取异常状态

取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定,用户逻辑可以将这些线圈定义,以说明从机状态,短报文适宜于迅速读取状态

08

回送诊断校验

把诊断校验报文送从机,以对通信处理进行评鉴

09

编程(只用于484)

使主机模拟编程器作用,修改PC从机逻辑

10

控询(只用于484)

可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送

11

读取事件计数

可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其他应答产生通信错误时

12

读取通信事件记录

可是主机检索每台从机的ModBus事务处理通信事件记录。如果某项事务处理完成,记录会给出有关错误

13

编程(184/384 484 584)

可使主机模拟编程器功能修改PC从机逻辑

14

探询(184/384 484 584)

可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送

15

强置多线圈

强置一串连续逻辑线圈的通断

16

预置多寄存器

把具体的二进制值装入一串连续的保持寄存器

17

报告从机标识

可使主机判断编址从机的类型及该从机运行指示灯的状态

18

(884和MICRO 84)

可使主机模拟编程功能,修改PC状态逻辑

19

重置通信链路

发生非可修改错误后,是从机复位于已知状态,可重置顺序字节

20

读取通用参数(584L)

显示扩展存储器文件中的数据信息

21

写入通用参数(584L)

把通用参数写入扩展存储文件,或修改之

22~64

保留作扩展功能备用

65~72

保留以备用户功能所用

留作用户功能的扩展编码

73~119

非法功能

120~127

保留

留作内部作用

128~255

保留

用于异常应答

参考:Modbus协议解析--小白一看就懂的协议_panda@Code的博客-CSDN博客_modbus解析 Modbus协议解析--小白一看就懂的协议

          新浪博客 modbus 入门篇,不冗长,很好理解!

          Modbus通讯协议详细解释_Hello-12345的博客-CSDN博客_modbus协议 Modbus通讯协议详细解释

          MODBUS协议最简单又是最直白的解释_JiaoCL的博客-CSDN博客_modbus协议最简单又是最直白的解释 MODBUS协议最简单又是最直白的解释


【modbus】modbus 协议

http://www.ourdev.cn/forum.php?mod=viewthread&tid=4548026


【modbus】modbus 协议

 概念:

     协议不仅是定义 帧的消息格式 还有 通信流程 以及通信的标准;

     所以协议是   帧格式定义+通信交互流程+通信标准;

modbus: modbus帧格式+modbus发送和回复流程+modbus硬件标准,软件标准:如波特率、校验位等。


modbus 内容:

更详尽的内容 :Modbus使用教程 - 百度文库

 

 

MODBUS通讯协议及编程

  ModBus通讯协议分为RTU协议和ASCII协议,我公司的多种仪表都采用ModBus RTU通讯协议,如:CH2000智能电力监测仪、CH 2000M电力参数采集模块、巡检表、数显表、光柱数显表等。下面就ModBus RTU协议简要介绍如下:

一、通讯协议

(一)、通讯传送方式:
   通讯传送分为独立的信息头,和发送的编码数据。以下的通讯传送方式定义也与MODBUS RTU通讯规约相兼容:

8位二进制

起始位

1位

数据位

8位

奇偶校验位

1位(偶校验位)

停止位

1位

错误校检

CRC(冗余循环码)

初始结构 = ≥4字节的时间
地址码 = 1 字节
功能码 = 1 字节
数据区 = N 字节
错误校检 = 16位CRC码
结束结构 = ≥4字节的时间


  地址码:地址码为通讯传送的第一个字节。这个字节表明由用户设定地址码的从机将接收由主机发送来的信息。并且每个从机都有具有唯一的地址码,并且响应回送均以各自的地址码开始。主机发送的地址码表明将发送到的从机地址,而从机发送的地址码表明回送的从机地址。

  功能码:通讯传送的第二个字节。ModBus通讯规约定义功能号为1到127。本仪表只利用其中的一部分功能码。作为主机请求发送,通过功能码告诉从机执行什么动作。作为从机响应,从机发送的功能码与从主机发送来的功能码一样,并表明从机已响应主机进行操作。如果从机发送的功能码的最高位为1(比如功能码大与此同时127),则表明从机没有响应操作或发送出错。

  数据区:数据区是根据不同的功能码而不同。数据区可以是实际数值、设置点、主机发送给从机或从机发送给主机的地址。

   CRC:二字节的错误检测码。

(二)、通讯规约:

   当通讯命令发送至仪器时,符合相应地址码的设备接通讯命令,并除去地址码,读取信息,如果没有出错,则执行相应的任务;然后把执行结果返送给发送者。返送的信息中包括地址码、执行动作的功能码、执行动作后结果的数据以及错误校验码。如果出错就不发送任何信息。

1.信息帧结构

地址码

功能码

数据区

错误校验码

8位

8位

N × 8位

16位

  地址码:地址码是信息帧的第一字节(8位),从0到255。这个字节表明由用户设置地址的从机将接收由主机发送来的信息。每个从机都必须有唯一的地址码,并且只有符合地址码的从机才能响应回送。当从机回送信息时,相当的地址码表明该信息来自于何处。

   功能码:主机发送的功能码告诉从机执行什么任务。表1-1列出的功能码都有具体的含义及操作。

代码

含义

操作

03

读取数据

读取当前寄存器内一个或多个二进制值

06

重置单一寄存器

把设置的二进制值写入单一寄存器

  数据区:数据区包含需要从机执行什么动作或由从机采集的返送信息。这些信息可以是数值、参考地址等等。例如,功能码告诉从机读取寄存器的值,则数据区必需包含要读取寄存器的起始地址及读取长度。对于不同的从机,地址和数据信息都不相同。

  错误校验码:主机或从机可用校验码进行判别接收信息是否出错。有时,由于电子噪声或其它一些干扰,信息在传输过程中会发生细微的变化,错误校验码保证了主机或从机对在传送过程中出错的信息不起作用。这样增加了系统的安全和效率。错误校验采用CRC-16校验方法。

注:信息帧的格式都基本相同:地址码、功能码、数据区和错误校验码。

2.错误校验

   冗余循环码(CRC)包含2个字节,即16位二进制。CRC码由发送设备计算,放置于发送信息的尾部。接收信息的设备再重新计算接收到信息的 CRC码,比较计算得到的CRC码是否与接收到的相符,如果两者不相符,则表明出错。

  CRC码的计算方法是,先预置16位寄存器全为1。再逐步把每8位数据信息进行处理。在进行CRC码计算时只用8位数据位,起始位及停止位,如有奇偶校验位的话也包括奇偶校验位,都不参与CRC码计算。

   在计算CRC码时,8位数据与寄存器的数据相异或,得到的结果向低位移一字节,用0填补最高位。再检查最低位,如果最低位为1,把寄存器的内容与预置数相异或,如果最低位为0,不进行异或运算。

   这个过程一直重复8次。第8次移位后,下一个8位再与现在寄存器的内容相相异或,这个过程与以上一样重复8次。当所有的数据信息处理完后,最后寄存器的内容即为CRC码值。CRC码中的数据发送、接收时低字节在前。

   计算CRC码的步骤为:

  • 预置16位寄存器为十六进制FFFF(即全为1)。称此寄存器为CRC寄存器;
  • 把第一个8位数据与16位CRC寄存器的低位相异或,把结果放于CRC寄存器;
  • 把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位;
  • 如果最低位为0:重复第3步(再次移位); 如果最低位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
  • 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
  • 重复步骤2到步骤5,进行下一个8位数据的处理;
  • 最后得到的CRC寄存器即为CRC码。

3.功能码03,读取点和返回值:

  仪表采用Modbus RTU通讯规约,利用通讯命令,可以进行读取点(“保持寄存器”) 或返回值(“输入寄存器” )的操作。保持和输入寄存器都是16位(2字节)值,并且高位在前。这样用于仪表的读取点和返回值都是2字节。一次最多可读取寄存器数是60。由于一些可编程控制器不用功能码03,所以功能码03被用作读取点和返回值。从机响应的命令格式是从机地址、功能码、数据区及CRC码。数据区中的寄存器数据都是每两个字节高字节在前。

4.功能码06,单点保存

  主机利用这条命令把单点数据保存到仪表的存储器。从机也用这个功能码向主机返送信息。

二、编程举例

  下面是一个用VC编写的ModBus RTU通讯的例子

(一)、通讯口设置

DCB dcb;
hCom=CreateFile("COM1",
     GENERIC_READ|GENERIC_WRITE,
     0,
     NULL,
     OPEN_EXISTING,
     0,
     NULL);
if(hCom==INVALID_HANDLE_VALUE)
{
  MessageBox("createfile error,error");
}
BOOL error=SetupComm(hCom,1024,1024);
if(!error)
  MessageBox("setupcomm error");
error=GetCommState(hCom,&dcb);
if(!error)
  MessageBox("getcommstate,error");
dcb.BaudRate=2400;
dcb.ByteSize=8;

dcb.Parity=EVENPARITY;//NOPARITY;
dcb.StopBits=ONESTOPBIT;

error=SetCommState(hCom,&dcb);

(二)、CRC校验码计算

UINT crc
void calccrc(BYTE crcbuf)
{
BYTE i;

crc=crc ^ crcbuf;
for(i&#61;0;i<8;i&#43;&#43;)
{
BYTE TT;
TT&#61;crc&1;
crc&#61;crc>>1;
crc&#61;crc&0x7fff;
if (TT&#61;&#61;1)
crc&#61;crc^0xa001;
crc&#61;crc&0xffff;
}
}

&#xff08;三&#xff09;、数据发送

zxaddr&#61;11;//读取地址为11的巡检表数据
zxnum&#61;10;//读取十个通道的数据

writebuf2[0]&#61;zxaddr;
writebuf2[1]&#61;3;
writebuf2[2]&#61;0;
writebuf2[3]&#61;0;
writebuf2[4]&#61;0;
writebuf2[5]&#61;zxnum;
crc&#61;0xffff;
calccrc(writebuf2[0]);
calccrc(writebuf2[1]);
calccrc(writebuf2[2]);
calccrc(writebuf2[3]);
calccrc(writebuf2[4]);
calccrc(writebuf2[5]);

writebuf2[6]&#61;crc & 0xff;
writebuf2[7]&#61;crc/0x100;
WriteFile(hCom,writebuf2,8,&comnum,NULL);

&#xff08;四&#xff09;、数据读取

ReadFile(hCom,writebuf,5&#43;zxnum*2,&comnum,NULL);//读取zxnum个通道数据
可增加错误处理程序&#xff0c;如地址码错误、CRC码错误判断、通讯故障处理等。

 ModBus通信系统协议

 

ModBus网络是一个工业通信系统&#xff0c;由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。下表1是ModBus的功能码定义。

表1 ModBus功能码

功能码

名称

作用

01

读取线圈状态

取得一组逻辑线圈的当前状态&#xff08;ON/OFF)

02

读取输入状态

取得一组开关输入的当前状态&#xff08;ON/OFF)

03

读取保持寄存器

在一个或多个保持寄存器中取得当前的二进制值

04

读取输入寄存器

在一个或多个输入寄存器中取得当前的二进制值

05

强置单线圈

强置一个逻辑线圈的通断状态

06

预置单寄存器

把具体二进值装入一个保持寄存器

07

读取异常状态

取得8个内部线圈的通断状态&#xff0c;这8个线圈的地址由控制器决定&#xff0c;用户逻辑可以将这些线圈定义&#xff0c;以说明从机状态&#xff0c;短报文适宜于迅速读取状态

08

回送诊断校验

把诊断校验报文送从机&#xff0c;以对通信处理进行评鉴

09

编程&#xff08;只用于484&#xff09;

使主机模拟编程器作用&#xff0c;修改PC从机逻辑

10

控询&#xff08;只用于484&#xff09;

可使主机与一台正在执行长程序任务从机通信&#xff0c;探询该从机是否已完成其操作任务&#xff0c;仅在含有功能码9的报文发送后&#xff0c;本功能码才发送

11

读取事件计数

可使主机发出单询问&#xff0c;并随即判定操作是否成功&#xff0c;尤其是该命令或其他应答产生通信错误时

12

读取通信事件记录

可是主机检索每台从机的ModBus事务处理通信事件记录。如果某项事务处理完成&#xff0c;记录会给出有关错误

13

编程&#xff08;184/384 484 584&#xff09;

可使主机模拟编程器功能修改PC从机逻辑

14

探询&#xff08;184/384 484 584&#xff09;

可使主机与正在执行任务的从机通信&#xff0c;定期控询该从机是否已完成其程序操作&#xff0c;仅在含有功能13的报文发送后&#xff0c;本功能码才得发送

15

强置多线圈

强置一串连续逻辑线圈的通断

16

预置多寄存器

把具体的二进制值装入一串连续的保持寄存器

17

报告从机标识

可使主机判断编址从机的类型及该从机运行指示灯的状态

18

&#xff08;884和MICRO 84&#xff09;

可使主机模拟编程功能&#xff0c;修改PC状态逻辑

19

重置通信链路

发生非可修改错误后&#xff0c;是从机复位于已知状态&#xff0c;可重置顺序字节

20

读取通用参数&#xff08;584L&#xff09;

显示扩展存储器文件中的数据信息

21

写入通用参数&#xff08;584L&#xff09;

把通用参数写入扩展存储文件&#xff0c;或修改之

22&#xff5e;64

保留作扩展功能备用

65&#xff5e;72

保留以备用户功能所用

留作用户功能的扩展编码

73&#xff5e;119

非法功能

120&#xff5e;127

保留

留作内部作用

128&#xff5e;255

保留

用于异常应答

ModBus网络只是一个主机&#xff0c;所有通信都由他发出。网络可支持247个之多的远程从属控制器&#xff0c;但实际所支持的从机数要由所用通信设备决定。采用这个系统&#xff0c;各PC可以和中心主机交换信息而不影响各PC执行本身的控制任务。表2是ModBus各功能码对应的数据类型。

表2 ModBus功能码与数据类型对应表

代码

功能

数据类型

01

02

03

整型、字符型、状态字、浮点型

04

整型、状态字、浮点型

05

06

整型、字符型、状态字、浮点型

08

N/A

重复“回路反馈”信息

15

16

整型、字符型、状态字、浮点型

17

字符型

&#xff08;1&#xff09;ModBus的传输方式

 在ModBus系统中有2种传输模式可选择。这2种传输模式与从机PC通信的能力是同等的。选择时应视所用ModBus主机而定&#xff0c;每个ModBus系统只能使用一种模式&#xff0c;不允许2种模式混用。一种模式是ASCII&#xff08;美国信息交换码&#xff09;&#xff0c;另一种模式是RTU&#xff08;远程终端设备&#xff09;这两种模式的定义见表3

表3 ASCII和RTU传输模式的特性

特性

ASCII(7位&#xff09;

RTU(8位&#xff09;

编码系统

十六进制&#xff08;使用ASCII可打印字符&#xff1a;0&#xff5e;9&#xff0c;A&#xff5e;F)

二进制

每一个字符的位数

开始位

1位

1位

数据位&#xff08;最低有效位第一位&#xff09;

7位

8位

奇偶校验&#xff08;任选&#xff09;

1位&#xff08;此位用于奇偶校验&#xff0c;无校应则无该位&#xff09;

1位&#xff08;此位用于奇偶校验&#xff0c;无校应则无该位&#xff09;

停止位

1或2位

1或2位

错误校验

LRC&#xff08;即纵向冗余校验&#xff09;

CRC(即循环冗余校验&#xff09;

ASCII可打印字符便于故障检测&#xff0c;而且对于用高级语言&#xff08;如Fortan&#xff09;编程的主计算机及主PC很适宜。RTU则适用于机器语言编程的计算机和PC主机。

用RTU模式传输的数据是8位二进制字符。如欲转换为ASCII模式&#xff0c;则每个RTU字符首先应分为高位和低位两部分&#xff0c;这两部分各含4位&#xff0c;然后转换成十六进制等量值。用以构成报文的ASCII字符都是十六进制字符。ASCII模式使用的字符虽是RTU模式的两倍&#xff0c;但ASCII数据的译玛和处理更为容易一些&#xff0c;此外&#xff0c;用RTU模式时报文字符必须以连续数据流的形式传送&#xff0c;用ASCII模式&#xff0c;字符之间可产生长达1s的间隔&#xff0c;以适应速度较快的机器。

表4给出了以RTU方式读取整数据的例子

以RTU方式读取整数据的例子

主机请求

地址

功能码

第一个寄存器的高位地址

第一个寄存器的低位地址

寄存器的数量的高位

寄存器的数量的底位

错误校验

01

03

00

38

00

01

XX


从机应答

地址

功能码

字节数

数据高字节

数据低字节

错误校验

01

03

2

41

24

XX

十六进制数4124表示的十进制整数为16676&#xff0c;错误校验值要根据传输方式而定。

&#xff08;2&#xff09;ModBus的数据校验方式

CRC-16&#xff08;循环冗余错误校验&#xff09;

CRC-16错误校验程序如下&#xff1a;报文&#xff08;此处只涉及数据位&#xff0c;不指起始位、停止位和任选的奇偶校验位&#xff09;被看作是一个连续的二进制&#xff0c;其最高有效位&#xff08;MSB&#xff09;首选发送。报文先与X↑16相乘&#xff08;左移16位&#xff09;&#xff0c;然后看X↑16&#43;X↑15&#43;X↑2&#43;1除&#xff0c;X↑16&#43;X↑15&#43;X↑2&#43;1可以表示为二进制数11000000000000101。整数商位忽略不记&#xff0c;16位余数加入该报文&#xff08;MSB先发送&#xff09;&#xff0c;成为2个CRC校验字节。余数中的1全部初始化&#xff0c;以免所有的零成为一条报文被接收。经上述处理而含有CRC字节的报文&#xff0c;若无错误&#xff0c;到接收设备后再被同一多项式&#xff08;X↑16&#43;X↑15&#43;X↑2&#43;1&#xff09;除&#xff0c;会得到一个零余数&#xff08;接收设备核验这个CRC字节&#xff0c;并将其与被传送的CRC比较&#xff09;。全部运算以2为模&#xff08;无进位&#xff09;。

习惯于成串发送数据的设备会首选送出字符的最右位&#xff08;LSB-最低有效位&#xff09;。而在生成CRC情况下&#xff0c;发送首位应是被除数的最高有效位MSB。由于在运算中不用进位&#xff0c;为便于操作起见&#xff0c;计算CRC时设MSB在最右位。生成多项式的位序也必须反过来&#xff0c;以保持一致。多项式的MSB略去不记&#xff0c;因其只对商有影响而不影响余数。

生成CRC-16校验字节的步骤如下&#xff1a;

①装如一个16位寄存器&#xff0c;所有数位均为1。

②该16位寄存器的高位字节与开始8位字节进行“异或”运算。运算结果放入这个16位寄存器。

③把这个16寄存器向右移一位。

④若向右&#xff08;标记位&#xff09;移出的数位是1&#xff0c;则生成多项式1010000000000001和这个寄存器进行“异或”运算&#xff1b;若向右移出的数位是0&#xff0c;则返回③。

⑤重复③和④&#xff0c;直至移出8位。

⑥另外8位与该十六位寄存器进行“异或”运算。

⑦重复③~⑥&#xff0c;直至该报文所有字节均与16位寄存器进行“异或”运算&#xff0c;并移位8次。

⑧这个16位寄存器的内容即2字节CRC错误校验&#xff0c;被加到报文的最高有效位。

另外&#xff0c;在某些非ModBus通信协议中也经常使用CRC16作为校验手段&#xff0c;而且产生了一些CRC16的变种&#xff0c;他们是使用CRC16多项式X↑16&#43;X↑15&#43;X↑2&#43;1&#xff0c;单首次装入的16位寄存器为0000&#xff1b;使用CRC16的反序X↑16&#43;X↑14&#43;X↑1&#43;1&#xff0c;首次装入寄存器值为0000或FFFFH。

LRC&#xff08;纵向冗余错误校验&#xff09;

LRC错误校验用于ASCII模式。这个错误校验是一个8位二进制数&#xff0c;可作为2个ASCII十六进制字节传送。把十六进制字符转换成二进制&#xff0c;加上无循环进位的二进制字符和二进制补码结果生成LRC错误校验&#xff08;参见图&#xff09;。这个LRC在接收设备进行核验&#xff0c;并与被传送的LRC进行比较&#xff0c;冒号&#xff08;&#xff1a;&#xff09;、回车符号&#xff08;CR&#xff09;、换行字符&#xff08;LF&#xff09;和置入的其他任何非ASCII十六进制字符在运算时忽略不计。

表5 LRC生成范例&#xff0d;&#xff0d;读取02号从机的前8个线圈

十六进制

二进制

地址

0

2

0000

0010

功能码

0

1

0000

0001

起始地址高位

0

0

0000

0000

起始地址低位

0

0

0000

0000

单元数量

0

0

0000

0000

0

8

&#43;

0000

1000

0000

1011

变成补码

1111

0101

错误校验

F

5

F

5

接受PC把所有收到的数据字节&#xff08;包括最后的LRC&#xff09;加在一起&#xff0c;8位应全部为0&#xff08;注意&#xff1a;和可能超过8位&#xff0c;应略去最低位&#xff09;

0000

0010

0000

0001

0000

0000

0000

0000

0000

0000

0000

1000

错误校验

1111

0101

0000

0000

 




推荐阅读
  • 本文探讨了一个Web工程项目的需求,即允许用户随时添加定时任务,并通过Quartz框架实现这些任务的自动化调度。文章将介绍如何设计任务表以存储任务信息和执行周期,以及如何通过一个定期扫描机制自动识别并加载新任务到调度系统中。 ... [详细]
  • 构建Python自助式数据查询系统
    在现代数据密集型环境中,业务团队频繁需要从数据库中提取特定信息。为了提高效率并减少IT部门的工作负担,本文探讨了一种利用Python语言实现的自助数据查询工具的设计与实现。 ... [详细]
  • 深入解析mt_allocator内存分配器(二):多线程与单线程场景下的实现
    本文详细介绍了mt_allocator内存分配器在多线程和单线程环境下的实现机制。该分配器以2的幂次方字节为单位分配内存,支持灵活的配置和高效的性能。文章分为内存池特性描述、内存池实现、单线程内存池实现、内存池策略类实现及多线程内存池实现等部分,深入探讨了内存池的初始化、内存分配与回收的具体实现。 ... [详细]
  • 本文详细解析 Skynet 的启动流程,包括配置文件的读取、环境变量的设置、主要线程的启动(如 timer、socket、monitor 和 worker 线程),以及消息队列的实现机制。 ... [详细]
  • 本文详细介绍了Golang中string类型的内部结构及其特性,包括字符串的定义、表示方式、数据结构以及相关的操作方法,如字符串拼接和类型转换等。 ... [详细]
  • 本文介绍了一个基本的同步Socket程序,演示了如何实现客户端与服务器之间的简单消息传递。此外,文章还概述了Socket的基本工作流程,并计划在未来探讨同步与异步Socket的区别。 ... [详细]
  • 本文深入探讨了领域驱动设计(DDD)中的聚合概念及其在事件溯源架构中的应用。聚合是一组紧密相关的类,这些类作为一个整体运作,形成一个有明确边界的组织。只有通过聚合根才能与聚合内的对象进行交互。 ... [详细]
  • 深入解析C++ Atomic编程中的内存顺序
    在多线程环境中,为了防止多个线程同时修改同一数据导致的竞争条件,通常会使用内核级同步对象,如事件、互斥锁和信号量等。然而,这些方法往往伴随着高昂的上下文切换成本。本文将探讨如何利用C++11中的原子操作和内存顺序来优化多线程编程,减少不必要的开销。 ... [详细]
  • 利用Git GUI将本地项目同步至GitHub的方法
    GitHub作为开发者不可或缺的工具,不仅提供了丰富的开源项目资源,还极大地便利了个人项目的管理和版本控制。本文将详细介绍如何使用Git GUI工具将本地开发的项目上传至GitHub。 ... [详细]
  • 本文档提供了首次周测的答案解析,涵盖特殊符号、命令作用、路径说明以及实战练习等内容。 ... [详细]
  • Node.js 断点调试指南
    本文详细介绍了利用Google Chrome DevTools和Visual Studio Code两种工具进行Node.js应用的断点调试技巧。 ... [详细]
  • 本文详细介绍了Objective-C中的面向对象编程概念,重点探讨了类的定义、方法的实现、对象的创建与销毁等内容,旨在帮助开发者更好地理解和应用Objective-C的面向对象特性。 ... [详细]
  • 华为云openEuler环境下的Web应用部署实践
    本文详细记录了在华为云openEuler系统上进行Web应用部署的具体步骤,包括配置yum源、安装Apache、MariaDB、PHP及其相关组件,并完成WordPress的安装与配置过程。 ... [详细]
  • 来自FallDream的博客,未经允许,请勿转载,谢谢。一天一套noi简直了.昨天勉强做完了noi2011今天教练又丢出来一套noi ... [详细]
  • 本文详细介绍了Socket在Linux内核中的实现机制,包括基本的Socket结构、协议操作集以及不同协议下的具体实现。通过这些内容,读者可以更好地理解Socket的工作原理。 ... [详细]
author-avatar
欣仪威侑扬芸_782
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有