modbus常见功能码

01  读1路或多路开关量线圈输出状态

例如 主机--->从机

主机要读取地址为01 开关量为D01 D02的输出状态

地址0000   DO寄存器数据02 {DO1寄存器输出状态为0,DO2寄存器输出状态为1}

01 01 00 00 00 02 BD CD

从机--->主机

01 01 01 02 D0 49

(第三个01为一个字节 8个bit位)02代表输出状态1 开

02:读1路或多路开关量状态输入

例如 主机--->从机

01 02 00 00 00 04 79 C9

00 00 为起始地址的bit位为0000  

00 04为 读取四路开关量输入状态位

从机--->主机

01 02 01 0B E0 4F

02读取开关量状态 

01 一个字节 8个bit位

0B DI寄存器内容

功能码03:读多路保持寄存器(寄存器可读可写,修改寄存器数据使用06或10功能码)

寄存器地址0002    数据 1234 十进制 4660

寄存器地址0003    数据 1111十进制 4369

寄存器地址0004    数据 2222十进制 8738

主机----PLC

01 03 00 02 00 03 A4 0B    起始地址0002   3代表0002开始 连续3个数据

PLC--主机

01 03 06 12 34 11 11 22 22 5E 43

功能码04:读多路输入寄存器(寄存器只能读取不能写入)

功能码05:写1路开关量输出

主机----PLC

FF00 为控制继电器合

0000为控制继电器分

01 05 00 00 FF 00 8C 3A

地址为0000   FF00为合闸

PLC--主机

返回报文格式与主机一致

例二:开关量输出点DO2,其当前状态为“合”,主机要控制该路继电器“分”。

01 05 00 01 0000 9C0A

0001为地址   0000为分闸

从机(PDM)响应返回的报文格式:
与主机发送的报文格式及数据内容完全相同。

功能码06:写单路寄存器

01 06 00 0B 1E 34 F0 7F

000B为寄存器地址   1E 34为要写入的数据

功能码10:写多路寄存器

01 10 00 2A 00 03 06 2D7A 3D7D 4A9B 52FC

00 2A 寄存器地址

00 03 写入数据的字长度(共3个字)

06 写入数据的字节长度(共6个字节)

2D7A 3D7D 4A9B  3个数据 

52FC校验码 

一个寄存器里就代表1个字的数据,3个寄存器当然是3个字,共6个字节了,一个字=两个字节

### Modbus 协议常见功能码解释 #### 01 (读线圈状态) 此功能用于读取离散输入的状态,即读取一组逻辑开关或触点的位置。请求消息指定了要读取的起始地址以及所需的数据点数量。响应则返回这些数据点的实际状态[^1]。 ```python # Python伪代码示例:发送Modbus RTU帧以读取线圈状态 def read_coils(slave_id, start_address, quantity_of_x): request_frame = f"{slave_id} 01 {start_address:04X} {quantity_of_x:04X}" response = send_modbus_request(request_frame) return parse_response(response) ``` #### 02 (读离散输入状态) 类似于功能码`01`,但是针对的是只读类型的离散输入寄存器而不是可以被外部控制改变其状态的线圈。这通常用来获取传感器或其他二进制输入设备的信息。 #### 03 (读保持寄存器) 该功能允许客户端应用程序从服务器端读取一系列连续保存下来的16位整数型变量值。这类寄存器既可以存储过程变量也可以作为配置参数使用,并且能够通过其他指令修改它们的内容[^2]。 ```python # Python伪代码示例:发送Modbus RTU帧以读取多个保持寄存器 def read_holding_registers(slave_id, start_address, number_of_regs): request_frame = f"{slave_id} 03 {start_address:04X} {number_of_regs:04X}" response = send_modbus_request(request_frame) data_bytes = int.from_bytes(parse_response(response)[3:5], byteorder='big') values = [] for i in range(data_bytes // 2): value = int.from_bytes( parse_response(response)[5+i*2 : 7+i*2], byteorder='big' ) values.append(value) return values ``` #### 04 (读输入寄存器) 与`03`相似之处在于都是为了访问16位整数值;不同点是它专门处理那些仅限于读操作而不支持写的寄存器位置。因此非常适合监控现场仪表所采集到的各种模拟信号转换后的数字化结果[^3]。 ```python # Python伪代码示例:发送Modbus RTU帧以读取多个输入寄存器 def read_input_registers(slave_id, start_address, number_of_regs): request_frame = f"{slave_id} 04 {start_address:04X} {number_of_regs:04X}" response = send_modbus_request(request_frame) data_bytes = int.from_bytes(parse_response(response)[3:5], byteorder='big') values = [] for i in range(data_bytes // 2): value = int.from_bytes( parse_response(response)[5+i*2 : 7+i*2], byteorder='big' ) values.append(value) return values ``` #### 05 和 06 (强制单个线圈 / 预置单个寄存器) 这两个命令分别提供了对单一布尔量(如继电器)的操作权限——前者负责设定指定地址处的目标为ON/OFF两种可能之一;后者则是向特定编号下的保持寄存器赋给定数值。 #### 10 (预置多个寄存器) 这个功能使得一次通信就能更新一批相邻排列着的保持寄存器里的内容。这对于批量上传新设置或是同步大量测量值得到了极大简化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值