FUNCTION_BLOCK FB104
VAR
wQueue : WORD := 0 ; // der FIFO-Pufferspeicher
xTransport_aktiv : BOOL := FALSE ;
xPlatz1_registered : BOOL ;
xPlatz2_registered : BOOL ;
xPlatz3_registered : BOOL ;
xPlatz4_registered : BOOL ;
END_VAR
VAR_TEMP
wNextP : WORD ; // Nr. nächster Transport, aus dem Pufferspeicher geholt
END_VAR
// wQueue: FIFO als Schieberegister, WORD für 4 Plätze ("Array OF Nibble")
//*** in FIFO einspeichern ***
IF xPlatz1_belegt AND NOT xPlatz1_registered THEN // Anforderung von Platz 1?
wQueue := SHL(IN := wQueue, N := 4) OR 1 ; // zu FIFO hinzufügen
xPlatz1_registered := TRUE ; // Anforderung wurde registriert!
END_IF ;
IF xPlatz2_belegt AND NOT xPlatz2_registered THEN // Anforderung von Platz 2?
wQueue := SHL(IN := wQueue, N := 4) OR 2 ; // zu FIFO hinzufügen
xPlatz2_registered := TRUE ; // Anforderung wurde registriert!
END_IF ;
IF xPlatz3_belegt AND NOT xPlatz3_registered THEN // Anforderung von Platz 3?
wQueue := SHL(IN := wQueue, N := 4) OR 3 ; // zu FIFO hinzufügen
xPlatz3_registered := TRUE ; // Anforderung wurde registriert!
END_IF ;
IF xPlatz4_belegt AND NOT xPlatz4_registered THEN // Anforderung von Platz 4?
wQueue := SHL(IN := wQueue, N := 4) OR 4 ; // zu FIFO hinzufügen
xPlatz4_registered := TRUE ; // Anforderung wurde registriert!
END_IF ;
//*** aus FIFO herausholen ***
IF NOT xTransport_aktiv THEN
IF wQueue <> 0 THEN // FIFO enthält Einträge
IF (wQueue AND W#16#F000) <> 0 THEN // Eintrag an FIFO-Pos.4?
wNextP := SHR(IN := wQueue, N := 12) ; // dann Eintrag kopieren
wQueue := wQueue AND W#16#0FFF ; // und aus FIFO löschen
ELSIF (wQueue AND W#16#0F00) <> 0 THEN // Eintrag an FIFO-Pos.3?
wNextP := SHR(IN := wQueue, N := 8) ; // dann Eintrag kopieren
wQueue := wQueue AND W#16#00FF ; // und aus FIFO löschen
ELSIF (wQueue AND W#16#00F0) <> 0 THEN // Eintrag an FIFO-Pos.2?
wNextP := SHR(IN := wQueue, N := 4) ; // dann Eintrag kopieren
wQueue := wQueue AND W#16#000F ; // und aus FIFO löschen
ELSE
wNextP := wQueue ; // Eintrag von FIFO-Pos.1 kopieren
wQueue := 0 ; // und FIFO löschen
END_IF ;
ELSE // wQueue = 0 : FIFO ist leer
wNextP := 0 ;
END_IF ;
// zu gespeicherter Anforderung gehörenden Transport starten
CASE WORD_TO_INT(wNextP) OF
1 : IF xPlatz1_belegt THEN
xTransport_aktiv := TRUE ;
//Starte_Transport_von_P1 ...
ELSE
xPlatz1_registered := FALSE ; // Palette verschwunden!
END_IF ;
2 : IF xPlatz2_belegt THEN
xTransport_aktiv := TRUE ;
//Starte_Transport_von_P2 ...
ELSE
xPlatz2_registered := FALSE ; // Palette verschwunden!
END_IF ;
3 : IF xPlatz3_belegt THEN
xTransport_aktiv := TRUE ;
//Starte_Transport_von_P3 ...
ELSE
xPlatz3_registered := FALSE ; // Palette verschwunden!
END_IF ;
4 : IF xPlatz4_belegt THEN
xTransport_aktiv := TRUE ;
//Starte_Transport_von_P4 ...
ELSE
xPlatz4_registered := FALSE ; // Palette verschwunden!
END_IF ;
END_CASE;
END_IF ;
//wenn ein Transport beendet wird oder schon wenn die Palette den Warteplatz verlassen hat,
//dann die zugehörige "xPlatzx_registered" auf FALSE rücksetzen
//kann man vorsichtshalber auch für alle "xPlatzx_registered" machen, wenn der FIFO leer ist
END_FUNCTION_BLOCK