H
Solche Sachen lassen sich NICHT in FUP programmieren.
*
FUNCTION_BLOCK FB 10
TITLE =
VERSION : 0.1
VAR_INPUT
xPulse : BOOL ;
wIn : WORD ;
END_VAR
VAR_OUTPUT
wOut : WORD ;
END_VAR
VAR
xHelpFlag : BOOL ;
wArrayOfWord : ARRAY [0 .. 7 ] OF WORD ;
END_VAR
VAR_TEMP
xHelp : BOOL ;
END_VAR
BEGIN
NETWORK
TITLE =
U #xPulse;
FP #xHelpFlag;
SPBN end;
NETWORK
TITLE =
U( ;
L #wArrayOfWord[7];
T #wOut;
SET ;
SAVE ;
CLR ;
U BIE;
) ;
SPBNB _001;
L #wArrayOfWord[6];
T #wArrayOfWord[7];
_001: NOP 0;
NETWORK
TITLE =
U( ;
L #wArrayOfWord[5];
T #wArrayOfWord[6];
SET ;
SAVE ;
CLR ;
U BIE;
) ;
SPBNB _002;
L #wArrayOfWord[4];
T #wArrayOfWord[5];
_002: NOP 0;
NETWORK
TITLE =
U( ;
L #wArrayOfWord[3];
T #wArrayOfWord[4];
SET ;
SAVE ;
CLR ;
U BIE;
) ;
SPBNB _003;
L #wArrayOfWord[2];
T #wArrayOfWord[3];
_003: NOP 0;
NETWORK
TITLE =
U( ;
L #wArrayOfWord[1];
T #wArrayOfWord[2];
SET ;
SAVE ;
CLR ;
U BIE;
) ;
SPBNB _004;
L #wArrayOfWord[0];
T #wArrayOfWord[1];
_004: NOP 0;
NETWORK
TITLE =
L #wIn;
T #wArrayOfWord[0];
NOP 0;
NETWORK
TITLE =
end: O #xHelp;
ON #xHelp;
SAVE ;
END_FUNCTION_BLOCK
AUF #Datenbaustein //Typ: Block_DB [COLOR=red]//hier[/COLOR][COLOR=red] muss dein DB hin ...
[/COLOR] L #Datenende //Typ: INT [COLOR=red]//die Anzahl der zu verarbeitenden Elemente - bei dir wären es 25
[/COLOR] L 1
-I
T #index //Typ: DINT
anf: NOP 0 //Schleifenanfang
L #index
SLD 4 //pointer erzeugen [COLOR=red] //von SLD 3 auf SLD 4 geändert, weil du ja mit Worten arbeiten willst[/COLOR]
[COLOR=red] // aus deiner Adresse wird so ein Bit-Pointer für die indirekte Adressierung erzeugt
[/COLOR] LAR1 //in das Adressregister laden
L DBW [AR1,P#0.0] [COLOR=red]// hier habe ich auch wieder geändert, da du ja mit Worten arbeiten willst
[/COLOR] T DBW [AR1,P#2.0]
L #index
L 1
-I //Index um 1 verringern
T #index
L 1
+I
L #Datenanfang //Typ: INT [COLOR=red] // in deinem Fall = 1[/COLOR]
<=I //prüfen ob fertig
SPB ende //wenn ja ende
SPA anf //sonst schleife wiederholen
ende: NOP 0
L #Eintrag //Typ: WORD
T DBW [AR1,P#0.0] //neuen Wert eintragen
@4L:
Wo ist denn das eine Schleife ?
Soll der TE den Anweisungsblock für seine 25 Worte dann so machen ? Ist für mich OK, wenn er das so will.
finde ech super, dass alle sich Mühe geben um mir zu helfen. Hoffe werde bald so wie ihr sein.
@Vierlagig
dein 1. Code habe ich super gut verstanden weil ich mehr in Richtung Hochsprache mich besser fühle.
Ich arbeite gerade mit dem und habe noch ein kleines Problem.
Habe zur INPUT noch #Datenbaustein( da ich am Ende mein FIFO als Standardbaustein haben muss) eingegeben. ;-)
Habe in STAT #wArrayOfWord Array [<1..32>] of <word> deklariert aber es gibt immer eine Fehlermeldungweiss nicht warum.
Ich muss es meiner Meinung nach danach #wArrayOfWord zu #Datenbaustein zuweisen aber wie???? weiss ich nicht.
Leider markiert S7 nur Array [<1..32>] of <word> ROT und sagt nichts weiter dazu
FUNCTION_BLOCK FB211 // FB_FIFO
// Beschreibung: FB_FIFO
// In diesem Baustein wurde ein FIFO Puffer (Ring-Puffer) realisiert.
// Es gibt zwei Zeiger einen Schreiben Zeiger und einen Lesen Zeiger. In den Puffer werden über diese Zeiger die Daten geschrieben und gelesen.
// Der Puffer kann bei Bedarf neu initialisiert (gelöscht) werden. Mit dem Fuellen Eingang kann der Puffer zum testen mit vorbelegten
// Standardwerten gefüllt werden.
// Schreiben hat in der Regel Vorrang vorm Lesen, das heißt steht z.B Schreiben und Lesen im gleichen Zyklus an, wird zuerst geschrieben und
// anschließend gelesen. Ist der Puffer jetzt allerdings voll, würde es durch diese Vorgehensweise ja zu einem Überlauf kommen, daher wird in diesem Fall
// zuerst gelesen und anschließend geschrieben.
// Ansonsten hat Init Vorrang vor Schreiben und Lesen. Das heißt steht Schreiben oder Lesen und eine Initialisierung im selben Zyklus an, dann wird
// der Auftrag fürs Schreiben bzw. Lesen verworfen.
// Füllen hat wiederum Vorrang vorm Initialisieren, steht hier beides in einem Zyklus an wird der Puffer initialisiert und anschließend gefüllt.
// Ersteller: Didaddy
// Erstelldatum: 21.01.2010
// Änderungen:
AUTHOR: Didaddy;
Version: '1.0';
VAR_INPUT
nIn :INT:= 0; // Der Wert der in den Puffer geschrieben werden soll
bSchreiben :BOOL:= FALSE; // Wert in Puffer schreiben (Bei Dauersignal wird der Auftrag nur einmalig ausgeführt (pos.Fl))
bLesen :BOOL:= FALSE; // Wert aus Puffer lesen (Bei Dauersignal wird der Auftrag nur einmalig ausgeführt (pos.Fl))
bInit :BOOL:= FALSE; // Puffer neu Initialisieren
bFuellen :BOOL:= FALSE; // Puffer mit Standardwerten füllen
END_VAR
VAR_OUTPUT
nOut :INT:= 0; // Der Wert der aus dem Puffer ausgelesen werden soll
nZS :INT:= 1; // Zeiger Schreiben
nZL :INT:= 1; // Zeiger Lesen
nAnzVorhDaten :INT:= 0; // Anzahl der vorhandenen Daten im Puffer
bUeberlauf :BOOL:= 0; // Der älteste Daten Eintrag wurde durch einen neuen überschrieben
END_VAR
CONST
PG := 9; // Puffergrenze
END_CONST
VAR
bSchreibenAlt :BOOL:= FALSE;
bLesenAlt :BOOL:= FALSE;
bInPufferSchreiben:BOOL:= FALSE;
bAusPufferLesen :BOOL:= FALSE;
bPufferInit :BOOL:= FALSE;
bPufferFuellen :BOOL:= FALSE;
nI :INT:= 0;
bVorrangLesen :BOOL:= FALSE; // Das Lesen aus dem Puffer hat Vorrang
anPuffer :ARRAY[1..PG] OF INT:= [PG(0)];
END_VAR
LABEL
Schreiben, Lesen;
END_LABEL
(******************** Kommandos entgegennehmen **********************)
// Kommando in Puffer schreiben
IF bSchreiben AND NOT bSchreibenAlt THEN
bInPufferSchreiben:= TRUE;
END_IF;
bSchreibenAlt:= bSchreiben;
// Kommando aus Puffer Lesen
IF bLesen AND NOT bLesenAlt THEN
bAusPufferLesen:= TRUE;
END_IF;
bLesenAlt:= bLesen;
// Kommando Puffer Initialisieren
IF bInit THEN
bInPufferSchreiben:= FALSE; // Gleichzeitig in Puffer schreiben wird ignoriert
bAusPufferLesen:= FALSE; // Gleichzeitig aus Puffer lesen wird ignoriert
bPufferInit:= TRUE;
END_IF;
// Kommando Puffer fuellen
IF bFuellen THEN
bInPufferSchreiben:= FALSE; // Gleichzeitig in Puffer schreiben wird ignoriert
bAusPufferLesen:= FALSE; // Gleichzeitig aus Puffer lesen wird ignoriert
bPufferFuellen:= TRUE;
END_IF;
(********** Puffer Initialisieren/Füllen, Überlauf checken **********)
// Puffer Initialisieren
IF bPufferInit THEN
FOR nI := 1 TO PG BY 1 DO
anPuffer[nI]:= 0;
END_FOR;
nAnzVorhDaten:= 0;
nZS:= 1;
nZL:= 1;
bUeberlauf:= FALSE;
bPufferInit:= FALSE;
END_IF;
// Puffer füllen
IF bPufferFuellen THEN
FOR nI := 1 TO PG BY 1 DO
anPuffer[nI]:= nI;
END_FOR;
nAnzVorhDaten:= PG;
nZS:= 1;
nZL:= 1;
bUeberlauf:= FALSE;
bPufferFuellen:= FALSE;
END_IF;
// Schreiben Zeiger hat Ringgrenze erreicht
IF nZS > PG THEN
nZS:= 1;
END_IF;
// Lesen Zeiger hat Ringgrenze erreicht
IF nZL > PG THEN
nZL := 1;
END_IF;
// Anzahl vorhandene Daten eingrenzen
IF nAnzVorhDaten > PG THEN
nAnzVorhDaten:= PG;
ELSIF nAnzVorhDaten < 0 THEN
nAnzVorhDaten:= 0;
END_IF;
// Erkennung ob der Puffer voll ist und Lesen und Schreiben gleichzeitig ansteht
IF nAnzVorhDaten = PG AND bInPufferSchreiben AND bAusPufferLesen THEN
GOTO Lesen;
bVorrangLesen:= TRUE; // dann muss erst gelesen und anschließend geschrieben werden (wegen unnötigem Überlauf)
ELSE
bVorrangLesen:= FALSE;
END_IF;
(********************* In den Puffer schreiben **********************)
Schreiben:
// Wert in Puffer schreiben
IF bInPufferSchreiben THEN
// Überlauf checken
IF nAnzVorhDaten = PG THEN
bUeberlauf:= TRUE; // Überlauf wird lediglich signalisiert, neue Daten werden natürlich trozdem eingetragen
nZL:= nZL + 1; // Der Lesen Zeiger wird auf den nächsten gültigen Eintrag gesetzt
ELSE
bUeberlauf:= FALSE;
END_IF;
anPuffer[nZS]:= nIn;
nZS:= nZS + 1;
// Nur erhöhen wenn die Puffergrenze noch nicht erreicht ist (mehr passt ja nicht rein)
IF nAnzVorhDaten < PG THEN
nAnzVorhDaten:= nAnzVorhDaten + 1;
END_IF;
bInPufferSchreiben:= FALSE;
END_IF;
// Wenn Lesen Vorrang hatte dann wurde dies ja bereits erledigt
IF bVorrangLesen THEN
RETURN; // also Ende hier
END_IF;
(*********************** Aus dem Puffer lesen ***********************)
Lesen:
// Nur wenn Daten vorhanden sind, können Werte ausgelesen werden
IF nAnzVorhDaten > 0 AND bAusPufferLesen THEN
bUeberlauf:= FALSE; // Sobald Daten wieder ausgelesen werden, bügeln wir das Überlaufbit wieder nieder
nOut:= anPuffer[nZL];
anPuffer[nZL]:= 0; // Nachdem wir den Puffer ausgelesen haben, schreiben wir ne 0 rein
nZL:= nZL + 1;
nAnzVorhDaten:= nAnzVorhDaten - 1;
bAusPufferLesen:= FALSE;
ELSIF nAnzVorhDaten = 0 AND bAusPufferLesen THEN // Sind keine Daten vorhanden
// nichts machen
bAusPufferLesen:= FALSE;
END_IF;
// Wenn Lesen Vorrang hatte
IF bVorrangLesen THEN
GOTO Schreiben; // dann muß ja noch geschrieben werden
END_IF;
END_FUNCTION_BLOCK
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?