以太网FINS通信中,各种数据信息是以UDP/IP包或者TCP/IP包的方式在以太网上发送和接收的。其中,在Internet层远程设备运用的是 IP地址,而在运用 层运用的则是FINS节点地址。传输层中定义了本地UDP或TCP端口号,它为运用层(即FINS通信)提供通信端口,其默认配置为 9600。用户可以根据实际情况自行修改,但是在同一网络中,各设备的通信端口号必须保持一致。
通常以太网通信运用的是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构成响应码,用来诊断不正确信息。
代码:
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
;
data[
1
] :=
$00
;
data[
2
] :=
$02
;
data[
3
] :=
$00
;
data[
4
] :=
$00
;
data[
5
] :=
$00
;
data[
6
] :=
$00
;
data[
7
] :=
$51
;
data[
8
] :=
$00
;
data[
9
] :=
$57
;
data[
10
] :=
$01
;
data[
11
] :=
$02
;
data[
12
] := MAC;
data[
13
] := address[
2
];
data[
14
] := address[
1
];
data[
15
] := address[
0
];
data[
16
] :=
$00
;
data[
17
] :=
$01
;
data[
18
] := value[
1
];
data[
19
] := value[
0
];
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
;
data[
1
] :=
$00
;
data[
2
] :=
$02
;
data[
3
] :=
$00
;
data[
4
] :=
$00
;
data[
5
] :=
$00
;
data[
6
] :=
$00
;
data[
7
] :=
$51
;
data[
8
] :=
$00
;
data[
9
] :=
$52
;
data[
10
] :=
$01
;
data[
11
] :=
$01
;
data[
12
] := MAC;
data[
13
] := address[
2
];
data[
14
] := address[
1
];
data[
15
] := address[
0
];
data[
16
] :=
$00
;
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
;