1、modbus协议简介

modbus是工业现场总线通信协议中应用较为成熟稳定的协议。理解起来也比较简单。modbus数据传输采用大端模式

1.1功能码简要说明

modbus定义了不同的功能码来操作不同类型的数据。具体如下:

序号

功能码

名称

读写

寄存器数据类型

说明

1

0x01

读线圈寄存器

R

bit

读输出开关量,每个bit代表一个信号。类比mcu的通用输出口

2

0x02

读离散输入寄存器

R

bit

读输入开关量,每个bit代表一个信号。类比mcu的通用输入口

3

0x03

读保持寄存器

R

uint16

读数据,每个数据是16位

4

0x04

读输入寄存器

R

uint16

读输入数据,每个数据是16位,类比模拟量输入信号

5

0x05

写单个线圈寄存器

W

bit

写输出开关量,每个bit代表一个信号。类比mcu的通用输出口

6

0x06

写单个保持寄存器

W

uint16

写数据,每个数据是16位

7

0x0f

写多个线圈寄存器

W

bit

写输出开关量,每个bit代表一个信号。类比mcu的通用输出口

8

0x10

写多个保持寄存器

W

uint16

写数据,每个数据是16位

1.2线圈寄存器读写操作(读输出口状态,设置输出口状态)

1.2.1 读单个线圈寄存器(功能码0x01)

字节

1

2

3

4

5

6

7

8

说明

通信地址

功能码

数据高地址

数据低地址

数据长度高字节

数据长度低字节

CRC低字节

CRC高字节

示例

0x01

0x01

0x00

0x00

0x00

0x01

0xFD

0xCA

数据地址:开始读取的首地址
数据长度:读取的长度,注意由于线圈寄存器的最小单位是bit,所以改长度对应的读取的bit数量,上面的例子中读取的是地址第一个线圈寄存器的值

如果线圈寄存器的值为1,则返回如下数据:

字节

1

2

3

4

5

5

说明

通信地址

功能码

字节数

数据0

CRC低字节

CRC高字节

示例

0x01

0x01

0x01

0x01

0x90

0x48

1.2.2写单个线圈寄存器(功能码0x05)

将单个线圈寄存器写1,注意写1要发送0xff 0x00

字节

1

2

3

4

5

6

7

8

说明

通信地址

功能码

数据高地址

数据低地址

数据长度高字节

数据长度低字节

CRC低字节

CRC高字节

寄存器置1

0x01

0x05

0x00

0x00

0xFF

0x00

0x8C

0x3A

返回数据为发送的数据:
01 05 00 00 FF 00 8C 3A

将单个线圈寄存器写0,注意写0要发送0x00 0x00

字节

1

2

3

4

5

6

7

8

说明

通信地址

功能码

数据高地址

数据低地址

数据长度高字节

数据长度低字节

CRC低字节

CRC高字节

寄存器置0

0x01

0x05

0x00

0x00

0x00

0x00

0xCD

0xCA

返回的数据为发送的数据:
01 05 00 00 00 00 CD CA

1.2.3读多个线圈寄存器(功能码0x01)

读取两个线圈寄存器,假如线圈寄存器1值为1,线圈寄存器2值为1则,

01 01 00 00 00 02 BD CB
数据返回
01 01 01 03 11 89

返回的值为3,3的2进制表述为11b

1.2.4写多个线圈寄存器(功能码0x0F)

字节

1

2

3

4

5

6

7

8

9

10

说明

通信地址

功能码

数据高地址

数据低地址

线圈数量高字节

线圈数量低字节

字节数量

数据

CRC低字节

CRC高字节

示例

0x01

0x0F

0x00

0x00

0x00

0x02

0x01

0x03

0x9E

0x96

上面的例子是将第一和第二个线圈写入1。0x03的二进制为11b。
返回的数据格式如下:

字节

1

2

3

4

5

6

9

10

说明

通信地址

功能码

数据高地址

数据低地址

线圈数量高字节

线圈数量低字节

CRC低字节

CRC高字节

示例

0x01

0x0F

0x00

0x00

0x00

0x02

0xD4

0x0A

注意,当写入的线圈数量不大于8则字节数量为1,数据为1个字节。如果长度超过8,则字节数量为2,字节8对应1-8线圈的值,字节9对应线圈9-16的值,字节10和11为crc

1.3读输入离散输入寄存器(功能码0x02)

字节

1

2

3

4

5

6

7

8

说明

通信地址

功能码

数据高地址

数据低地址

读取数量高字节

读取数量低字节

CRC低字节

CRC高字节

示例

0x01

0x02

0x00

0x00

0x00

0x04

0xFD

0xCA

上面读取了4个离散输入寄存器的值,假如4个寄存器的值为0101b,则返回数据如下:

字节

1

2

3

4

7

8

说明

通信地址

功能码

字节数量

数据

CRC低字节

CRC高字节

示例

0x01

0x02

0x01

0x05

0x61

0x8b

其中的每个bit代表io口的输入值。

1.4读取输入寄存器(功能码0x04)

输入寄存器读取的是类似模拟量的数据,每个数据占16bit。而离散输入寄存器每个bit占1个bit,这是这两者的区别。

字节

1

2

3

4

5

6

7

8

说明

通信地址

功能码

数据高地址

数据低地址

读取数量高字节

读取数量低字节

CRC低字节

CRC高字节

示例

0x01

0x04

0x00

0x00

0x00

0x01

0x90

0x0a

上面读取了1个输入寄存器值,假如寄存器的值为0x1000,从机的返回如下:

字节

1

2

3

4

7

8

说明

通信地址

功能码

字节数量

寄存器数据高字节

寄存器数据低字节

CRC低字节

CRC高字节

示例

0x01

0x04

0x02

0x10

0x00

0xb4

0xf0

读取4个输入寄存器如下:
01 04 00 00 00 04 F1 C9
返回数据
01 04 08 10 00 10 01 10 02 10 03 F2 90
返回的数据长度:8字节
第一个寄存器值:0x1000
第二个寄存器值:0x1001
第三个寄存器值:0x1002
第四个寄存器值:0x1003

1.5 保持寄存器读写操作

1.5.1读保持寄存器(功能码0x03)

字节

1

2

3

4

5

6

7

8

说明

通信地址

功能码

寄存器高地址

寄存器低地址

读取数量高字节

读取数量低字节

CRC低字节

CRC高字节

示例

0x01

0x03

0x00

0x00

0x00

0x02

0xc4

0x0b

上面读取了两个寄存器的值,假如第一个寄存器值0x147b,第二个寄存器值0x3f8e,则从机的返回数据如下:

字节

1

2

3

4

7

8

9

10

11

说明

通信地址

功能码

字节数量

第一个寄存器数据高字节

第一个寄存器数据低字节

第二个寄存器数据高字节

第二个寄存器数据低字节

CRC低字节

CRC高字节

示例

0x01

0x03

0x04

0x14

0x7b

0x3F

0x8E

0x1E

0x4E

1.5.2写单个保持寄存器(功能码0x06)

字节

1

2

3

4

5

6

7

8

说明

通信地址

功能码

寄存器高地址

寄存器低地址

写入值高字节

写入值低字节

CRC低字节

CRC高字节

示例

0x01

0x06

0x00

0x00

0x00

0x02

0x08

0x0b

如果写入成功:则返回发送下去的值
01 06 00 00 00 02 08 0B
这样就成功将第一个寄存器的值写为0x0002

1.5.3写多个保持寄存器(功能码0x10)

字节

1

2

3

4

5

6

7

8

9

10

11

12

13

说明

通信地址

功能码

寄存器高地址

寄存器低地址

寄存器数量高字节

寄存器数量低字节

写入字节数

第一个寄存器值高字节

第一个寄存器值低字节

第二个寄存器值高字节

第二个寄存器值低字节

CRC低字节

CRC高字节

示例

0x01

0x10

0x00

0x00

0x00

0x02

0x04

0x00

0x01

0x00

0x02

0x23

0xae

如果写入正常则从机的返回值如下:

字节

1

2

3

4

5

6

9

10

说明

通信地址

功能码

数据高地址

数据低地址

线圈数量高字节

线圈数量低字节

CRC低字节

CRC高字节

示例

0x01

0x10

0x00

0x00

0x00

0x02

0x41

0xc8

这样就正常将第一个寄存器写入0x0001,第二个寄存器写入0x0002

1.6 错误反馈

如果发送的命令有问题,则会返回错误帧,如果是crc错误,从机是不会返回任何数据。从机返回错误的格式如下:

字节

1

2

3

9

10

说明

地址码

功能码

错误码

CRC低字节

CRC高字节

示例

0x01

0x80+功能码

0x00

常见错误码

错误码

名称

说明

0x01

非法功能码

不支持该功能码操作寄存器

0x02

非法的寄存器地址

设备没有该地址

0x03

非法的数据

数据格式不对

0x04

从机故障

从机工作不正常

发送:01 06 00 00 01 02 04 00 01 00 02
返回:01 86 03 02 61
错误码为3,说明数据格式错误。上面的数据应该是写多个寄存器0x10,但功能码是写单个寄存器0x06,所有导致错误。

发送:01 16 00 00 01 02 04 00 01 00 02 D3 71
返回:01 96 01 8E 60
错误码为1,说明功能码不对,没有0x16功能码