基于QT开发支持MODBUS协议的上位机:二、MODBUS协议的功能码


一、MODBUS协议的基本表格

MODBUS 以一系列具有不同特征表格上的数据模型为基础。四个基本表格为:

基本表格对象类型访问类型内容
输入离散量单个bit只读I/O 系统提供这种类型数据
线圈单个bit读写通过应用程序改变这种类型数据
输入寄存器单个寄存器只读I/O 系统提供这种类型数据
保持寄存器单个寄存器读写通过应用程序改变这种类型数据

对于基本表格中任何一项,协议都允许单个地选择 65536 个数据项,而且设计那些项的读写操作可以越过多个连续数据项直到数据大小规格限制,这个数据大小规格限制与事务处理功能码有关。MODBUS 功能码中使用的 MODBUS 逻辑参考数字是以 0 开始的无符号整数索引。

每个设备根据其应用都有它自己的数据结构,也即以上四种基本表格在具体设备中的存储位置由设备自身构造决定。

二、MODBUS 事务处理流程

MODBUS事务处理流程
依据上图,从机在处理完主机请求后,可能会建立两种响应:

  1. 正常的MODBUS 响应
    响应的功能码 = 请求的功能码
  2. 异常的MODBUS 响应
    向主机提供一个异常码来指示差错原因
    响应功能码 = 请求功能码 + 0x80

MODBUS 异常码:01 非法功能;02 非法数据地址;03 非法数据值;04 从站设备故障;其他异常码 略…。

三、功能码

1、功能码分类
有三类 MODBUS 功能码:公共功能码、用户定义功能码、保留功能码
MODBUS功能码范围
MODBUS功能码的有效范围是十进制 1-255(128-255 为异常响应保留)。

2、常用公共功能码定义

功能码定义功能
0X01读线圈
0X02读输入离散量
0X03读保持寄存器
0X04读输入寄存器
0X05写单个线圈
0X06写单个寄存器
0X0F写多个线圈
0X10写多个寄存器
0X14读文件记录
0X15写文件记录
0X16屏蔽写寄存器
0x17读/写多个寄存器

3、部分公共功能码的请求/响应数据格式
MODBUS 协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。特定总线或网络上的 MODBUS 协议映射能够在应用数据单元(ADU)上引入一些附加域。
MODBS数据格式
1)0X01(读线圈)
请求PDU

功能码1个字节0X01
起始地址2个字节0 - 65535
线圈数量2个字节1-2000(0X7D0)

响应PDU

功能码1个字节0X01
字节数1个字节N*
线圈状态N个字节

错误

功能码1个字节0X81(功能码+0X80)
异常码1个字节01、02、03或04

举例:读取线圈20-38

请求响应
功能码0X01功能码0x01
起始地址Hi00字节数0X03
起始地址Lo0x13输出状态27-20**
线圈数量Hi00输出状态35-28**
线圈数量Lo0x13输出状态38-36**

输出38 是左侧第六个比特位置,输出 36 是这个字节的 LSB。用零填充五个剩余高位比特。

2)0X02(读输入离散量)

3)0X03 (读保持寄存器)
请求PDU

功能码1个字节0X03
起始地址2个字节0 至 65535
寄存器数量2个字节1-125(0X7D)

响应PDU

功能码1个字节0X03
字节数1个字节2xN*
寄存器值2xN*个字节

错误

功能码1个字节0X83(功能码+0X80)
异常码1个字节01、02、03或04

举例:读寄存器108-110

请求响应
功能码0X03功能码0x03
起始地址Hi00字节数0X06
起始地址Lo0x6B寄存器Hi(108 )**
寄存器数量Hi00寄存器Lo(108 )**
寄存器数量Lo0x03寄存器Hi(109 )**
寄存器Lo(109 )**
寄存器Hi(110 )**
寄存器Lo(110 )**

4)0X04(读输入寄存器)

5)0X05(写单个线圈)
请求PDU

功能码1个字节0X05
写入地址2个字节0 - 65535
写入值2个字节0X0000(OFF) 或 0XFF00(ON)

响应PDU

功能码1个字节0X01
写入地址1个字节0 - 65535
写入值2个字节0X0000(OFF) 或 0XFF00(ON)

错误

功能码1个字节0X85(功能码+0X80)
异常码1个字节01、02、03或04

举例:写线圈173为ON

请求响应
功能码0X05功能码0x05
写入地址Hi00写入地址Hi00
写入地址Lo0xAC写入地址Lo0xAC
写入值Hi0XFF写入值Hi0XFF
写入值Lo0x00写入值Lo0x00

6)0X06(写单个寄存器)
请求PDU

功能码1个字节0X06
写入地址2个字节0 - 65535
写入值2个字节0X0000 - 0XFFFF

响应PDU

功能码1个字节0X01
写入地址1个字节0 - 65535
写入值2个字节0X0000 - 0XFFFF

错误

功能码1个字节0X86(功能码+0X80)
异常码1个字节01、02、03或04

举例:向寄存器13写入01 02

请求响应
功能码0X06功能码0x06
写入地址Hi00写入地址Hi00
写入地址Lo0x0D写入地址Lo0x0D
写入值Hi0X01写入值Hi0X01
写入值Lo0x02写入值Lo0x02

7)0X0f(写多个线圈)
请求PDU

功能码1个字节0X0f
起始地址2个字节0 - 65535
线圈数量2个字节1- 1968(0X7B0)
字节数1个字节N*
写入值N*个字节

备注:N*=线圈数量/8,如果余数不等于 0,那么 N = N+1

响应PDU

功能码1个字节0X01
起始地址2个字节0 - 65535
线圈数量2个字节1- 1968(0X7B0)

错误

功能码1个字节0X8F(功能码+0X80)
异常码1个字节01、02、03或04

举例:从线圈20开始写入10个线圈值为 CD 01 (二进制 1100 1101 0000 0001)

请求响应
功能码0X0F功能码0x0F
起始地址Hi00起始地址Hi00
起始地址Lo0x13起始地址Lo0x13
线圈数量Hi0X00线圈数量Hi0X00
线圈数量Lo0x0A线圈数量Lo0x0A
字节数0X02
写入值Hi0XCD
写入值Lo0X01

8)0X10 (写多个寄存器)
请求PDU

功能码1个字节0X0f
起始地址2个字节0 - 65535
线圈数量2个字节1- 123(0X7B)
字节数1个字节2xN*
写入值2xN*个字节

备注:N*=寄存器数量

响应PDU

功能码1个字节0X10
起始地址2个字节0 - 65535
线圈数量2个字节1- 123(0X7B)

错误

功能码1个字节0X90(功能码+0X80)
异常码1个字节01、02、03或04

举例:将01 02 和 03 04 写入02,03寄存器

请求响应
功能码0X10功能码0x10
起始地址Hi00起始地址Hi00
起始地址Lo0x02起始地址Lo0x02
寄存器数量Hi0X00寄存器数量Hi0X00
寄存器数量Lo0x02寄存器数量Lo0x02
字节数0X04
写入值Hi0X01
写入值Lo0X02
写入值Hi0X03
写入值Lo0X04

声明

以上内容仅供个人学习使用,如果侵权请联系删除。另外,如有出错,欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值