Scl-fifo

Code:
FUNCTION_BLOCK FB50
VAR_INPUT
  // Eingangs Variablen
  bWrite       :BOOL;
  bRead        :BOOL;  
  wStore       :WORD;
END_VAR

VAR_OUTPUT
  // Ausgangs Variablen
  wValue       :WORD;
END_VAR

VAR
  // statische Variablen
  myData        :ARRAY[0..99] OF WORD;
  myWriteIndex  :INT:=0;
  myReadIndex   :INT:=0;  
  myFPWrite     :BOOL;
  myFPRead      :BOOL;
END_VAR

  // Anweisungsteil
  IF bWrite AND NOT myFPWrite THEN
    myData[myWriteIndex] := wStore;
    myWriteIndex := myWriteIndex + 1;
    IF myWriteIndex > 99 THEN 
      myWriteIndex := 0;
    END_IF;    
  END_IF;
  myFPWrite := bWrite;
  
  IF bRead AND NOT myFPRead THEN
    wValue := myData[myReadIndex];
    myReadIndex := myReadIndex + 1;
    IF myReadIndex > 99 THEN 
      myReadIndex := 0;
    END_IF;    
  END_IF;
  myFPRead := bRead;
END_FUNCTION_BLOCK
 
Hallo,
damit es einwandfrei klappt, muss myWriteIndex>=myReadIndex (man kann nicht aus einem leeren Stack(Fifo) nicht lesen)

MFG

johnij
 
Hallo,
damit es einwandfrei klappt, muss myWriteIndex>=myReadIndex (man kann nicht aus einem leeren Stack(Fifo) nicht lesen)

MFG

johnij

1. Der Code oben war nur ein Grundgerüst.
2. würde ich um angesprochenes Problem zu umgehen folgende Funktionen einfügen.
-einen Zähler der nach außen bekannt gibt wie viele Elemente gespeichert sind.
-eine Resetfunktion.

Code:
FUNCTION_BLOCK FB50
VAR_INPUT
  // Eingangs Variablen
  bWrite       :BOOL;
  bRead        :BOOL;  
  wStore       :WORD;
  bReset       :BOOL;
END_VAR

VAR_OUTPUT
  // Ausgangs Variablen
  wValue       :WORD;
  iCount       :INT;
END_VAR

VAR
  // statische Variablen
  myData        :ARRAY[0..99] OF WORD;
  myWriteIndex  :INT:=0;
  myReadIndex   :INT:=0;  
  myFPWrite     :BOOL;
  myFPRead      :BOOL;
END_VAR

  // Anweisungsteil
  IF bWrite AND NOT myFPWrite THEN
    myData[myWriteIndex] := wStore;
    myWriteIndex := myWriteIndex + 1;
    iCount := iCount + 1;
    IF myWriteIndex > 99 THEN 
      myWriteIndex := 0;
    END_IF;    
  END_IF;
  myFPWrite := bWrite;
  
  IF iCount >= 0 THEN
    IF bRead AND NOT myFPRead THEN
      wValue := myData[myReadIndex];
      myReadIndex := myReadIndex + 1;
      iCount := iCount - 1;
      IF myReadIndex > 99 THEN 
        myReadIndex := 0;
      END_IF;      
    END_IF;    
  ELSE
    wValue := 0;
  END_IF;
  
  myFPRead := bRead;
  
  IF bReset THEN
    myWriteIndex := 0;
    myReadIndex  := 0;
    iCount       := 0;
  END_IF;
    
END_FUNCTION_BLOCK
//Edit:
PS: Deine Lösung mit dem Vergleich (myWriteIndex>=myReadIndex) geht nicht! Diese Bedingung ist kein verlässliches Indiz für einen befüllten Speicher.

PPS: Man sollte Außerhalb des FB beim Lesen und Schreiben auswerten wie groß die Datenmenge ist. Also bei <1 nichts auslesen und bei >=100 nichts reinschreiben. Wenn man das innerhalb des FBs macht muss man an den Aufruf mitteilen das, dass Lesen bzw. Schreiben wegen eines Speicher Über- bzw. Unterlauf fehlgeschlagen ist.
 
Zuletzt bearbeitet:
Zurück
Oben