Applikationsobjekte definieren und konfigurieren

Applikationsobjekte = Single Points, Double Points, Measured Values, Short Floating Point Values usw.

In diesem Beispiel wurden die Befehle so konfiguriert, dass die Prozessdaten der Befehle im gleichen Speicherbereich aber auf einem anderen Byte-/Bit-Offset wie die Daten der Information in Überwachungsrichtung liegen. Sie können aber auch die Befehle auf den gleichen Byte- Bit-Offset wie die Information in Überwachungsrichtung legen.

Beispiel:

C_SC_NA_1 mit IOA = 10 auf den gleichen Byte- und Bit-Offset wie M_SP_NA_1 mit IOA = 100 (beide Byte-Offset = 100 und Bit-Offset = 0). In diesem Fall wird eine Wertänderung durch ein Kommando von der Leitstation eine Übertragung des M_SP_NA_1 mit der Objektadresse 100 und Übertragungsursache <11> (returned by remote command) zur Folge haben.

Als Beispiel für das Tutorial werden folgende Applikationsobjekte:

Arrayelement

ASDU identifier

Objektadresse
IOA

Group-Konfigurationsparameter

Basiszeitmultiplikator

SPS-Prozessdatenbereich

Offset
Byte

Offset
Bit

Prozessdatenbreite

in der TwinCAT SPS

0

M_SP_NA_1

100

Generalabfrage

0

Merker

100

0

1 Bit

1

M_SP_NA_1

101

Generalabfrage

0

Merker

100

1

1 Bit

2

M_SP_TB_1

102

Generalabfrage

0

Merker

100

2

1 Bit

3

M_DP_NA_1

200

Generalabfrage

0

Merker

200

0

2 Bits

4

M_DP_NA_1

201

Generalabfrage

0

Merker

200

2

2 Bits

5

M_DP_TB_1

202

Generalabfrage

0

Merker

200

4

2 Bits

6

M_ST_NA_1

300

Generalabfrage

0

Merker

300

0

1 Byte

7

M_ST_NA_1

301

Generalabfrage

0

Merker

301

0

1 Byte

8

M_ST_TB_1

302

Generalabfrage

0

Merker

302

0

1 Byte

9

M_BO_NA_1

400

Generalabfrage

0

Merker

400

0

4 Byte

10

M_BO_NA_1

401

Generalabfrage

0

Merker

404

0

4 Byte

11

M_BO_TB_1

402

Generalabfrage

0

Merker

408

0

4 Byte

12

M_ME_NA_1

500

Generalabfrage

0

Merker

500

0

2 Byte

13

M_ME_NA_1

501

Generalabfrage

0

Merker

502

0

2 Byte

14

M_ME_TD_1

502

Generalabfrage

0

Merker

504

0

2 Byte

15

M_ME_NB_1

600

Generalabfrage

0

Merker

600

0

2 Byte

16

M_ME_NB_1

601

Generalabfrage

0

Merker

602

0

2 Byte

17

M_ME_TE_1

602

Generalabfrage

0

Merker

604

0

2 Byte

18

M_ME_NC_1

700

Generalabfrage

0

Merker

700

0

4 Byte

19

M_ME_NC_1

701

Generalabfrage

0

Merker

704

0

4 Byte

20

M_ME_TF_1

702

Generalabfrage

0

Merker

708

0

4 Byte

21

M_IT_NA_1

800

Generalzählerabfrage und Mode A (lokal Umspeichern mit Spontanübertragung alle 15s)

0

Merker

800

0

4 Byte

22

M_IT_NA_1

801

Generalzählerabfrage und Mode A

(lokal Umspeichern mit Spontanübertragung alle 15s)

0

Merker

804

0

4 Byte

23

M_IT_TB_1

802

Generalzählerabfrage und Mode A

(lokal Umspeichern mit Spontanübertragung alle 15s)

0

Merker

808

0

4 Byte

Commands

 

 

 

 

 

 

 

 

24

C_SC_NA_1

10

-

0

Merker

2100

0

1 Bit

25

C_SC_NA_1

11

-

0

Merker

2100

1

1 Bit

26

C_SC_TA_1

12

-

0

Merker

2100

2

1 Bit

27

C_DC_NA_1

20

-

0

Merker

2200

0

2 Bit

28

C_DC_NA_1

21

-

0

Merker

2200

2

2 Bit

29

C_DC_TA_1

22

-

0

Merker

2200

4

2 Bit

30

C_RC_NA_1

30

-

0

Merker

2300

0

1 Byte

31

C_RC_NA_1

31

-

0

Merker

2301

0

1 Byte

32

C_RC_TA_1

32

-

0

Merker

2302

0

1 Byte

33

C_BO_NA_1

40

-

0

Merker

2400

0

4 Byte

34

C_BO_NA_1

41

-

0

Merker

2404

0

4 Byte

35

C_BO_TA_1

42

-

0

Merker

2408

0

4 Byte

36

C_SE_NA_1

50

-

0

Merker

2500

0

2 Byte

37

C_SE_NA_1

51

-

0

Merker

2502

0

2 Byte

38

C_SE_TA_1

52

-

0

Merker

2504

0

2 Byte

39

C_SE_NB_1

60

-

0

Merker

2600

0

2 Byte

40

C_SE_NB_1

61

-

0

Merker

2602

0

2 Byte

41

C_SE_TB_1

62

-

0

Merker

2604

0

2 Byte

42

C_SE_NC_1

70

-

0

Merker

2700

0

4 Byte

43

C_SE_NC_1

71

-

0

Merker

2704

0

4 Byte

44

C_SE_TC_1

72

-

0

Merker

2708

0

4 Byte

Datenbankvariable deklarieren

Die Applikationsobjekt-Datenbank ist eine Array-Variable vom Typ ST_IEC870_5_101AODBEntry. Jedes Array-Element entspricht einem Applikationsobjekt. Die maximale Anzahl der Applikationsobjekte ist frei wählbar und nur durch den verfügbaren Speicher begrenzt. Sie müssen sich auf eine konstante maximale Anzahl während der SPS-Programmierung festlegen. Zur Laufzeit kann die maximale Anzahl der Applikationsobjekte nicht mehr verändert werden.

In unserem Beispiel werden 50 Applikationsobjekte deklariert. Diese Anzahl reicht für die meisten Anwendungen aus. Beachten Sie, dass sehr viele Applikationsobjekte auch entsprechend viel Speicher und Laufzeit benötigen.

Definieren Sie folgende Variable in MAIN:

PROGRAM MAIN
VAR
AODB : ARRAY[0..49] OF ST_IEC870_5_101AODBEntry;
END_VAR

Applikationsobjekte konfigurieren

Während der Konfiguration der einzelnen Applikationsobjekte werden unter anderem der Objekt-Typ ( M_SP_NA_1, M_DP_NA_1, M_ST_NA_1 usw.), die Objekt-Adresse und weitere Objekt-Parameter festgelegt.

Die Konfiguration der gewünschten Applikationsobjekte wird zur Programmlaufzeit durchgeführt. Jedes Applikationsobjekt (Datenbank-Array-Element) wird durch einen einmaligen Aufruf der F_iecInitAOEntry-Funktion konfiguriert. Das zu konfigurierende Array-Element wird an die Funktion per VAR_IN_OUT übergeben. Im Regelfall wird die Konfiguration beim SPS-Programmstart einmalig in einer Init-Routine durchgeführt. Die Funktion F_iecInitAOEntry erwartet folgende Funktionsparameter (von links nach rechts):

FUNCTION F_iecInitAOEntry : UDINT
VAR_INPUT
eType : E_IEC870_5_101TcTypeID;
objAddr : DWORD := 0;
group : DWORD := 0;
multiplier : BYTE := 0;
ioMapType : E_IEC870_5_101IOMappingType;
byteOffs : UDINT := 0;
bitOffs : UDINT := 0;
END_VAR
VAR_IN_OUT
dbEntry : ST_IEC870_5_101AODBEntry;
END_VAR

eType: Applikationsobjekt-Typ (ASDU identifier, z.B.: M_SP_NA_1 für Single Point oder M_DP_NA_1 für Double Point ). Beachten Sie, dass nur die in der Kompatibilitätsliste aufgeführten ASDU-Typen verwendet werden können. Unzulässige Typen werden ignoriert.

objAddr : Objektadresse, z.B. 100. Jedes Applikationsobjekt sollte mit einer eindeutigen Adresse konfiguriert werden.

group: Group-Konfigurationsparameter. Die verfügbaren Group-Parameter sind als Konstanten definiert und können mit ODER-Operator kombiniert werden. Z.B.: IEC870_GRP_INROGEN OR IEC870_GRP_PERCYC.

Hier finden Sie die Beschreibung aller Group-Konfigurationsparameter.

mutiplier: Basiszeitmultiplikator für die zyklische/periodische Datenübertragung ( 0=Deaktiviert). Die Basiszeit wird über die Systemparameter konfiguriert. Wurde die Basiszeit z.B. auf T#10s gesetzt und der Multiplikator auf den Wert 2, dann werden die periodischen/zyklischen Daten des Applikationsobjekts alle 20 Sekunden gesendet.

ioMapType: Dieser Parameter legt fest, aus oder in welchen Prozessdatenbereich der TwinCAT SPS die IEC-Prozessdaten zur Laufzeit gemappt werden sollen (inputs, outputs, memory, data).

byteOffs: Prozessdatenbereich Byteoffset;

bitOffs: Prozessdatenbereich Bitoffset;

dbEntry: Applikationsobjekt das konfiguriert werden soll (ein Datenbankvariable-Arrayelement, das an die Funktion per VAR_IN_OUT übergeben wird).

Um die Applikationsobjekte beim Programmstart zu konfigurieren wird in MAIN folgender SPS-Code hinzugefügt:

PROGRAM MAIN
VAR
AODB : ARRAY[0..49] OF ST_IEC870_5_101AODBEntry;

init : BOOL := TRUE;
initError : UDINT;
END_VAR

IF init THEN
init := FALSE;

(* Monitored Single Points *)
initError := F_iecInitAOEntry( M_SP_NA_1, 100, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 100, 0, AODB[0] );
initError := F_iecInitAOEntry( M_SP_NA_1, 101, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 100, 1, AODB[1] );
initError := F_iecInitAOEntry( M_SP_TB_1, 102, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 100, 2, AODB[2]);
(* Double Points*)
initError := F_iecInitAOEntry( M_DP_NA_1, 200, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 200, 0, AODB[3] );
initError := F_iecInitAOEntry( M_DP_NA_1, 201, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 200, 2, AODB[4] );
initError := F_iecInitAOEntry( M_DP_TB_1, 202, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 200, 4, AODB[5] );
(* Regulating step value *)
initError := F_iecInitAOEntry( M_ST_NA_1, 300, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 300, 0, AODB[6] );
initError := F_iecInitAOEntry( M_ST_NA_1, 301, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 301, 0, AODB[7] );
initError := F_iecInitAOEntry( M_ST_TB_1, 302, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 302, 0, AODB[8] );
(* 32 bit string*)
initError := F_iecInitAOEntry( M_BO_NA_1, 400, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 400, 0, AODB[9] );
initError := F_iecInitAOEntry( M_BO_NA_1, 401, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 404, 0, AODB[10] );
initError := F_iecInitAOEntry( M_BO_TB_1, 402, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 408, 0, AODB[11] );
(* Measured value, normalized value *)
initError := F_iecInitAOEntry( M_ME_NA_1, 500, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 500, 0, AODB[12] );
initError := F_iecInitAOEntry( M_ME_NA_1, 501, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 502, 0, AODB[13] );
initError := F_iecInitAOEntry( M_ME_TD_1, 502, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 504, 0, AODB[14] );
(* Mesured value, scaled value *)
initError := F_iecInitAOEntry( M_ME_NB_1, 600, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 600, 0, AODB[15] );
initError := F_iecInitAOEntry( M_ME_NB_1, 601, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 602, 0, AODB[16] );
initError := F_iecInitAOEntry( M_ME_TE_1, 602, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 604, 0, AODB[17] );
(* Measured value , short floating point value *)
initError := F_iecInitAOEntry( M_ME_NC_1, 700, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 700, 0, AODB[18] );
initError := F_iecInitAOEntry( M_ME_NC_1, 701, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 704, 0, AODB[19] );
initError := F_iecInitAOEntry( M_ME_TF_1, 702, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 708, 0, AODB[20] );
(* Integrated totals *)
initError := F_iecInitAOEntry( M_IT_NA_1, 800, IEC870_GRP_REQCOGEN OR IEC870_GRP_LOCFREEZE, 0, MAP_AREA_MEMORY, 800, 0, AODB[21] );
initError := F_iecInitAOEntry( M_IT_NA_1, 801, IEC870_GRP_REQCOGEN OR IEC870_GRP_LOCFREEZE, 0, MAP_AREA_MEMORY, 804, 0, AODB[22] );
initError := F_iecInitAOEntry( M_IT_TB_1, 802, IEC870_GRP_REQCOGEN OR IEC870_GRP_LOCFREEZE, 0, MAP_AREA_MEMORY, 808, 0, AODB[23] );

(* Single commands *)
initError := F_iecInitAOEntry( C_SC_NA_1, 10, 0, 0, MAP_AREA_MEMORY, 2100, 0, AODB[24] );
initError := F_iecInitAOEntry( C_SC_NA_1, 11, 0, 0, MAP_AREA_MEMORY, 2100, 1, AODB[25] );
initError := F_iecInitAOEntry( C_SC_TA_1, 12, 0, 0, MAP_AREA_MEMORY, 2100, 2, AODB[26] );
(* Double commands *)
initError := F_iecInitAOEntry( C_DC_NA_1, 20, 0, 0, MAP_AREA_MEMORY, 2200, 0, AODB[27] );
initError := F_iecInitAOEntry( C_DC_NA_1, 21, 0, 0, MAP_AREA_MEMORY, 2200, 2, AODB[28] );
initError := F_iecInitAOEntry( C_DC_TA_1, 22, 0, 0, MAP_AREA_MEMORY, 2200, 4, AODB[29] );
(* Regulating step commands *)
initError := F_iecInitAOEntry( C_RC_NA_1, 30, 0, 0, MAP_AREA_MEMORY, 2300, 0, AODB[30] );
initError := F_iecInitAOEntry( C_RC_NA_1, 31, 0, 0, MAP_AREA_MEMORY, 2301, 0, AODB[31] );
initError := F_iecInitAOEntry( C_RC_TA_1, 32, 0, 0, MAP_AREA_MEMORY, 2302, 0, AODB[32] );
(* 32 bit string commands *)
initError := F_iecInitAOEntry( C_BO_NA_1, 40, 0, 0, MAP_AREA_MEMORY, 2400, 0, AODB[33] );
initError := F_iecInitAOEntry( C_BO_NA_1, 41, 0, 0, MAP_AREA_MEMORY, 2404, 0, AODB[34] );
initError := F_iecInitAOEntry( C_BO_TA_1, 42, 0, 0, MAP_AREA_MEMORY, 2408, 0, AODB[35] );
(* Set point, normalized values*)
initError := F_iecInitAOEntry( C_SE_NA_1, 50, 0, 0, MAP_AREA_MEMORY, 2500, 0, AODB[36] );
initError := F_iecInitAOEntry( C_SE_NA_1, 51, 0, 0, MAP_AREA_MEMORY, 2502, 0, AODB[37] );
initError := F_iecInitAOEntry( C_SE_TA_1, 52, 0, 0, MAP_AREA_MEMORY, 2504, 0, AODB[38] );
(* Set point, scaled valuess *)
initError := F_iecInitAOEntry( C_SE_NB_1, 60, 0, 0, MAP_AREA_MEMORY, 2600, 0, AODB[39] );
initError := F_iecInitAOEntry( C_SE_NB_1, 61, 0, 0, MAP_AREA_MEMORY, 2602, 0, AODB[40] );
initError := F_iecInitAOEntry( C_SE_TB_1, 62, 0, 0, MAP_AREA_MEMORY, 2604, 0, AODB[41] );
(* Set point, short floating point values *)
initError := F_iecInitAOEntry( C_SE_NC_1, 70, 0, 0, MAP_AREA_MEMORY, 2700, 0, AODB[42] );
initError := F_iecInitAOEntry( C_SE_NC_1, 71, 0, 0, MAP_AREA_MEMORY, 2704, 0, AODB[43] );
initError := F_iecInitAOEntry( C_SE_TC_1, 72, 0, 0, MAP_AREA_MEMORY, 2708, 0, AODB[44] );

END_IF

Das zugehörige Tutorial SPS-Beispiel kann hier heruntergeladen werden.