FB_IEC870_5_101TBufferCtrl
Ab der Produktversion: TwinCAT PLC Library IEC60870-5-104 Unterstation v2.0.6 / IEC60870-5-101 Unterstation v2.0.2 und höher.
Mit diesem Funktionsbaustein kann der Inhalt des TX/RX-Datenpuffers manipuliert werden, der bei der Kommunikation über das IEC60870-5-104/101 Transport Interface benutzt wird.
Der Funktionsbaustein besitzt folgende Aktionen:
- RxRemoveObj (entfernt den ältesten Fifoeintrag aus dem RX-Fifo);
- RxReset (löscht alle RX-Fifoeinträge, setzt den RX-Fifo zurück);
- TxAddObj (fügt einen neuen Fifoeintrag in den TX-Fifo);
- TxReset (löscht alle TX-Fifoeinträge, setzt den TX-Fifo zurück)
Durch den Aufruf der oben aufgelisteten Aktionen kann der Inhalt des TX/RX-Datenpuffers verändert werden.
VAR_IN_OUT
VAR_IN_OUT
buffer : ST_IEC870_5_101TBuffer; (* TX/RX data buffer *)
END_VAR
buffer: TX/RX-Datenpuffer. Die TX/RX-Pufferparameter (wie z.B. asduSize ) müssen vor der Benutzung konfiguriert werden.
VAR_INPUT
VAR_INPUT
putObj : ST_IEC870_5_101AOGen; (* ASDU to send *)
END_VAR
putObj: Dateneinheit (ASDU), die gesendet werden soll.
VAR_OUTPUT
VAR_OUTPUT
getObj : ST_IEC870_5_101AOGen; (* received ASDU *)
bOk : BOOL; (* TRUE = action succesfully, FALSE=Fifo overflow or fifo empty *)
END_VAR
getObj: Empfangene Dateneinheit (ASDU).
bOk: Diese Variable wird TRUE, wenn ein neuer Eintrag erfolgreich hinzugefügt oder aus dem Fifo entfernt wurde. Diese Variable wird FALSE beim Pufferüberlauf und wenn kein Eintrag entfernt werden konnte, weil der Fifo bereits leer ist.
Beispiel in ST:
Folgendes Beispielcode (Ausschnitt) demonstriert die Benutzung der Baustein-Aktionen. Alle ~100ms (tCycle) wird eine neue ASDU (M_BO_TB_1) mit der Übertragungsursache: Spontan und Zeitstempel generiert und in den TX-Fifo abgelegt.
Die empfangenen Testkommandos (C_TS_TA_1) und Uhrzeitsynchronisationskommandos (C_CS_NA_1) werden aus dem RX-Fifo entfernt und mit gespiegelten ASDU's beantwortet.
PROGRAM P_SAMPLE_1ms
VAR
(* TX/RX data buffer *)
fbBuffer : FB_IEC870_5_101TBufferCtrl;
buffer : ST_IEC870_5_101TBuffer := ( asduSize := 253 );
tCycle : TIME := T#100ms;
timer : TON;
dtStart : DT := DT#2006-07-05-12:34:56;
txAsdu : ST_IEC870_5_101AOGen;
rxAsdu : ST_IEC870_5_101AOGen;
txBSI : DWORD := 1;
txQDS : BYTE;
txTT : T_CP56Time2a;
rxTT : T_CP56Time2a;
END_VAR
timer( IN := TRUE, PT := tCycle );
IF timer.Q THEN
timer( IN := FALSE );
txAsdu.ident.eType := M_BO_TB_1; (* Bit string with time tag *)
txAsdu.ident.bSQ := FALSE;
txAsdu.ident.nObj := 1;
txAsdu.ident.eCOT := eIEC870_COT_SPONTAN;
txAsdu.ident.nORG := 1;
txAsdu.ident.bPN := FALSE;
txAsdu.ident.bT := FALSE;
txAsdu.ident.eClass := eIEC870_Class_1;
txAsdu.ident.asduAddr := 7;
txAsdu.info.objAddr := 100;
txBSI := ROL( txBSI, 1); (* Modify bit string value *)
txQDS.7 := NOT txQDS.7; (* Toggle IV quality flag *)(* create dummy time tag *)
dtStart := dtStart + tCycle;
txTT := SYSTEMTIME_TO_CP56Time2a( DT_TO_SYSTEMTIME( dtStart ), TRUE );
F_iecResetStream( 0, txAsdu.info.stream ); (* clear previous data (this sets the stream length = 0 *)
F_iecCopyBufferToStream( ADR( txBSI ), SIZEOF( txBSI ), txAsdu.info.stream ); (* put BSI to stream *)
F_iecCopyBufferToStream( ADR( txQDS ), SIZEOF( txQDS ), txAsdu.info.stream ); (* put QDS to stream *)
F_iecCopyBufferToStream( ADR( txTT ), SIZEOF( txTT ), txAsdu.info.stream ); (* put time tag to stream *)
fbBuffer.TxAddObj( putObj := txAsdu, buffer := buffer ); (* put asdu to the TX fifo *)
IF NOT fbBuffer.bOk THEN
;(* Report send buffer overflow error *)
END_IF
END_IF
REPEAT
fbBuffer.RxRemoveObj( getObj=>rxAsdu, buffer := buffer ); (* Try to remove asdu from RX fifo *)
IF fbBuffer.bOk THEN (* success *)
CASE rxAsdu.ident.eType OF
C_TS_TA_1: (* Test command *)
txAsdu := rxAsdu;
txAsdu.ident.eCOT := eIEC870_COT_ACT_CON; (* send activation confirmation *)
fbBuffer.TxAddObj( putObj := txAsdu, buffer := buffer ); (* put asdu to the TX fifo *)
IF NOT fbBuffer.bOk THEN
;(* Report send buffer overflow error *)
END_IF
C_CS_NA_1: (* clock synchronisation *)
F_iecCopyStreamToBuffer( ADR( rxTT ), SIZEOF( rxTT ), rxAsdu.info.stream );
(*... *)
txAsdu := rxAsdu; (* dummy old time value *)
txAsdu.ident.eCOT := eIEC870_COT_ACT_CON; (* send activation confirmation *)
fbBuffer.TxAddObj( putObj := txAsdu, buffer := buffer ); (* put asdu to the TX fifo *)
IF NOT fbBuffer.bOk THEN
;(* Report send buffer overflow error *)
END_IF
END_CASE
END_IF
UNTIL NOT fbBuffer.bOk (* RX fifo is empty *)
END_REPEAT
Voraussetzungen
Entwicklungsumgebung | Zielplattform | Einzubindende SPS Bibliotheken |
---|---|---|
TwinCAT v2.10.0 Build >= 1301 | PC oder CX (x86) CX (ARM) | TcIEC870_5_101.Lib |