当前位置:网站首页 > 编程语言 > 正文

modbus报文解析10号功能码(modbus16功能码的报文组织)



什么是协议:是一种约定或规则或规则,它在计算机网络和通信领域起着至关重要的作用。具体来说,协议是网络中(或一般业务中)进行数据交换和解释信息时所要遵守的一套规则和约定,或者说是通信双方共同遵守的一组规则或标准。这些规则或标准详细定义了信息的格式、传输的顺序、控制信息以及同步机制等各个方面。

什么是modbus协议:Modbus协议是一种串行通信协议,由Modicon公司(现为施耐德电气Schneider Electric)于1979年发表,旨在实现可编辑逻辑控制器(PLC)之间的通信。如今,它已经成为工业领域通信协议的业界标准,并且是工业电子设备之间常用的连接方式。Modbus是主从方式通信,也就是说,不能同步进行通信,总线上每次只有一个数据进行传输,既主机发送,从机应答,主机不发送,总线上就没有数据通信。一个主线上只能有一个主句,可以有若干个从机。

什么是串行通信协议:串行通信是一种计算机通信方式,它在主机与外设以及主机之间的数据传输中起着重要作用。串行通信是指数据按位依次传输的通信方式,每位数据占据固定的时间长度,并使用少数几条通信线路完成系统间的信息交换。在串行通信中,数据被分解为一系列单独的比特(位),并按顺序通过传输线进行传输。每个比特在传输线上占用固定的时间长度,这样接收端就可以按照相同的时序接收并重组这些数据位,从而回复出原始数据

Modbus协议广泛应用于工业控制和自动化领域,可以连接各种设备和控制器,用于实现数据交换、监控和控制。具体包括:

  1. 工业自动化控制:Modbus被广泛应用于工业自动化控制系统中,用于连接PLC、传感器、执行器等设备,实现监控和控制
  2. 智能家居:Modbus协议可以应用于智能家居系统中,用于连接各种传感器和执行器,实现远程控制和检测
  3. 能源监控:Modbus协议可以用于能源监控系统,连接电表、燃气表、水表等设备,实现能源数据的采集和分析。
  4. 环境检测:Modbus协议可以应用于环境检监测系统中,连接各种传感器和仪器,监测环境参数如温度、湿度、气压等。
  5. 智能交通:Modbus可以应用于智能交通系统中,用于连接交通控制设备、车辆检测器等,实现交通信号的控制和管理

总的来说,就是约定了一套设备之间数据交互的规则,用于各种设备之间进行通信的。

3.1 Modbus概述

modbus分为以下三种协议:

  • Modbus-RTU
  • Modbus-TCP
  • Modbus-ASCII

以上三种协议,比较常用的 Modbus-RTU 协议,其次是 Modbus-TCP 协议,一个设备只会有一种协议。

Modbus是主从方式通信

什么是帧:Modbus每发送一次数据就是一个数据帧,每个数据帧都必须符合modbus的帧结构。

3.2 Modbus-RTU

设备必须要有RTU协议!这是Modbus协议上规定的,且默认模式必须是 RTU,ASCLL作为选项。

也就是说,大部分时候我们都是使用 Modbus-RTU协议进行通信

3.2.1 帧格式

帧结构 = 地址 + 功能码 + 数据 + 校验

  • 地址(设备编号):占用一个字节,范围是 0-255,其中有效范围是 1-247,其他有特殊用途,比如 255 是广播地址(广播就是应答所有地址,正常的需要两个设备的地址一样才能进行查询和回复)
  • 功能码:占一个字节,功能码的意义就是,知道这个指令是干啥的,就是告诉从机你要执行什么操作(常用 0x03,0x06和0x10功能码)
  • 数据:根据功能码的不同,数据会有不同的结构,具体详见下面的分析
  • 校验:为了保证数据不错误,需传输校验码进行校验,如果校验无误则代表传输的数据并没有丢失。校验的算法为CRC冗余校验
3.2.2 0x03查询寄存器功能码

如果有硬件条件,使用支持modbus协议的设备,通过串口连接主机以及设备,同时打开串口调试工具按下面的进行操作

 

如果通过发送上面的数据,从机返回对应数据,则代表我们成功通过串口实现了受用 modbus 协议进行通信

来分析上面的报文

 

02:从机地址,这里是发给设备编号为02的从机,占1bit

03:功能码,0x03代表查询寄存器功能,占1bit

8000:要查询的起始寄存器地址,这里寄存器地址为 0x8000,占2bit

0002:要查询几个寄存器,这里查询2(0x0002)个寄存器,占2bit

ED F8:CRC校验码,通过CRC算法算的,占2bit

这串报文简单化来讲就是,我向02设备发送报文(02),告诉02设备我要查询寄存器(03功能码),寄存器起始地址是0x8000(根据实际需要修改寄存器地址),我要查询 2(0002)个寄存器,为了保证我发的这个报文是没有被人动过的,我告诉02设备,我这个报文的密码是 ED F8(CRC校验码),02设备你收到我发给你的报文后,看下这个密码能不能打开报文(从机设备会将除校验码外的其他报文用CRC算法进行计算,并比对报文中的CRC校验码,一致则代表报文是完整的),打不开的话那就是我这边给错密码了,或者是中间丢失了一些东西(报文不完整)

 

02:从机地址,这里是返回的设备编号为02的从机,占1bit

03:功能码,0x03代表查询寄存器功能,占1bit

04:返回的数据长度,数值为 2x查询的寄存器个数,占1bit

0000:查询0x8000寄存器数据,占2bit

2009:查询0x8001寄存器数据,占2bit

10 F5:CRC校验码,通过CRC算法算的,占2bit

注:功能码和CRC校验中间的为查询后返回的数据,长度为 2bit x 查询的寄存器个数,每2bit作为一个返回的值

这串报文简单化来讲就是,02设备说我是02设备(02),刚刚执行的是查询寄存器的操作(03),总共返回的数据长度为为4bit(04),返回的数据为 0x0000 和 0x2009(0000 2009),主机你收到我的报文后用 10 F5 作为密码进行打开(CRC校验码)

也就是说,

主机发送的报文就是: 找谁(从机地址) + 要干嘛(功能码) + 具体要干的事情细节(数据:寄存器起始地址 + 查询的寄存器个数)+ 验证

从机发送的报文就是: 我是谁(从机地址) + 刚刚干了什么事情(功能码) + 干了几件事情(查询的寄存器个数) + 每件事情的结果(数据:寄存器里面的值)+ 验证

3.2.3 0x06修改寄存器功能码

报文如下

 

对上面报文进行分析

 

02:从机地址,这里是发给设备编号为02的从机,占1bit

06:功能码,0x06代表修改寄存器功能,占1bit

A80A:要修改的寄存器地址,这里寄存器地址为 0xA80A,占2bit

0001:修改后的值,这里为 0x0001,占2bit

48 5B:CRC校验码,通过CRC算法算的,占2bit

0x06发送的报文和0x03发送的报文很像,区别就是0x03修改寄存器的个数咋 0x06 就是修改后的数据,可以进行联想记忆。

这串报文简单化来讲就是,主机向02设备发送报文(02),告诉02设备我要修改寄存器(06),修改的寄存器地址为 0xA80A (A80A ),修改后的数据为 0x0001(0001),打开这个报文的密码是 48 5B(CRC校验码)

 

这里可以看到,0x06修改命令返回的报文和发送的报文是一致的,但他们代表的意义是不同的,当然,除了一些特殊的从机地址,可以按照返回的报文和发送的报文一致来判断返回报文是否正确

02:从机地址,这里是返回的设备编号为02的从机,占1bit

06:功能码,0x06代表修改寄存器功能,占1bit

8000:已经修改的寄存器地址,这里寄存器地址为 0xA80A,占2bit

0001:修改完成后该寄存器的值,这里为 0x0001,占2bit

48 5B:CRC校验码,通过CRC算法算的,占2bit

这串报文简单化来讲就是,02设备向主机发送报文,告诉主机我是02设备(02),刚刚执行了修改寄存器(0x06),修改后的寄存器地址为 0xA80A (A80A ),修改后的数据为 0x0001(0001),打开这个报文的密码是 48 5B(CRC校验码)

3.2.3 0x10批量修改寄存器功能码

在批量修改或者修改32位寄存器(32位寄存器在存储时占了两个16位的寄存器)时使用这个命令

报文如下

 

对上面报文进行分析

 

02:从机地址,这里是发给设备编号为02的从机,占1bit

10:功能码,0x10代表批量修改寄存器功能,占1bit

A806:要修改的寄存器起始地址,这里寄存器起始地址为 0xA806,占2bit

0002:修改的寄存器个数,这里为 0x0002,占2bit

04:修改的数据长度,数值为 2x修改的寄存器个数,这里为 0x04,占1bit

000F:修改的第一个寄存器的值,这里为 0x000F,占2bit

0003:修改的第二个寄存器的值,这里为000F,占2bit

93 04:CRC校验码,通过CRC算法算的,占2bit

这个报文和发送0x03查询的报文有点相似,就是在查询寄存器个数后面增加了要发送的数据的长度和具体数据,可以联想来记忆

这串报文简单化来讲就是,主机向02设备发送报文(02),告诉02设备我要批量修改寄存器(10功能码),被修改的寄存器起始地址是0xA806(A806),我要修改 2(0002)个寄存器,我接下来要修改的值长度位 0x04(04),第一个寄存器的值要改为 0x000F(000F),第二个寄存器的值要改为 0x0003(0003),为了保证我发的这个报文是没有被人动过的,我告诉02设备,我这个报文的密码是 93 04(CRC校验码),

 

02:从机地址,这里是发给设备编号为02的从机,占1bit

10:功能码,0x10代表批量修改寄存器功能,占1bit

A806:已经修改的寄存器起始地址,这里寄存器起始地址为 0xA806,占2bit

0002:修改好了的寄存器个数,这里为 0x0002,占2bit

81 9A:CRC校验码,通过CRC算法算的,占2bit

这串报文简单化来讲就是,02设备向主机发送报文,告诉主机我是02设备(02),刚刚执行了批量修改寄存器(0x10),修改后的寄存器地址为 0xA806 (A806 ),修改好的寄存器个数为 0x0002(0002),打开这个报文的密码是 81 9A(CRC校验码)

注:32位的寄存器需要用 0x10功能码进行批量修改,不能用0x6修改单个寄存器的功能码修改

3.3 Modbus-TCP

Modbus-TCP 报文帧的格式和 Modbus-RTU是差不多的,区别就在于 Modbus-TCP 采用的是TCP进行连接,而非串口,报文帧的头部比Modbus-RTU要多了6bit的数据, Modbus-TCP不需要做CRC冗余校验。

Modbus-TCP 的报文头部起始为 :

  • 事物处理标识符:长度2bit,可以理解为报文的序列号,一般每次通信之后就要加1以区别不同的通信数据报文
  • 协议标识符:长度2bit, 0x0000 代表 Modbus-TCP协议
  • 长度:长度2bit,表示接下来的字节长度,单位字节

报文头部,Nodbus-TCP的报文帧在Modbus-RTU 的基础上,在增加了上面 6 bit 的数据

报文尾部,Nodbus-TCP不需要做CRC冗余校验

以 0x03 查询功能码为例

 

00 01 00 00 00 0B

00 01:事物处理标识符

00 00:Modbus-TCP协议

00 0B:接下来的数据长度为 11(0x000B) 个

02 10 A8 06 00 02 04 00 0F 00 03:与前面RTU的报文格式差不多,只是少了CRC冗余校验码

3.4 Modbus-ACSSII

一般只需要了解RTU协议,因为Modbus协议的设备都必须有 Modbus-RTU协议,至于ACSLL协议,做个大概了解即可

3.4.1 帧形式

对于RTU协议,比如RTU协议发送一个字节:0x12;ASCLL协议则需要发送2个字节:1个字节代表ASCLL码1,一个代表ASCLL码2,既0x31和0x32才能代表0x12.所以,ASCLL协议的效率比较低。但是,ASCLL更符合串口打印查看,因为串口发送的数据一般都是文本模式(ASCLL)。

但是因为RTU一个字节ASCLL需要两个字节来表示,所以ASCLL发送的数据量是RTU的两倍,ASCLL的效率更低

那么ASCLL码效率更低,数据发送量大为啥还采用这种方式呢?

因为假如你要发送数据0x03,采用RTU方式(16进制发送),计算机终端设备接收到0x03后是不可以显示的,就是不能把0x03打印出来。因为可见字符的ASCLL码是从32-126,不是这个范围以外的显示屏上都看不到,会出现乱码,如果是串口助手的话就会显示口口口口。如果采用ASCLL方式(文本模式发送),就不会出现不可显示和乱码的情况,因为文本模式发送0x03,就是发送ASCLL码0和ASCLL码3.也就是0x30和0x33,是可以正常显示在计算机终端的。所以ASCLL效率虽然低,但方便调试显示。

从上图可以看出:

  1. 比TRU多了起始段 : ,多个结束符 CR,LF
  2. 地址和功能都变成了2个字节
  3. 数据部分更加繁琐,但更符合人们的查看

3.5 CRC冗余校验

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

二字节的错误校验码,低字节在前,高字节在后。

 

底层代码实现比较需要注意的就是高低位的转换,下面是高低位的提取代码

 

4.1 Modbus-RTU

需先导入串口通信的包 jSerialComm

 
 

4.2 Modbus-TCP

通过创建 socket 实现Modbus 的TCP连接,报文解析和Modbus-RTU差不多,多了头部6个字节的解析以及少了后面的CRC冗余码

 

还有一些比较深入的内容没有讲到,比如数据模型之类,下面的内容也比较零散,详见这个视频的讲解,感兴趣可以自己研究

这节课带你吃透Modbus通信协议_哔哩哔哩_bilibili

线圈(布尔量,开关)

存储区:

​ 输出线圈: 0

​ 0 0001 - 0 9999

​ 0 00001 - 065536

​ 输入线圈: 1

​ 1 0001 - 1 9999

​ 1 00001 -

​ 输出寄存器:4

​ 4 0001 - 4 9999

​ 4 00001 -

​ 输入寄存器:3

​ 3 0001 - 3 9999

​ 3 00001 -

存储区范围:5位(标准地址)和6位(拓展地址)

​ 第一位表示区域,后面几位表示地址

读和写 功能码

读可以读输入和输出的,写只能写输出的,写可以单个写,也可以多个写

读输出线圈 01

读输入线圈 02

读输出寄存器 03

读输入寄存器 04

单个输出线圈 05

单个输出寄存器 06

多个输出线圈 15 (OxF)

多个输出寄存器 16 (Ox10)

到此这篇modbus报文解析10号功能码(modbus16功能码的报文组织)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 腾讯会员怎么分享二维码登录(腾讯会员怎么分享二维码登录手机)2025-01-01 14:09:05
  • 2258xt固件全套(2258xt最新2019固件)2025-01-01 14:09:05
  • 双系统删除ubuntu重装(双系统卸载ubuntu系统并重装)2025-01-01 14:09:05
  • py文件是什么(pyd文件是什么)2025-01-01 14:09:05
  • st7735r(st7735r 7735s区别)2025-01-01 14:09:05
  • 卡巴斯基设置(卡巴斯基设置白名单)2025-01-01 14:09:05
  • 免费海报制作模板(免费海报制作模板psd)2025-01-01 14:09:05
  • u盘启动盘制作工具下载安装(最新u盘启动盘制作工具)2025-01-01 14:09:05
  • 合并数组的方法包括(合并数组的方法包括哪几种)2025-01-01 14:09:05
  • 颜色代码黑色怎么调(颜色代码黑色怎么调出来)2025-01-01 14:09:05
  • 全屏图片