Modbus调试工具《五》Modbus功能码15,16,22,23,自定义命令

目录

前言

写多线圈

写多寄存器

掩码寄存器

读写寄存器

自定义报文

写文件


前言

Dick Morley在1979年发表的Modbus协议,最初只是为了让自动化系统使用可编程逻辑控制器PLC设备而制定了这样的一个总线协议。由于其无版权而免费,简洁易用和易于维护等优点得到了广泛应用。随着智能设备的普及应用,Modbus协议在工业自动化、智能建筑和能源管理等诸多领域得到了广泛的应用。

这篇文章会从简单的采集Modbus线圈任务开始,通过介绍一个简单采集任务来快速熟悉该modbus调试软件的基本使用方法:

  • 连接设置
  • 开始和停止调试
  • 制定采集任务
  • 写单个线圈
  • 写单寄存器

软件的下载地址如下:

百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固,支持教育网加速,支持手机端。注册使用百度网盘即可享受免费存储空间icon-default.png?t=O83Ahttps://pan.baidu.com/s/1ics9LmKUhYVOcta23zNhVg?pwd=r28tModbusDebuger模拟器无需安装,解压就可以使用。下载链接目录中含有个人版和专业版两个目录,目前这两个软件都免费。

写多线圈

点击功能菜单下的写多线圈可以写单个线圈对话框,这里可以设置设备的多个线圈值。

从站:从站的地址

地址:线圈的地址

数量:修改线圈的数量

更新列表按钮,修改了地址和数量后,需要点击更新列表按钮

执行结果:定制执行后的动作

PDU和RTU-ADUS:以RTU报文格式来显示要下发的报文

发送按钮:向从站设备发送修改线圈值报文

生成按钮:会根据状态值生成PDU,RTU-ADU报文

保存按钮:保存当前对话框的设置参数,保存后会出现在项目视图中

写多寄存器

点击功能菜单下的写多线圈可以写多个寄存器对话框,这里可以设置设备的多个寄存器值

从站:从站的地址

地址:线圈的地址

数量:修改线圈的数量

类型:相应寄存器的值类型

更新列表按钮,修改了地址、数量和类型后,需要点击更新列表按钮

执行结果:定制执行后的动作

PDU和RTU-ADUS:以RTU报文格式来显示要下发的报文

发送按钮:向从站设备发送修改线圈值报文

生成按钮:会根据状态值生成PDU,RTU-ADU报文

保存按钮:保存当前对话框的设置参数,保存后会出现在项目视图中

掩码寄存器

点击功能菜单下的掩码寄存器,这里可以设置设备的一个寄存器的掩码值

从站:从站的地址

地址:寄存器的地址

AND:and值

OR:or值

执行结果:定制执行后的动作

PDU和RTU-ADUS:以RTU报文格式来显示要下发的报文

发送按钮:向从站设备发送修改线圈值报文

保存按钮:保存当前对话框的设置参数,保存后会出现在项目视图中

读写寄存器

点击功能菜单下的读写寄存器可以打开读写寄存器对话框,这里可以修改和读取多个寄存器值

从站:从站的地址

写入地址:寄存器的地址

写入数量:修改寄存器数量

类型:相应寄存器的值类型

更新列表按钮,修改了地址、数量和类型后,需要点击更新列表按钮

读地址:读寄存器的地址

读数量:读寄存器数量

执行结果:定制执行后的动作

PDU和RTU-ADUS:以RTU报文格式来显示要下发的报文

发送按钮:向从站设备发送修改线圈值报文

生成按钮:会根据状态值生成PDU,RTU-ADU报文

保存按钮:保存当前对话框的设置参数,保存后会出现在项目视图中

自定义报文

点击功能菜单下的自定义报文可以打开自定义报文对话框,这里可以发送和接收自定义报文

从站:从站的地址

地址:寄存器的地址

报文内容:输入自定义的报文

回复PDU:slave端回复报文的PDU内容

发送按钮:向从站设备发送修改线圈值报文

保存按钮:保存当前对话框的设置参数,保存后会出现在项目视图中

写文件

点击功能菜单下的写文件可以打开写文件对话框,这里可以给设备发送文件

从站:从站的地址

功能码:自定义的功能码

单包大小:给设备发送文件的单个报文大小

发送文件:选择要发送的文件

执行结果:定制执行后的动作

发送按钮:向从站设备发送修改线圈值报文

保存按钮:保存当前对话框的设置参数,保存后会出现在项目视图中

### 如何在 Modbus RTU 协议中实现自定义功能码 #### 定义自定义功能码的需求分析 为了满足特定应用场景下的需求,有时标准的功能码无法覆盖所有的操作。因此,在某些情况下需要引入自定义功能码来扩展Modbus协议的能力[^2]。 #### 自定义功能码的选择原则 根据Modbus官方规定,用户可以使用的私有功能码区间为`0x80~0xFF`。这意味着任何超出此范围之外的功能码都属于保留或已分配给其他用途的标准命令集的一部分。对于开发者而言,应该谨慎选择未被占用的编号作为新的指令标识符,并确保在整个系统内部保持唯一性以防止冲突发生[^1]。 #### 数据帧结构设计 当决定好要采用的具体数值之后,则需考虑数据包格式的设计问题。通常来说,一个完整的请求消息由以下几个部分组成: - **地址域 (Address Field)**: 表明目标设备的身份; - **功能码字段(Function Code Field)** : 此处即为我们所设定的新编码; - **寄存器起始位置(Register Address Start Position)** 和 **数量(Number of Registers to Read or Write)** :用于指示具体的操作对象及其规模大小; - **校验位(CRC Checksum)**:保证传输过程中的准确性; 例如,如果想要创建一条读取特殊存储区内容的消息,那么其大致形式如下所示: | 地址 | 功能码 | 寄存器起始位置 | 数量 | CRC | | --- | ------ | --------------- | ---- | ---| | 01H | C0H | 000AH | 05H | ...| 这里假设选择了十六进制C0代表新加入的功能——获取指定区域内的历史记录摘要信息。 #### 编写处理逻辑 接下来就是针对上述定义编写相应的解析函数了。这一步骤涉及到对输入参数的有效性验证、实际业务流程执行以及最终响应报文构建等多个方面的工作。下面给出了一段伪代码样例供参考: ```c++ // 假设已经接收到客户端发来的完整查询语句并保存于buffer数组内 if(buffer[1]==0xC0){ // 判断是否匹配到预设好的自定义功能号 uint16_t startAddr = ((uint16_t) buffer[2]<<8)|buffer[3]; uint16_t quantity= ((uint16_t) buffer[4]<<8)|buffer[5]; if(startAddr>=MIN_ADDR && startAddr<=MAX_ADDR&&quantity>0){ // 执行具体的读取动作... // 构造返回的数据体 responseBuffer[0]=slaveID; responseBuffer[1]=0xC0; ... calculateCRC(responseBuffer); // 添加crc检验值 }else{ constructExceptionResponse(slaveID,ILLEGAL_DATA_ADDRESS); } } ``` 通过这种方式就可以成功地向现有的RTU通信机制里融入个性化的交互方式了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值