Modbus简介

Modbus 是一种串行通信协议,是 Modicon 于 1979 年,为使用可编程逻辑控制器(PLC)而发表的。Modbus 是工业领域通信协议的业界标准,并且现在是工业电子设备之间相当常用的连接方式。

格式总览

从机地址 功能码 数据 CRC校验
1字节 1字节 0~252字节 2字节
  • 举例: 01 03 00 00 00 0A C5 CD

从机地址

地址 说明
广播地址:0 主机向地址0发送命令报文,全部从机收到报文后执行,但不发送回应报文。
1-247
保留:248-255

功能码和寄存器

PLC地址和Modbus协议地址

PLC地址

PLC 的地址,是指控制器中的寄存器地址,这些控制器可以是 PLC,也可以是触摸屏,或是文本显示器。
PLC 地址一般采用 10 进制描述,共有 5 位,其中第一位代码,如 0、3,标明寄存器类型。第一位开头数字和寄存器类型的对应关系如常用公共功能码所示。
PLC 地址例如40001、30002 等。

Modbus协议地址

协议地址指,通信时使用的地址,例如 PLC 地址 40001 对应寻址地址 0x0000,40002对应寻址地址 0x0001,40016 对应 0x000F,通讯寻址地址一般使用 16 进制描述。
再如,PLC 地址 40003 对应协议地址 0002,PLC 地址 30003 也对应协议地址 0002,虽然访问这两个 PLC 地址 40003、30003,通信时使用相同的协议地址 0002,但是需要使用不同的命令访问(PLC 地址开头的 0、1、3、4,决定了访问它们需要不同的功能码,命令的第二字节即功能码),所以访问时不存在冲突。

地址的转换

PLC 地址和通讯协议地址十分相似,PLC 地址由开头的 0、1、3、4 指示是哪种类型的变量,后面加 4 位数字来表示偏移量。
不同的是,PLC 的起始地址(偏移量)是 0001 开始,而 Modbus 协议的偏移量是从 0000开始,另外,PLC 地址是十进制表示,而协议地址是十六进制表示。 :::info 一般来说,PLC 的起始地址 = Modbus 协议地址(先换成十进制)+ 1 :::

功能码总览

常用公共功能码
操作单位 寄存器种类 PLC地址
(10进制)
功能码
单个比特
(位操作)
线圈状态 - Coil Status> 数字量输出 - DO

例:继电器输出、LED

| 00001 - 09999> 可读可写

| 0x01 | 读单个或多个线圈 | | | | | 0x05 | 写单个线圈 | | | | | 0x0F | 写多个线圈 | | | 离散输入状态 - Input Status> 数字量输入 - DI

例:拨码开关 、接近开关

| 10001 - 19999> 只读

| 0x02 | 读单个或多个离散输入 | | 16比特
(字操作) | 输入寄存器 - Input Register> 模拟量输入 - AI

例:模拟量输入

| 30001 - 39999> 只读

| 0x04 | 读一个或多个输入寄存器 | | | 保持寄存器 - HoldingRegister> 模拟量输出 - AO

例:温度传感器

| 40001 - 49999> 可读可写

| 0x03 | 读一个或多个保持寄存器 | | | | | 0x06 | 写单个保持寄存器 | | | | | 0x10 | 写多个保持寄存器 |

有人(cloud.usr.cn)扩展功能码
功能码 功能 通信数据格式
0x45 从机主动上报多个线圈 格式与 0x0F 写多个线圈 相同
0x42 从机主动上报多个离散输入
0x46 从机主动上报多个保持寄存器 格式与 0x10 写多个保持寄存器 相同
0x44 从机主动上报多个输入寄存器

Modbus功能码分类

功能码(十进制) 功能码(十六进制) 分类
1 ~ 64 0x01 ~ 0x40 公共功能码
65 ~ 72 0x41 ~ 0x48 用户自定义功能码
73 ~ 119 0x49 ~ 0x77 非法功能
120 ~ 127 0x78 ~ 0x7F 保留。留作内部使用
128 ~ 255 0x80 ~ 0xFF 保留。用作异常应答

0x01 读单个或多个线圈

请求
- 读取0x0001到0x000A单元的开关状态
从机地址 功能码 寄存器起始地址 寄存器单元长度 CRC校验
id 01 00 00 00 0A CrcL CrcH
应答
- 1表示ON,0表示OFF
- 现场状态为全开(即全1) :1111 1111 0000 0011 -> FF 03
从机地址 功能码 字节数 数据 CRC校验
id 01 02 FF 03 CrcL CrcH

0x02 读单个或多个离散输入

  • 0x01 读单个或多个线圈 | 请求 |
    - 读取0x0001到0x000A单元的开关状态
    | | | | | | —- | —- | —- | —- | —- | —- | | | 从机地址 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | | | id | 02 | 00 00 | 00 0A | CrcL CrcH |
应答
- 1表示ON,0表示OFF
- 现场状态为全开(即全1) :1111 1111 0000 0011 -> FF 03
从机地址 功能码 字节数 数据 CRC校验
id 02 02 FF 03 CrcL CrcH

0x05 写单个线圈

请求
- 将0x00AD单元状态置为ON
- FF 00 表示ON,00 00 表示OFF
从机地址 功能码 寄存器起始地址 线圈状态 CRC校验
id 05 00 AC FF 00 CrcL CrcH
应答
- 应答跟请求相同
从机地址 功能码 寄存器起始地址 线圈状态 CRC校验
id 05 00 AC FF 00 CrcL CrcH

0x0F 写多个线圈

请求
- 1表示ON,0表示OFF
- 从0x0014开始写入10个状态值,数据内容为2个字节:十六进制CD 01(二进制 1100 1101 0000 0001,用不到的位补0)
从机地址 功能码 寄存器起始地址 寄存器单元长度 字节数 数据 CRC校验
id 0F 00 13 00 0A 02 CD 01 CrcL CrcH
应答
从机地址 功能码 寄存器起始地址 寄存器单元长度 CRC校验
id 0F 00 13 00 0A CrcL CrcH

0x04 读一个或多个输入寄存器

请求
- 读取寄存器108—110的值
从机地址 功能码 寄存器起始地址 寄存器单元长度 CRC校验
id 04 00 6B 00 03 CrcL CrcH
应答
- 108的内容为0x022B(即555),109的内容为0x0000(即0),110的内容为0x0064(即100)
从机地址 功能码 字节数 数据 CRC校验
id 04 06 02 2B 00 00 00 64 CrcL CrcH

0x03 读一个或多个保持寄存器

  • 0x04 读一个或多个输入寄存器 | 请求 |
    - 读取寄存器108—110的值
    | | | | | | —- | —- | —- | —- | —- | —- | | | 从机地址 | 功能码 | 寄存器起始地址 | 寄存器单元长度 | CRC校验 | | | id | 03 | 00 6B | 00 03 | CrcL CrcH |
应答
- 108的内容为0x022B(即555),109的内容为0x0000(即0),110的内容为0x0064(即100)
从机地址 功能码 字节数 数据 CRC校验
id 03 06 02 2B 00 00 00 64 CrcL CrcH

0x06 写单个保持寄存器

请求
- 将数据0x0003写入寄存器单元0x0002
从机地址 功能码 寄存器起始地址 数据 CRC校验
id 06 00 01 00 03 CrcL CrcH
应答
- 应答跟请求相同
从机地址 功能码 寄存器起始地址 数据 CRC校验
id 06 00 01 00 03 CrcL CrcH

0x10 写多个保持寄存器

请求
- 将数据0x000A和0x0102写入从0x0002开始的两个寄存器单元
从机地址 功能码 寄存器起始地址 寄存器单元长度 字节数 数据 CRC校验
id 10 00 01 00 02 04 00 0A 01 02 CrcL CrcH
应答
从机地址 功能码 寄存器起始地址 寄存器单元长度 CRC校验
id 10 00 01 00 02 CrcL CrcH

附 学习资料

  • 闫越老师的总结

modbus协议181024.pptx

  • 有人扩展指令(本扩展指令非Modbus RTU标准,仅适用于设备与透传云/有人云网络通讯的规则)

有人扩展指令ModbusRTU V1.1.0.xlsx
有人扩展指令ModbusRTU V1.1.0.xlsx

附 调试工具

  • ModeBusRTU调试工具

ModeBusRTU调试工具CRC16版.zip