通常以太网通信运用的是ip地址,而在fins通信中则是运用网络号、节点号以及单元号来对不同设备(包括plc、pc等现场设备)执行 地址定义的。这就为不同网络之间各种设备的通信提供了统一的寻址方式。在以太网fins通信中,欧姆龙的以太网单元一项主要的功能就是能在ip地址和fins节点地址之间执行 转换,其转换方式有自动转换、ip地址表和复合地址表三种方式,其地址转换数量依据模块型号和转换方式的不同还有相应的限定。以太网fins通信服务是一种基于udp/ip的通信方式,称为fins/udp方式,欧姆龙相关 的以太网产品都支撑这种方式。此外,cs1w-etn21和cj1w- etn21以太网通信模块还支撑 tcp/ip协议,称为fins/tcp方式。
1 、fi ns/udp方式
fins/udp方式是一种运用 udp/ip协议的fins通信方式。udp/ip是一种无连接的通信协议。当一条信息从一个节点发到另一个时,这两个节点是没有明确连接的对等联系的。udp协议具有较快的传输速度,但是数据通信的可靠性没有tcp协议高。
如图2所示,是一个在以太网中发送和接收所运用的udp帧结构。fins/udp方式运用的是一种嵌套格式数据包,即ethernet报头、ip报头、 udp报头和fins帧。一个udp数据段(fins 帧)超过1472字节将被分成若干个数据包来传送。分开的udp数据将在udp/ip协议层自动组合。通常不须要关注运用 层的数据分段,但是在一个多层 ip网络中1427字节的udp包可能无法 发送。在这种系统中就须要运用 fins/tcp方式。
2、 fins帧结构
fins 帧分为fins指令帧和fins响应帧两种形式。指令帧在发送fins指令时运用,响应帧则在接收到fins指令后对其返回响应时运用。它们都是由一个 fins报头(存储传输控制信息)、一个fins指令域(存储一个fins指令)以及一个fins参数/数据域(存储指令参数和发送/响应数据)所组成的。响应帧fins指令域的内容与所接收到的指令帧的fins指令域相同。详细结构见图3、图4。
icf为信息控制域,用于标明指令和响应;rsv为系统保存;gct为网关允许数目;dna为目的网络号;da1为目的节点号;da2为目的单元号;sna为源网络号;sa1为源节点号;sa2为源单元号;sid为服务和响应的标识号,可任意配置,指令和响应对应相同;mrc和src分别为 fins指令的主指令和从指令;参数/数据域,用于标明所操作的数据地址、范围等,在响应帧中前两个字节mres和sres构成响应码,用来诊断不正确信息。
代码:
//plc网络号 //plc节点号 //plc单元号 请根据设备环境自行填写.
//程序没有做输入值的判断.
//写入功能每次只写2个字节.即 ffff
procedure
tform1
.
setaddress();
var
v:
integer
;
begin
mac :=
$82
;
if
radiobutton1
.
checked
then
mac :=
$82
;表示dm区
if
radiobutton2
.
checked
then
mac :=
$80
;
v := hextoint(edtaddress
.
text);
address[
0
] :=
$00
;
address[
1
] :=
byte
( v
and
$00ff
);
address[
2
] :=
byte
( (v
and
$ff00
)
shr
8
) ;
v := hextoint(edtval
.
text);
value[
0
] :=
byte
( v
and
$00ff
);
value[
1
] :=
byte
( (v
and
$ff00
)
shr
8
);
end
;
procedure
tform1
.
btnwriteclick(sender: tobject);
var
data:
array
[
0..19
]
of
byte
;
n,i:
integer
;
s,t:
string
;
datalen:
integer
;
begin
//
setaddress();
s:=
''
;
data[
0
] :=
$80
;
//icf
data[
1
] :=
$00
;
//rsv
data[
2
] :=
$02
;
//gct
data[
3
] :=
$00
;
//plc网络号
data[
4
] :=
$00
;
//plc节点号
data[
5
] :=
$00
;
//plc单元号
data[
6
] :=
$00
;
//上位机网络号
data[
7
] :=
$51
;
//上位机节点号
data[
8
] :=
$00
;
//上位机节点号
data[
9
] :=
$57
;
//sid
data[
10
] :=
$01
;
//mrc 命令
data[
11
] :=
$02
;
//src
data[
12
] := mac;
//visbaletype
data[
13
] := address[
2
];
//起始地址. $00 从0开始
data[
14
] := address[
1
];
//第9位为$09,第十位为$0a直到$0f,接下去再从10开始以此算起,因为是十六进制数。
data[
15
] := address[
0
];
data[
16
] :=
$00
;
//no.of item
data[
17
] :=
$01
;
//no.of item
data[
18
] := value[
1
];
//data
data[
19
] := value[
0
];
//data
idudpclient1
.
sendbuffer(data,
20
); 控件端口
9600
host为plc的ip地址
t:=
'--------->>>>'
;
for
i:=
0
to
19
do
t:= t+ inttohex(data[i],
2
) +
' '
;
memo1
.
lines
.
add(t);
checkrecv();
end
;
procedure
tform1
.
init();
begin
//
idudpclient1
.
active :=
true
;
end
;
procedure
tform1
.
formcreate(sender: tobject);
begin
init();
end
;
procedure
tform1
.
formclose(sender: tobject;
var
action: tcloseaction);
begin
idudpclient1
.
active :=
false
;
end
;
procedure
tform1
.
btnreadclick(sender: tobject);
var
data:
array
[
0..17
]
of
byte
;
recv:
array
[
0..1023
]
of
byte
;
n,i:
integer
;
s,t:
string
;
datalen:
integer
;
begin
//
setaddress();
s:=
''
;
data[
0
] :=
$80
;
//icf
data[
1
] :=
$00
;
//rsv
data[
2
] :=
$02
;
//gct
data[
3
] :=
$00
;
//plc网络号
data[
4
] :=
$00
;
//plc节点号
data[
5
] :=
$00
;
//plc单元号
data[
6
] :=
$00
;
//上位机网络号
data[
7
] :=
$51
;
//上位机节点号
data[
8
] :=
$00
;
//上位机节点号
data[
9
] :=
$52
;
//sid
data[
10
] :=
$01
;
//mrc 命令
data[
11
] :=
$01
;
//src
data[
12
] := mac;
//visbaletype
data[
13
] := address[
2
];
//起始地址.
data[
14
] := address[
1
];
//
data[
15
] := address[
0
];
//
data[
16
] :=
$00
;
//no.of item
//data[17] := $01; //no.of item
data[
17
] :=
byte
(strtoint(edtlen
.
text));
idudpclient1
.
sendbuffer(data,
18
);
t:=
'--------->>>>'
;
for
i:=
0
to
17
do
t:= t+ inttohex(data[i],
2
) +
' '
;
memo1
.
lines
.
add(t);
checkrecv();
end
;