ModBusTcp协议
简介
- Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP。
- Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。
- 标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口,采用master/slave方式通信。
- Modbus的工作方式是请求/应答,每次通讯都是主站先发送指令,可以是广播,或是向特定从站的单播;从站响应指令,并按要求应答,或者报告异常。当主站不发送请求时,从站不会自己发出数据,从站和从站之间不能直接通讯。
- Modbus协议是应用层(协议层)报文传输协议,它定义了一个与物理层无关的协议数据单元(PDU),即PDU=功能码+数据域,功能码1byte,数据域不确定。
- Modbus协议能够应用在不同类型的总线或网络。对应不同的总线或网络,Modbus协议引入一些附加域映射成应用数据单元(ADU),即ADU=附加域+PDU,例如modbus tcp/ip------ ADU=MBAP+ADU。
通讯方式
- 以太网:对应的通信模式是Modbus TCP/IP
- 异步串行传输(各种介质如有线RS-232-/422/485/;光纤、无线等):对应的通信模式是Modbus RTU或Modbus ASCII
- 高速令牌传递网络:对应的通信模式是Modbus PLUS
modbus tcp/ip通信方式
- Modbus设备可分为主站(poll)和从站(slave)。主站只有一个,从站有多个,主站向各从站发送请求帧,从站给予响应。在使用TCP通信时,主站为client端,主动建立连接;从站为server端,等待连接。
- 主站请求:功能码+数据
- 从站正常响应:请求功能码+响应数据
- 从站异常响应:异常功能码+异常码,其中异常功能码即将请求功能码的最高有效位置1,异常码指示差错类型
- 注意:需要超时管理机制,避免无期限的等待可能不出现的应答
- IANA(Internet Assigned Numbers Authority,互联网编号分配管理机构)给Modbus协议赋予TCP端口号为502,这是目前在仪表与自动化行业中唯一分配到的端口号。
通信过程
- connect 建立TCP连接
- 准备Modbus报文
- 使用send命令发送报文
- 在同一连接下等待应答
- 使用recv命令读取报文,完成一次数据交换
- 通信任务结束时,关闭TCP连接
报文格式
- Modbus协议的报文(或帧)的基本格式是:表头 + 功能码 + 数据区 + 校验码
- 对于Modbus TCP而言,主站通常称为Client,从站称为Server;而对于Modbus RTU和Modbus ASCII来说,主站是Master,从站是Slave。
- ModbusTCP的数据帧可分为两部分:ADU=MBAP+PDU = MBAP + 功能码 + 数据域,MBAP 7byte,功能码1byte,数据域不确定,由具体功能决定。
报文头MBAP
- MBAP为报文头,长度为7字节,组成如下:
事务处理标识 | 协议标识 | 长度 | 单元标识符 |
2字节 | 2字节 | 2字节 | 1字节 |
内容 | 解释 |
事务处理标识 | 报文的序列号,每次通信之后就要加1以区别不同的通信数据报文 |
协议标识符 | 00 00表示ModbusTCP协议 |
长度 | 数据长度,单位为字节 |
单元标识符 | 可以理解为设备地址 |
帧结构PDU
- PDU由功能码+数据组成。功能码为1字节,数据长度不定,由具体功能决定。
功能码
- Modbus的操作对象有四种:线圈、离散输入、保持寄存器、输入寄存器。
对象 | 含义 |
线圈 | PLC的输出位,开关量,在Modbus中可读可写 |
离散量 | PLC的输入位,开关量,在Modbus中只读 |
输入寄存器 | PLC中只能从模拟量输入端改变的寄存器,在Modbus中只读 |
保持寄存器 | PLC中用于输出模拟量信号的寄存器,在Modbus中可读可写 |
代码 | 中文名称 | 英文名 | 位操作/字操作 | 操作数量 |
01 | 读线圈状态 | READ COIL STATUS | 位操作 | 单个或多个 |
02 | 读离散输入状态 | READ INPUT STATUS | 位操作 | 单个或多个 |
03 | 读保持寄存器 | READ HOLDING REGISTER | 字操作 | 单个或多个 |
04 | 读输入寄存器 | READ INPUT REGISTER | 字操作 | 单个或多个 |
05 | 写线圈状态 | WRITE SINGLE COIL | 位操作 | 单个 |
06 | 写单个保持寄存器 | WRITE SINGLE REGISTER | 字操作 | 单个 |
15 | 写多个线圈 | WRITE MULTIPLE COIL | 位操作 | 多个 |
16 | 写多个保持寄存器 | WRITE MULTIPLE REGISTER | 字操作 | 多个 |