Modbus各个功能码报文解析及实例

sunnyroc  2023-02-11 15:42  阅读 4,927 次 评论 0 条
大神带你秒懂Modbus通信协议_网络协议

 

Modbus 协议是:
  • Modbus 是由 Modicon(现为施耐德电气公司的一个品牌)在 1979 年发明的一种工业控制总线协议,是全球第一个真正用于工业现场的总线协议。Modbus 以其简单、健壮、开放而且不需要特许授权的特点,成为通用通信协议。为了适应以太网环境,Modbus 被封装在 TCP 包中,并且在默认情况下通过 TCP 协议的 502 端口进行传输。
  • 基于 Modbus 协议的系统由带智能终端的可编程逻辑控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件,又包括软件。可应用于各种数据采集和过程监控。
  • Modbus 协议采用主 - 从结构,为客户机和服务器之间提供通信连接。
  • Modbus 协议定义了一个与基础通信无关的协议数据单元(Protocol Description Unit,PDU),描述协议的基本功能。PDU 属于应用数据单元(Application Data Unit,ADU)的一部分,除此之外,ADU 还包括附加地址域和差错校验域及实际传输的数据,这个数据可能是业务数据,也可能是指令、响应信息或报警信息等。
  • Modbus 协议包括 ASCIIRTU、TCP 三种报文类型,可以使用串口传输数据和指令。

 

一、功能码 03:读保持寄存器

可读多个或者单个寄存器内容主机请求

域名 所占字节数 可输入的数据内容
从机地址 1个字节 根据从机地址而定
功能码 1个字节 0x03
寄存器起始地址 2个字节 根据所要读取的寄存器位置而定,范围是0x0000 至 0xFFFF
寄存器数目 2个字节 1 至 125(0x7D)
CRC校验码 2个字节 根据前面的数据计算出来
从机响应
域名 所占字节数 返回的数据内容
:–: :– :–:
从机地址 1个字节 从机地址
功能码 1个字节 0x03
字节数 1个字节 2×N
寄存器的值 N×2 个字节 根据所读取的保持寄存器内容而定
CRC校验码 2个字节 根据前面的数据计算出来
N = 寄存器的数量

 

  • 1

从机返回错误帧

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
功能码 1个字节 0x83
异常码 1个字节 01 或 02 或 03 或 04
CRC校验码 2个字节 根据前面的数据计算出来

 

下面是来一个实例:

假如从机地址为1,保持寄存器1~3的内容分别是:0x042B、0x0341、0x0210。现在有一个主机想要从该从机内的保持寄存器地址1处开始读取3个保持寄存器的内容,则下面的报文将是主机所发送的数据帧和接收到的数据帧的内容

主机请求,发送的报文: 01 03 0001 0003 540B

域名 十六进制
从机地址 01
功能码 03
寄存器地址 Hi 00
寄存器地址 Lo 01
寄存器数目 Hi 00
寄存器数目 Lo 03
CRC高字节 54
CRC低字节 0B
从机响应,主机收到的报文:01 03 042B 0341 0210 C7B9
域名 十六进制
:– :–:
从机地址 01
功能码 03
字节数 06
(01)寄存器的值 Hi 04
(01)寄存器的值 Lo 2B
(02)寄存器的值 Hi 03
(02)寄存器的值 Lo 41
(03)寄存器的值 Hi 02
(03)寄存器的值 Lo 10
CRC高字节 C7
CRC低字节 b9

 

二、功能码 06:写单个保持寄存器
写单个保持寄存器的返回帧和写入帧是一模一样
主机------------请求

域名 所占字节数 可输入的数据内容
从机地址 1个字节 根据从机地址而定
功能码 1个字节 0x06
寄存器地址 2个字节 根据所要写入的寄存器位置而定,范围是0x0000 至 0xFFFF
寄存器值 2个字节 0x0000 至 0xFFFF
CRC校验码 2个字节 根据前面的数据计算出来

从机------------响应

域名 所占字节数 返回的数据内容
从机地址 1个字节 根据从机地址而定
功能码 1个字节 0x06
寄存器地址 2个字节 根据从机被读取的地址而定,范围是0x0000 至 0xFFFF
寄存器值 2个字节 根据从机所存放的数据而定,范围是0x0000 至 0xFFFF
CRC校验码 2个字节 根据前面的数据计算出来

错误

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
差错码 1个字节 0x86
异常码 1个字节 01 或 02 或 03 或 04
CRC校验码 2个字节 根据前面的数据计算出来

 

来一个实例:
假如从机地址为1,现在有一个主机想要从该从机内的保持寄存器地址1处写入0x0C02,则下面的报文将是主机所发送的数据帧和接收到的数据帧的内容

主机请求,发送的报文:01 06 0001 0C02 5CCB

域名 十六进制
从机地址 01
功能码 06
寄存器地址高字节 00
寄存器地址低字节 01
(要写入的数据)的高字节 0C
(要写入的数据)的低字节 02
CRC高字节 5C
CRC低字节 CB

从机响应,主机收到的报文:01 06 0001 0C02 5CCB

域名 十六进制
从机地址 01
功能码 06
寄存器地址高字节 00
寄存器地址低字节 01
寄存器的值 HI 0C
寄存器的值 Lo 02
CRC高字节 5C
CRC低字节 CB
写单个保持寄存器的成功的话,它的返回帧和写入帧是一模一样

 

三、功能码 10:写多个保持寄存器

主机------------请求

域名 所占字节数 可输入的数据内容
从机地址 1个字节 根据从机地址而定
功能码 1个字节 0x10
寄存器起始地址 2个字节 根据所要写入的寄存器位置而定,范围是0x0000 至 0xFFFF
寄存器数目 2个字节 根据所要写入的寄存器数目而定,范围是0x0001 至 0x0078
字节数 1个字节 2×N
寄存器值 N×2 个字节 要写入的数据值
CRC校验码 2个字节 根据前面的数据计算出来
N = 寄存器的数量

 

  • 1

从机------------响应

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
功能码 1个字节 0x10
寄存器起始地址 2 个字节 根据被写入的寄存器地址而定,范围是0x0000 至 0xFFFF
寄存器数目 2个字节 1 至 123(0x7B)
CRC校验码 2个字节 根据前面的数据计算出来

错误

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
差错码 1个字节 0x90
异常码 1个字节 01 或 02 或 03 或 04
CRC校验码 2个字节 根据前面的数据计算出来

 

来一个实例:
假如从机地址为1,现在有一个主机想要从该从机内的保持寄存器地址1~3写入0x0101 、0x0202、0303 ,则下面的报文将是主机所发送的数据帧和接收到的数据帧的内容

主机请求,发送的报文: 01 10 0001 0003 06 0101 0202 0303 6BDD

域名 十六进制
从机地址 01
功能码 10
寄存器地址 Hi 00
寄存器地址 Lo 01
寄存器数量 Hi 00
寄存器数量 Lo 03
字节数 06
寄存器的值 Hi(01) 01
寄存器的值 Lo(01) 01
寄存器的值 Hi(02) 02
寄存器的值 Lo(02) 02
寄存器的值 Hi(03) 03
寄存器的值 Lo(03) 03
CRC高字节 2F
CRC低字节 09

从机响应,主机收到的报文:01 10 0001 0003 D1C8

域名 十六进制
从机地址 01
功能码 10
寄存器地址Hi 00
寄存器地址Lo 01
寄存器数量 Hi 00
寄存器数量 Lo 03
CRC高字节 D1
CRC低字节 C8

 

四、功能码 17:读/写多个保持寄存器

主机------------请求

域名 所占字节数 可输入的数据内容
从机地址 1个字节 根据从机地址而定
功能码 1个字节 0x17
读起始地址 2个字节 根据所要读取的寄存器位置而定,范围是0x0000 至 0xFFFF
要读的寄存器数目 2个字节 根据所要读取的寄存器数目而定,范围是0x0001 至近似 0x0076
写起始地址 2个字节 根据所要写入的寄存器位置而定,范围是0x0000 至 0xFFFF
要写入的寄存器数目 2个字节 根据所要写入的寄存器数目而定,范围是0x0001 至近似 0x0076
字节数 1个字节 2×N
要写入的寄存器的值 N×2 个字节 要写入的数据值
CRC校验码 2个字节 根据前面的数据计算出来
N = 要写入的寄存器的数量

 

  • 1

从机------------响应

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
功能码 1个字节 0x17
字节数 1个字节 2×N
寄存器的值 N×2 个字节 根据所读取的保持寄存器内容而定
CRC校验码 2个字节 根据前面的数据计算出来
*N = 要读取到的寄存器的数量

 

  • 1

错误

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
差错码 1个字节 0x97
异常码 1个字节 01 或 02 或 03 或 04
CRC校验码 2个字节 根据前面的数据计算出来

 

 

来一个实例:
假如从机地址为1,保持寄存器1~3的内容分别是:0x042B、0x0341、0x0210。
现在有一个主机想要从该从机内的保持寄存器地址1处读取3个保持寄存器的数据,并向保持寄存器地址4~5写入0x0101 、0x0202,则下面的报文将是主机所发送的数据帧和接收到的数据帧的内容。

主机请求,发送的报文: 01 17 0001 0003 0004 0002 04 0101 0202 BA28

域名 十六进制
从机地址 01
功能码 17
读寄存起始地址 Hi 00
读寄存器起始地址 Lo 01
读的寄存器数量 Hi 00
读的寄存器数量 Lo 03
写寄存起始地址 Hi 00
写寄存器起始地址 Lo 04
写的寄存器数量 Hi 00
写的寄存器数量 Lo 02
要写入的数据的字节数 04
(04)要写入的值 Hi 01
(04)要写入的值 Lo 01
(05)要写入的值 Hi 02
(05)要写入的值 Lo 02
CRC高字节 BA
CRC低字节 28

**从机响应,主机收到的报文:01 17 06 042B 0341 0210 54F4 **

域名 十六进制
从机地址 01
功能码 17
读取到的字节数 06
(01)读取到的寄存器的值 Hi 04
(01)读取到的寄存器的值 Lo 2B
(02)读取到的寄存器的值 Hi 03
(02)读取到的寄存器的值 Lo 41
(03)读取到的寄存器的值 Hi 02
(03)读取到的寄存器的值Lo 10
CRC高字节 54
CRC低字节 F4

 

五、功能码 14:读文件记录

主机------------请求

域名 所占字节数 可输入的数据内容
从机地址 1个字节 根据从机地址而定
功能码 1个字节 0x14
字节数 1字节 根据此数据帧后面还需要发送的数据的字节数,不包含CRC,范围是0x07 至 0xF5 字节
子请求 x,参考类型 1个字节 06
子请求 x,文件号 2 个字节 根据所需要读取的文件号而定,范围是0x0000 至 0xFFFF
子请求 x,记录号 2个字节 根据所需要读取的记录号而定,也可以说是寄存器起始地址,范围是0x0000 至 0x270F
子请求 x,记录长度 2个字节 根据所需要读取的寄存器数目N而定,范围是0x0000 至 0x270F
子请求 x+1,…
CRC校验码 2个字节 根据前面的数据计算出来

从机------------响应

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
功能码 1个字节 0x14
响应数据长度 1个字节 根据此数据帧后面还需要发送的数据的字节数,不包含CRC,范围是0x07 至 0xF5
子请求 x,文件响应长度 1个字节 根据当前文件号下的数据长度而定,范围是0x07 至 0xF5
子请求 x,参考类型 1字节 0x06
子请求 x,记录数据 N×2 个字节 根据所读取到寄存器数据而定
子请求 x+1,…
CRC校验码 2个字节 根据前面的数据计算出来
N 该文件下所需要读取的记录长度,也就是寄存器数目

 

  • 1

错误

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
差错码 1个字节 0x94
异常码 1个字节 01 或 02 或 03 或 04 或08
CRC校验码 2个字节 根据前面的数据计算出来

 

来一个实例:
假如从机地址为1,它有2个文件:文件号分别是3、4。其中文件3以寄存器地址9开始,有2个寄存器:0x1101、0x2202;文件4以寄存器地址1开始,有4个寄存器:0x3303、0x4404、0x5505、0x6606。
现在主机需要去读取这2个文件的内容。

**主机请求,发送的报文: 01 14 0E 06 0003 0009 0002 06 0004 0001 0003 751E **

域名 十六进制
从机地址 01
功能码 14
字节数 0E
子请求 1,参考类型 06
子请求 1,文件号 Hi 00
子请求 1,文件号 Lo 03
子请求 1,记录号 Hi 00
子请求 1,纪录号 Lo 09
子请求 1,记录长度 Hi 00
子请求 1,纪录长度 Lo 02
子请求 2,参考类型 06
子请求 2,文件号 Hi 00
子请求 2,文件号 Lo 04
子请求 2,记录号 Hi 00
子请求 2,纪录号 Lo 01
子请求 2,记录长度 Hi 00
子请求 2,纪录长度 Lo 04
CRC高字节 75
CRC低字节 1E

从机响应,主机收到的报文:01 17 10 05 06 1101 2202 09 06 3303 4404 5505 6606 5BC9

域名 十六进制
从机地址 01
功能码 14
响应数据长度 10
子请求 1,文件响应长度 05
子请求 1,参考类型 06
子请求 1,记录数据Hi 11
子请求 1,记录数据Lo 01
子请求 1,记录数据Hi 22
子请求 1,记录数据Lo 02
子请求 2,文件响应长度 09
子请求 2,参考类型 06
子请求 2,记录数据Hi 33
子请求 2,记录数据Lo 03
子请求 2,记录数据Hi 44
子请求 2,记录数据Lo 04
子请求 2,记录数据Hi 55
子请求 2,记录数据Lo 05
子请求 2,记录数据Hi 66
子请求 2,记录数据Lo 06
CRC高字节 5B
CRC低字节 C9

 

六、功能码 15:写文件记录

写文件记录的发送帧和反馈帧一模一样

 

  • 1

主机------------请求

域名 所占字节数 可输入的数据内容
从机地址 1个字节 根据从机地址而定
功能码 1个字节 0x15
字节数 1字节 根据此数据帧后面还需要发送的数据的字节数,不包含CRC,范围是0x07 至 0xF5 字节
子请求 x,参考类型 1个字节 06
子请求 x,文件号 2 个字节 根据所需要写入的文件号而定,范围是0x0000 至 0xFFFF
子请求 x,记录号 2个字节 根据所需要写入的记录号而定,也可以说是寄存器起始地址,范围是0x0000 至 0x270F
子请求 x,记录长度 2个字节 根据所需要写入的寄存器数目N而定,范围是0x0000 至 0x270F
子请求 x,记录数据 N×2 个字节 要写入的数据值
子请求 x+1,…
CRC校验码 2个字节 根据前面的数据计算出来

从机------------响应

域名 所占字节数 可输入的数据内容
从机地址 1个字节 根据从机地址而定
功能码 1个字节 0x15
字节数 1字节 根据此数据帧后面还需要发送的数据的字节数,不包含CRC,范围是0x07 至 0xF5 字节
子请求 x,参考类型 1个字节 06
子请求 x,文件号 2 个字节 根据所需要写入的文件号而定,范围是0x0000 至 0xFFFF
子请求 x,记录号 2个字节 根据写入的记录号而定,也可以说是寄存器起始地址,范围是0x0000 至 0x270F
子请求 x,记录长度 2个字节 根据写入的寄存器数目N而定,范围是0x0000 至 0x270F
子请求 x,记录数据 N×2 个字节 被写入的数据值
子请求 x+1,…
CRC校验码 2个字节 根据前面的数据计算出来

错误

域名 所占字节数 返回的数据内容
从机地址 1个字节 从机地址
差错码 1个字节 0x95
异常码 1个字节 01 或 02 或 03 或 04 或08
CRC校验码 2个字节 根据前面的数据计算出来

 

来一个实例:
假如从机地址为1,它有一个文件4,文件4以寄存器7为起始地址,有3个寄存器。现在主机需要往里面写数据:0x0101、0x0202、0x0303。

**主机请求,发送的报文: 01 15 0D 06 0004 0007 0003 0101 0202 0303 73FC **

域名 十六进制
从机地址 01
功能码 15
字节数 0D
子请求 1,参考类型 06
子请求 1,文件号 Hi 00
子请求 1,文件号 Lo 04
子请求 1,记录号 Hi 00
子请求 1,纪录号 Lo 07
子请求 1,记录长度 Hi 00
子请求 1,纪录长度 Lo 03
子请求 1,记录数据Hi 01
子请求 1,记录数据Lo 01
子请求 1,记录数据Hi 02
子请求 1,记录数据Lo 02
子请求 1,记录数据Hi 03
子请求 1,记录数据Lo 03
CRC高字节 73
CRC低字节 FC

从机响应,主机收到的报文:01 15 0D 06 0004 0007 0003 0101 0202 0303 73FC

域名 十六进制
从机地址 01
功能码 15
字节数 0D
子请求 1,参考类型 06
子请求 1,文件号 Hi 00
子请求 1,文件号 Lo 04
子请求 1,记录号 Hi 00
子请求 1,纪录号 Lo 07
子请求 1,记录长度 Hi 00
子请求 1,纪录长度 Lo 03
子请求 1,记录数据Hi 01
子请求 1,记录数据Lo 01
子请求 1,记录数据Hi 02
子请求 1,记录数据Lo 02
子请求 1,记录数据Hi 03
子请求 1,记录数据Lo 03
CRC高字节 73
CRC低字节 FC

 

本文地址:https://www.roc666.com/2023/02/industry/bus/modbus.html
版权声明:欢迎分享本文,转载请保留出处!

发表评论


表情