libmodbus学习(三)之Modbus协议转换

在这里插入代码片# 一、RTU Slaver–TCP Master

1.测试平台搭建

Modbus RTU转 Modbus TCP测试平台搭建如下,网关起协议转换作用。首先,master(主站)通过modbus tcp协议发送读取数据请求,网关接收后解析Modbus TCP请求后,将Modbus TCP协议转成Modbus RTU向slaver(从站)设备发送Modbus RTU请求。其次,slaver(从站)设备收到请求后进行Modbus RTU响应,网关接收到Modbus RTU响应后将其转换成Modbus TCP响应发给Modbus TCP。
image.png
MThings模拟从站设备,通过RS485串口通信与网关(开发板)进行通信
###1.1Modbus RTU 的建立
在Modbus RTU通信中, PC机创建slaver,网关为master
image.png
slave上创建的寄存器种类、数量及地址如下,网关作为master通过Modbus RTU协议读取或写入寄存器的数值。
image.png

1.2Modbus TCP 的建立

在Modbus TCP通信中, PC机创建master,网关为slaver
image.png
master上可以进行读取和写入指定寄存器的操作,slave通过Modbus TCP协议响应这些操作。
image.png

1.3协议转换

网关将Modbus TCP-master的Modbus TCP请求数据转换成Modbus RTU请求数据给Modbus RTU-slaver
image.png

网关将Modbus RTU-slaver的Modbus RTU响应数据转换成Modbus TCP响应数据给Modbus TCP-master
image.png

1.4测试结果

image.png

image.png

image.png

[2020-12-08 18:55:32-128]NET000-发送:[00 03 00 00 00 06] 01 01 00 64 00 01

TCP Master发送线圈状态读取报文中括号中[00 03 00 00 00 06]是modbus-tcp的表头信息,其中
00 03代表包序号为3,
00 00代表协议是tcp,
00 06代表后面还有6byte有效数据。
后续数据为modbus协议的PDU(数据单元),其中
01为 Modbus-tcp协议的目标slaver ID(从站ID,实际设备是网关),
01为功能码,表示读取线圈状态,
00 64为线圈的地址100
00 01为数量1
PDU的含义:读取slaver ID为1的设备,地址为100的1个线圈状态。

网关收到请求后,将PUD截取,加上CRC校验转换成Modbus-RTU协议发起请求

Modbus-RTU-slaver接收到的请求如下

[2020-12-08 18:55:32-148]COM34-接收:01 01 00 64 00 01 bc 15

PDU不变,最后多了bc 15的CRC校验码。

Modbus-RTU-slaver响应如下

[2020-12-08 18:55:32-158]COM34-发送:01 01 01 01 90 48

01为 Modbus-RTU协议的目标slaver ID(从站ID,实际设备是PC模拟的设备)
01代表功能码,表示读取线圈状态,
01代表后面还有1byte有效数据
01代表读取数值
90 48是CRC校验
响应信息的含义:读取的线圈状态为1。

Modbus-RTU-master(实际设备为网关)接收到Modbus-RTU-slaver的响应后,截取PDU,加上Modbus-TCP表头,响应Modbus-TCP-master的请求,响应消息含义:读取的线圈状态为1。

[2020-12-08 18:55:32-208]NET000-接收:[00 03 00 00 00 04] 01 01 01 01

1.5测试程序

RTU Slaver–TCP Master

#include <stdio.h>
#include <unistd.h>  
#include <stdlib.h>
#include <errno.h>
#include <memory.h>
#include <modbus/modbus.h>
#include "unit-test.h"int main(void)
{int socket;int rc;int i;modbus_t *tcp_ctx;modbus_t *rtu_ctx;modbus_mapping_t *mb_mapping;int header_length;uint8_t *query;uint16_t* regs_value = (uint16_t*)malloc(256*sizeof(uint16_t));int addr,nb,coil_statu;int coils,input_coils,regs,input_regs;uint16_t reg_value;/* 创建tcp server 对象、rtu master 对象*/tcp_ctx = modbus_new_tcp("192.168.1.184", 502);         //开发板iprtu_ctx = modbus_new_rtu("/dev/ttymxc2",9600,'N',8,1);  //开发板串口/* 分配报文接收空间 */query = (uint8_t *


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部