目录
4、分别创建测试ModbusTCP测试的Server和Client程序
PLC地址
安装库文件
PLC硬件环境设置、库文件安装、防火墙设置等,参见博客文章:TwinCAT3中ModbusTCP Server和C# Client连接-CSDN博客
将创建的程序添加到Task中。
测试电脑IP地址和PLC的IP地址在一个网段内。
使用测试工具ModSim32,创建ModbusTCP Server服务端。端口号默认502,测试软件默认IP地址是计算机本地地址。
定义变量:ModbusTCP Server服务端ip地址
Server_IpAddress :STRING:='192.168.1.33'; //ModbusTCP Server服务端ip地址
定义变量
02: Input Status 读取//
fbReadInputs : FB_MBReadInputs; (*读取离散量输入功能块*)
bReadInputs : BOOL; (*读取离散量输入执行条件*)
nQuantityinput : WORD:=1 ; (*读取离散量输入个数*)
nMBAddrinput : WORD:=1 ; (*读取离散量输入起始地址*)
arrDatainput : BYTE; (*存放离散量输入的值*)
程序
nUnitID:Modbus-Tcp从站号。如果实际中不知道从站号多少,默认写1就行。
fbReadInputs(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:=1 , //Modbus-Tcp从站号
nQuantity:=nQuantityinput , //读取离散量输入个数
nMBAddr:= nMBAddrinput, //读取离散量输入 Modbus起始地址
cbLength:= SIZEOF(arrDatainput), //存放离散量输入变量的个数
pDestAddr:=ADR(arrDatainput), //存放离散量输入变量指针起始地址
bExecute:=bReadInputs , //读取离散量输入执行条件
tTimeout:=T#1S ,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
运行测试1,单个离散量读操作:
对10002写1
PLC读取
读取个数是1,nQuantityinput值为1
起始地址nMBAddrinput写1对应的寄存器是10002。离散变量实际地址=10001+nMBAddrinput
读取
运行测试2,多个离散量读操作:
对10002写1、10003写1、10004写1
PLC读取
设置读取个数是3。读取出来的值是7。(三个位都为1,就是7)
定义变量
fbReadCoils : FB_MBReadCoils; (*读取线圈功能块*)
bReadCoils : BOOL; (*读取线圈执行条件*)
nQuantitycoils : WORD :=3; (*读取线圈个数*)
nMBAddrcoils : WORD :=1; (*读取线圈起始地址*)
arrDatacoils : BYTE; (*存放线圈的值*)
PLC程序
fbReadCoils(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502 , //Modbus-Tcp端口号
nUnitID:=1 , //Modbus-Tcp从站号
nQuantity:=nQuantitycoils , //读取线圈个数
nMBAddr:=nMBAddrcoils , //读取线圈 Modbus起始地址
cbLength:=SIZEOF(arrDatacoils) , //存放线圈变量的个数
pDestAddr:=ADR(arrDatacoils) , //存放线圈变量指针起始地址
bExecute:=bReadCoils , //读取线圈执行条件
tTimeout:= T#1S,
bBusy=> ,
bError=>,
nErrId=> ,
cbRead=> );
运行测试,多个线圈读操作:
对线圈00005/00006/0007/0008/00009写1操作
PLC
nMBAddrcoils:读取线圈的地址
nQuantitycoils:读取的线圈个数
线圈的实际地址=00001+nMBAddrcoils。
00005对应的nMBAddrcoils地址设置就是4。
5个线圈的值都是ON,即31
PLC中数据显示,2进制、10进制、16进制显示设置
定义变量
fbWriteSingleCoil : FB_MBWriteSingleCoil; (*写入单个线圈功能块*)
bWriteSingleCoil : BOOL; (*写入单个线圈执行条件*)
nMBAddrWriteSingleCoil : WORD := 3; (*写入单个线圈Modbus 地址*)
nValueWriteSingleCoil : WORD := 16#FF00; (*16#FF00:True;16#0000:False*)
PLC程序
fbWriteSingleCoil(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:= 502, //Modbus-Tcp端口号
nUnitID:= 1, //Modbus-Tcp从站号
nMBAddr:=nMBAddrWriteSingleCoil , //写入单个线圈Modbus起始地址
nValue:=nValueWriteSingleCoil , //写入单个线圈的值:16#FF00:True;16#0000:False
bExecute:=bWriteSingleCoil , //写入单个线圈执行条件
tTimeout:=T#1S ,
bBusy=> ,
bError=> ,
nErrId=> );
运行测试,单个线圈写操作:
对线圈00004写操作
线圈地址nMBAddrWriteSingleCoil值设置:3。(线圈地址=00001+nMBAddrWriteSingleCoil)
nValueWriteSingleCoil值设置:
TRUE:16#FF00,即10进制65280。
FALSE:16#0000,即10进制0。
变量定义
fbWriteCoils : FB_MBWriteCoils; (*写入线圈功能块*)
bWriteCoils : BOOL; (*写入线圈执行条件*)
nQuantityWriteCoils : WORD := 10; (*写入离散量输入个数*)
nMBAddrWriteCoils : WORD := 14; (*写入离散量输入起始地址*)
arrDataWriteCoils : ARRAY[1..2] OF BYTE := [16#11, 16#33];(*写入离散量输入的值*)
PLC程序
fbWriteCoils(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:=1 , //Modbus-Tcp从站号
nQuantity:= nQuantityWriteCoils , //写入线圈个数
nMBAddr:=nMBAddrWriteCoils , //写入线圈Modbus起始地址
cbLength:=SIZEOF(arrDataWriteCoils), //写入线圈的变量个数
pSrcAddr:=ADR(arrDataWriteCoils), //写入线圈的变量指针起始地址
bExecute:=bWriteCoils , //写入线圈的执行条件
tTimeout:=T#1S ,
bBusy=> ,
bError=> ,
nErrId=> );
运行测试,多个线圈写操作:
写16个线圈,线圈地址从00006开始。(00001+nMBAddrWriteCoils,nMBAddrWriteCoils设置值为5)。
1个BYTE是8位,8位都是1即BYTE值是255。
BYTE数组arrDataWriteCoils长度为2、即16位。最多可以写16个线圈操作。
(注意:写的线圈BYTE个数要和数组长度相同,16个线圈2个BYTE。对应否则会报错。)
变量定义
fbReadInputRegs : FB_MBReadInputRegs; (*读取输入寄存器功能块*)
bReadInputRegs : BOOL; (*读取输入寄存器执行条件*)
nQuantityInputRegs : WORD := 3; (*读取输入寄存器个数*)
nMBAddrInputRegs : WORD:= 2; (*读取输入寄存器起始地址*)
arrDataInputRegs : ARRAY [1..3] OF WORD; (*存放输入寄存器的值*)
PLC程序
fbReadInputRegs(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:=1, //Modbus-Tcp从站号
nQuantity:=nQuantityInputRegs, //读取输入寄存器个数
nMBAddr:=nMBAddrInputRegs , //读取输入寄存器Modbus起始地址
cbLength:= SIZEOF(arrDataInputRegs), //存放输入寄存器变量的个数和指针起始地址
pDestAddr:=ADR(arrDataInputRegs), //存放输入寄存器变量指针起始地址
bExecute:= bReadInputRegs , //读取输入寄存器执行条件
tTimeout:=T#1S ,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
运行测试,多个输入寄存器读操作:
给30003、30004、30005赋值
PLC读
寄存器地址30003=30001+nMBAddrInputRegs,nMBAddrInputRegs设置值2
多三个寄存器
(注意:读的寄存器个数要和数组长度相同,否则会报错。)
变量定义:
fbReadRegs : FB_MBReadRegs; (*读取保持寄存器功能块*)
bReadRegs : BOOL; (*读取保持寄存器执行条件*)
nQuantityregs : WORD:=2; (*读取保持寄存器个数*)
nMBAddrregs : WORD:=24; (*读取保持寄存器起始地址*)
arrDataregs : ARRAY [1..2] OF WORD; (*存放保持寄存器的值*)
PLC程序:
fbReadRegs(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:= 1, //Modbus-Tcp从站号
nQuantity:=nQuantityregs, //读取保持寄存器个数
nMBAddr:=nMBAddrregs , //读取保持寄存器Modbus起始地址
cbLength:=SIZEOF(arrDataregs) , //存放保持寄存器变量的个数
pDestAddr:=ADR(arrDataregs) , //存放保持寄存器变量指针起始地址
bExecute:=bReadRegs, //读取保持寄存器执行条件
tTimeout:= T#1S ,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
运行测试,多个保持寄存器读操作:
读保持寄存器40005、40006
寄存器首地址40005=40001+nMBAddrregs,设置nMBAddrregs值为4。读两个寄存器。
(注意:读的寄存器个数要和数组长度相同,否则会报错。)
变量定义:
fbWriteSingleReg : FB_MBWriteSingleReg; (*写入单个寄存器功能块*)
bWriteSingleReg : BOOL; (*写入单个寄存器执行条件*)
nMBAddrSingleReg : WORD := 4; (*写入单个寄存器Modbus 地址*)
nValueSingleReg : WORD := 16#1234; (*写入单个寄存器数值*)
PLC程序:
fbWriteSingleReg(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:=1 , //Modbus-Tcp从站号
nMBAddr:=nMBAddrSingleReg, //写入单个保持寄存器起始地址
nValue:=nValueSingleReg, //写入单个寄存器数值
bExecute:=bWriteSingleReg , //写入单个寄存器的执行条件
tTimeout:=T#1S ,
bBusy=> ,
bError=> ,
nErrId=> );
运行测试,单个保持寄存器写操作:
写保持寄存器40005。40005=40001+nMBAddrSingleReg,设置nMBAddrSingleReg值为4
变量定义:
fbWriteRegs : FB_MBWriteRegs; (*写入保持寄存器功能块*)
bWriteRegs : BOOL; (*写入保持寄存器个数*)
nQuantityWriteRegs : WORD := 4; (*写入保持寄存器个数*)
nMBAddrWriteRegs : WORD := 4; (*写入保持寄存器起始地址*)
arrDataWriteRegs : ARRAY[1..4] OF WORD := [1122, 3344, 5566, 7788];(*写入保持寄存器的值*)
PLC程序:
fbWriteRegs(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:=1 , //Modbus-Tcp从站号
nQuantity:=nQuantityWriteRegs , //写入保持寄存器个数
nMBAddr:= nMBAddrWriteRegs , //写入保持寄存器起始地址
cbLength:= SIZEOF(arrDataWriteRegs), //写入变量的个数和指针起始地址
pSrcAddr:=ADR(arrDataWriteRegs) , //写入变量指针起始地址
bExecute:= bWriteRegs , //写入保持寄存器的执行条件
tTimeout:=T#1S ,
bBusy=> ,
bError=> ,
nErrId=> );
运行测试,多个保持寄存器写操作:
写保持寄存器40003、40004、40005,寄存器首地址40003=40001+nMBAddrWriteRegs,设置nMBAddrWriteRegs值2
(注意:写寄存器个数要和数组长度相同,否则会报错。)
arr1 AT%MB0 :ARRAY[1..5] OF WORD; //起始地址是12289
arr2 AT%MB10 :ARRAY[1..10] OF WORD; //起始地址是12294
使用测试工具ModScan32模拟ModbusTCP Client客户端。
打开ModScan32
根据Server服务端PLC 中定义的寄存器,做如下设置
MB0对应的起始地址是12289。
寄存器说明:一个MW寄存器对应两个MB寄存器,比如MW0是MB0、MB1组成。一个12289对应一个MW0寄存器,即对应MB0、MB1。
客户端ModScan32对服务端PLC的寄存器写操作
PLC服务端接收的
(2)PLC服务端写操作
PLC寄存器写
客户端ModScan32接收的
PLC服务端程序不变,就定义读写的寄存器变量
变量定义
arr1 AT%MB0 :ARRAY[1..5] OF WORD; //起始地址是12289
arr2 AT%MB10 :ARRAY[1..10] OF WORD; //起始地址是12294
变量定义
Server_IpAddress :STRING:='192.168.1.21';
03: Holding Register 读取&写入
fbReadRegs : FB_MBReadRegs; (*读取保持寄存器功能块*)
bReadRegs : BOOL; (*读取保持寄存器执行条件*)
nQuantityregs : WORD:=5; (*读取保持寄存器个数*)
nMBAddrregs : WORD:=12288; (*读取保持寄存器起始地址*) // 寄存器地址=40001+nMBAddrregs
arrDataregs : ARRAY [1..5] OF WORD; (*存放保持寄存器的值*)
fbWriteRegs : FB_MBWriteRegs; (*写入保持寄存器功能块*)
bWriteRegs : BOOL; (*写入保持寄存器个数*)
nQuantityWriteRegs : WORD := 10; (*写入保持寄存器个数*)
nMBAddrWriteRegs : WORD := 12294; (*写入保持寄存器起始地址*) // 寄存器地址=40001+nMBAddrWriteRegs
arrDataWriteRegs : ARRAY[1..10] OF WORD := [11, 22, 33, 44,55,66,77,88,99,100]; (*写入保持寄存器的值*)
fbWriteSingleReg : FB_MBWriteSingleReg; (*写入单个寄存器功能块*)
bWriteSingleReg : BOOL; (*写入单个寄存器执行条件*)
nMBAddrSingleReg : WORD := 4; (*写入单个寄存器Modbus 地址*)
nValueSingleReg : WORD := 16#1234; (*写入单个寄存器数值*)
//
PLC程序
fbReadRegs(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:= 1, //Modbus-Tcp从站号
nQuantity:=nQuantityregs, //读取保持寄存器个数
nMBAddr:=nMBAddrregs , //读取保持寄存器Modbus起始地址
cbLength:=SIZEOF(arrDataregs) , //存放保持寄存器变量的个数
pDestAddr:=ADR(arrDataregs) , //存放保持寄存器变量指针起始地址
bExecute:=bReadRegs, //读取保持寄存器执行条件
tTimeout:= T#1S ,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
fbWriteRegs(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:=1 , //Modbus-Tcp从站号
nQuantity:=nQuantityWriteRegs , //写入保持寄存器个数
nMBAddr:= nMBAddrWriteRegs , //写入保持寄存器起始地址
cbLength:= SIZEOF(arrDataWriteRegs), //写入变量的个数和指针起始地址
pSrcAddr:=ADR(arrDataWriteRegs) , //写入变量指针起始地址
bExecute:= bWriteRegs , //写入保持寄存器的执行条件
tTimeout:=T#1S ,
bBusy=> ,
bError=> ,
nErrId=> );
fbWriteSingleReg(
//sIPAddr:='169.254.0.1' , //modsim32的IP地址
sIPAddr:=Server_IpAddress , //modsim32的IP地址
nTCPPort:=502, //Modbus-Tcp端口号
nUnitID:=1 , //Modbus-Tcp从站号
nMBAddr:=nMBAddrSingleReg, //写入单个保持寄存器起始地址
nValue:=nValueSingleReg, //写入单个寄存器数值
bExecute:=bWriteSingleReg , //写入单个寄存器的执行条件
tTimeout:=T#1S ,
bBusy=> ,
bError=> ,
nErrId=> );
一个MW寄存器对应两个MB寄存器,比如MW0对应12289、12289对应MB0、MB1
PLC 客户端程序中变量
读寄存器地址=40001+nMBAddrregs? ? ? ? 则MB0对应设置nMBAddrregs12288
写寄存器地址=40001+nMBAddrWriteRegs? ? ? ??
先给服务端的寄存器赋值
PLCServer程序读
PLC客户端写寄存器
PLC服务端接收到客户端写的寄存器
https://download.csdn.net/download/panjinliang066333/88609166
工程包括:
(1)客户端、服务端PLC程序
(2)TF6250-Modbus-TCP库文件安装软件
(3)ModbusTCP测试工具
模拟客户端:modscan32
模拟服务端:modsim32
(4)倍福官方简单测试参考