Fifo S7

stevexxx

Level-1
Beiträge
40
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
hy...
muss einen FIFO mit s7 in AWL realisieren mit 2 Pointern (ohne Schiebefunktionen)
dazu muss ich 100 int Werte einlesen und bei Bedarf ausgeben natürlich ohne die Hilfe des S7 Fifo Bausteines



E0.1 Wert einlesen
E0.2 Wert ausgeben
Ew 2 einzulesender Wert
Db1 DW0-200 FIFo Werte
AW0 FIFO Ausgabe

Problematik dabei ist wenn ich bei 100 angelangt bin auslese dann muss er anfangen von vorne den fifo zu beschreiben
 
Hallo Steve,
mit dem folgende Satz konnte ich garnichts anfangen :
Problematik dabei ist wenn ich bei 100 angelangt bin auslese dann muss er anfangen von vorne den fifo zu beschreiben

Aber davon unabhängig :
Ich würde mit einem Index arbeiten, der mit die erste zu beschreibende DB-Adresse angibt und einen weiteren, der mir die erste auszulesende DB-Adresse angibt.
Schreibst du den ersten Wert in den FIFO, dann erhöhst du den Schreibzeiger und den Lesezeiger setzt du auf "1". Bei jedem weiteren eingetragenen Wert erhöhst du nur den Schreibzeiger. Beschreiben kannst du den FIFO bis dein Schreibzeiger entweder den max.Wert erreicht hat oder wenn du mit Ring-Schreiben arbeitest bis der Schreibzeiger = Lesezeiger -1 ist.
Beim Auslesen erhöhst du den Lesezeiger jeweils um 1 bis dein Lesezeiger = Schreibzeiger -1 ist.

Vielleicht hilft dir das ja schon ...

Gruß
LL
 
naja schulaufgabe net ganz


U "FIFO Beschreiben"
FP "Flanke Pos Besch"
SPBNB Next
AUF DB 1
L DBW 202
L DBW 204
-D
T MB 9
L MB 9
L 99
<=I
SPBB Null

Nul1: L DBW 204
L 16
*D
NOP 0
R "Nur Schreiben"
L DBW 202
L 16
*D
LAR1
L "Wert einlesen"
T DBW [AR1,P#0.0]

L DBW 202
INC 1
T DBW 202
L DBW 202
SPA Next
Null: L 0
T DBW 202
SPA Nul1

Next: NOP 0






U "FIFO Lesen"
FP "Flanke pos lesen"
UN "Nur Schreiben"
SPBNB NEXT

AUF DB 1
L DBW 202
L DBW 204
-D
T MB 8
L MB 8
L 0
==I
SPBB Nein


LAR1
L DBW [AR1,P#0.0]
T "Ausgang Lesen"
L DBW 204
INC 1
T DBW 204

SPA Next
Nein: S "Nur Schreiben"
NEXT: NOP 0





woran es hängt Umlaufspeicher... das nicht ausgelesene Sachen nicht überschreibe.....
 
Um einen Überlauf oder Unterlauf des FIFO-Speichers auszuwerten, würde ich eine Zählvariable verwenden.

Immer bein schreiben inkrementieren und beim Lesen dekrementieren. Wenn diese Variable =Null ist kann man nicht mehr Lesen und wenn sie =MAX ist kann man nicht mehr schreiben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... nur mal so auf die Schnelle ... so in etwa sähe mein Vorschlag aus :
Code:
FUNCTION_BLOCK FB 100
TITLE =FIFO
VERSION : 0.1

VAR_INPUT
  Reset : BOOL ; 
  Write_Into : BOOL ; 
  Read_From : BOOL ; 
  Write_Val : INT ; 
END_VAR
VAR_OUTPUT
  Error : BOOL ; 
  Reset_OK : BOOL ; 
  Write_OK : BOOL ; 
  Read_OK : BOOL ; 
  Read_Val : INT ; 
END_VAR
VAR
  int_Read_OK : BOOL ; 
  int_Write_OK : BOOL ; 
  Read_Index : INT ; 
  Write_Index : INT ; 
  Daten_Puffer : ARRAY  [1 .. 100 ] OF INT ; 
END_VAR
VAR_TEMP
  hPointer : DWORD ; 
END_VAR

BEGIN
NETWORK
TITLE = 
      SET   ; 
      R     #Error; 
NETWORK
TITLE =Reset
      U     #Reset; 
      SPBN  nRes; 
      L     0; 
      T     #Read_Index; 
      T     #Write_Index; 
nRes: U     #Reset; 
      =     #Reset_OK; 
NETWORK
TITLE =Wert eintragen
      U     #Write_Into; 
      UN    #int_Write_OK; 
      SPBN  nWri; 
// Zeiger erhöhen
      L     #Write_Index; 
      L     1; 
      +I    ; 
      T     #Write_Index; 
// Zeiger > max ?
      L     #Write_Index; 
      L     100; 
      <I    ; 
      SPB   Wri1; 
      L     1; 
      T     #Write_Index; 
Wri1: L     #Write_Index; 
      L     #Read_Index; 
      >=I   ; 
      SPB   Err; 
      L     #Write_Index; 
      L     1; 
      -I    ; 
      SLD   4; 
      L     P##Daten_Puffer; 
      +D    ; 
      T     #hPointer; 
      L     #Write_Val; 
      T     DIW [#hPointer]; 
nWri: U     #Write_Into; 
      =     #int_Write_OK; 
      =     #Write_OK; 
NETWORK
TITLE =Wert auslesen
      U     #Read_From; 
      UN    #int_Read_OK; 
      SPBN  nRea; 
// Zeiger erhöhen
      L     #Read_Index; 
      L     1; 
      +I    ; 
      T     #Read_Index; 
// Zeiger > max ?
      L     #Read_Index; 
      L     100; 
      <I    ; 
      SPB   Rea1; 
      L     1; 
      T     #Read_Index; 
Rea1: L     #Read_Index; 
      L     #Write_Index; 
      >=I   ; 
      SPB   Err; 
      L     #Read_Index; 
      L     1; 
      -I    ; 
      SLD   4; 
      L     P##Daten_Puffer; 
      +D    ; 
      T     #hPointer; 
      L     DIW [#hPointer]; 
      T     #Read_Val; 
nRea: U     #Read_From; 
      =     #int_Read_OK; 
      =     #Read_OK; 
      BEA   ; 
NETWORK
TITLE =---
Err:  SET   ; 
      S     #Error; 
END_FUNCTION_BLOCK

Der dargestellt Code ist NICHT getestet und könnte noch tolle Fehler beinhalten ...

Gruß
LL
 
Ich habe den Wunsch nach AWL zwar gelesen... aber hier mal eine SCL Lösung. Ich denke das der Ablauf wie ich ihn mir vorstelle zu erkennen ist.

Code:
FUNCTION_BLOCK FB50
VAR_INPUT
  // Eingangs Variablen
  xWrite       :BOOL;   (* Es wird ein Wert in dem FIFO-Speicher geschrieben  *)
  XRead        :BOOL;   (* Es wird ein Wert aus dem FIFO-Speicher gelesen     *)
  wStore       :WORD;   (* Wert der in dem FIFO-Speicher abgelegt werden soll *)
  xReset       :BOOL;   (* Der FIFO-Speicher wird Resetet  *)
END_VAR

VAR_OUTPUT
  // Ausgangs Variablen
  wValue       :WORD;  (* Wert, der aus dem FIFO-Speicher gelsesen wurde      *) 
  iCount       :INT;   (* Anzahl der gespeicherten Werte                      *)
  xOverflow    :BOOL;  (* FIFO-Überlauf *)
  xUnderflow   :BOOL;  (* FIFO-Unterlauf *)
END_VAR

VAR
  // statische Variablen
  myData        :ARRAY[0..199] OF WORD; (* Der FIFO-Speicher                  *)
  myWriteIndex  :INT:=0; (* Index zum Schreiben der neuen Daten               *)
  myReadIndex   :INT:=0; (* Index zum Lesen der gespeicherten Daten           *)
  myFPWrite     :BOOL;   (* Flanken erkennung zum schreiben von Daten         *)
  myFPRead      :BOOL;   (* Flanken erkennung zum lesen von Daten             *)
END_VAR
  // Anweisungsteil  
  IF xWrite AND NOT myFPWrite THEN           (* Flankenerkennung neue Daten schreiben *)
    IF iCount < 199 THEN                     (* Ist Platz im FIFO-Speicher ? *)
      myData[myWriteIndex] := wStore;        (* Speichern des neuen Werts *)
      myWriteIndex := myWriteIndex + 1;      (* "Zeiger" auf die nächste Speicherzelle schieben *)
      iCount := iCount + 1;                  (* Anzahl der gespeicherten Werte erhöhen *)
      IF myWriteIndex > 199 THEN             (* "Zeiger" überlauf wieder bei 0 beginnen *)
        myWriteIndex := 0;
      END_IF;    
    ELSE
      xOverflow := TRUE;                     (* FIFO-Überlauf melden *)
    END_IF;
  END_IF;
  myFPWrite := xWrite;                       (* Speicher für die Flanken erkennung *)
  IF xOverflow THEN                          (* FIFO-Überlauf Meldung rücksetzen *)
    xOverflow := xWrite;                 
  END_IF;
  
  
  IF xRead AND NOT myFPRead THEN             (* Flankenerkennung Daten lesen *)      
    IF iCount > 0 THEN                       (* Sind Daten im FIFO-Speicher ? *)
      wValue := myData[myReadIndex];         (* Wert aus Speicher an den Ausgang legen *)
      myReadIndex := myReadIndex + 1;        (* "Zeiger" auf die nächste Speicherzelle schieben *)
      iCount := iCount - 1;                  (* Anzahl der gespeicherten Werte reduzieren *)
      IF myReadIndex > 199 THEN              (* "Zeiger" überlauf wieder bei 0 beginnen *)
        myReadIndex := 0;
      END_IF;      
    ELSE
      wValue := 0;                           (* Wenn keine Daten vorhanden immer 0 ausgeben *)
      xUnderflow := TRUE;                    (* FIFO-Unterlauf melden *)
    END_IF;
  END_IF;    
  myFPRead   := xRead;                       (* Speicher für die Flanken erkennung *)
  IF xUnderflow THEN                         (* FIFO-Unterlauf Meldung rücksetzen *)
    xUnderflow := xRead;                 
  END_IF;
 
  
  IF xReset THEN                             (* FIFO Reseten *)
    myWriteIndex         := 0;
    myReadIndex          := 0;
    iCount               := 0;
  END_IF;
 
END_FUNCTION_BLOCK
PS: Auch ungetestet, bin aber zuversichtlich das der Code funktioniert.
 
Zuletzt bearbeitet:
@Zotos:
Du bist ja böse ... mit SCL wäre mir die Sache auch sehr viel leichter gefallen ... Kunststück, ist ja von der Aufgabenstellung her auch eigentlich prädestiniert dafür ...

Gruß
LL
 
Zurück
Oben