在这里插入代码片# 一、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。
MThings模拟从站设备,通过RS485串口通信与网关(开发板)进行通信
###1.1Modbus RTU 的建立
在Modbus RTU通信中, PC机创建slaver,网关为master
slave上创建的寄存器种类、数量及地址如下,网关作为master通过Modbus RTU协议读取或写入寄存器的数值。
1.2Modbus TCP 的建立
在Modbus TCP通信中, PC机创建master,网关为slaver
master上可以进行读取和写入指定寄存器的操作,slave通过Modbus TCP协议响应这些操作。
1.3协议转换
网关将Modbus TCP-master的Modbus TCP请求数据转换成Modbus RTU请求数据给Modbus RTU-slaver
网关将Modbus RTU-slaver的Modbus RTU响应数据转换成Modbus TCP响应数据给Modbus TCP-master
1.4测试结果
[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); //开发板ip
rtu_ctx = modbus_new_rtu("/dev/ttymxc2",9600,'N',8,1); //开发板串口
/* 分配报文接收空间 */
query = (uint8_t *