TIA SCL Baustein Input: byte Output: any (einzelne Bits)

kliebisch.m

Level-1
Beiträge
120
Reaktionspunkte
5
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich brauche einen Konvertierbaustein:

Input: Byte (0-256)
Output: any (einzelne Bits in einem Datenbaustein)

Output ist ein Datenbaustein mit 256 Bool's.
Und ich möchte einen Bit je nach Zahl am Input im Datenbaustein auf 1 haben.

Gibt es hierfür bereits etwas? Ober ist das schnell in SCL zu machen?
Ich Glaube sowas nennt sich 1-aus-n-Decoder

Herzlichen Dank
 
Zuletzt bearbeitet:
Das habe ich nicht verstanden ... beschreib doch mal an Hand von 1 - 2 Zuweisungsbeispielen, welche Zahl am Eingang was im Ziel-DB ändern soll ...

Gruß
Larry
 
Was fertiges gibts wohl nicht. Aber ist ja doch recht simpel zu machen. zu beginn des Bausteins die Bits alle auf null setzen.
Dann indextiert das entsprechende Bit schreiben. Das ginge einfacher wenn du statt ANY ein Array of Bool anhängen könntest.
Ansonsten mapst du mithilfe dem Any und Blockmove ein Array of bool im Temp auf den DB.
Beispiele gibts genug im Forum.

mfG René
 
Dann würde ich es so machen, dass du deinem Baustein diese Nummer (von mir aus als Byte - ich würde INT nehmen) übergibst und die Nummer des Ziel-DB's auch als Betrag (INT).
Im Baustein bastelst du dir dann die Ziel-Adresse zusammen (DB-Nummer hast du ja schon, Byte-Nummer wäre dann Index/8 und die Bit-Nummer wäre dann (Index mod 8)) und setzt diese Adresse dann.
Alternativ könntest du noch einen weiteren IN-Parameter für den zu erzeugenden Zustand übergeben (also TRUE für setzen und FALSE für rücksetzen).

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In TIA gibt es eine Anweisung, die (Überraschung ;)) DECO heißt. Die arbeitet zwar nur bis Bitnummer 31, die könnte man sich aber hinpfriemeln (sprich: zusätzlich ausrechnen, in welchem Byte/Word/DWord das Bit gesetzt werden muß). Geht aber nicht mit optimierten Speicherbereichen.

Jetzt kommt es wie immer darauf an, was für eine CPU Du hast und ob der DB "optimiert" ist und wie der DB deklariert ist.
Außerdem ist Deine Aufgabenstellung nicht eindeutig - was soll aus den anderen 255 Bits werden? Sollen die auf 0 gesetzt werden oder den bisherigen Wert unverändert beibehalten?

So funktioniert es mit jeder CPU und jedem Speicher, der als "ARRAY[0..255] OF BOOL" deklariert ist:
Code:
//gesamtes Bit-Array löschen
FOR #i := 0 TO 255 DO
  BoolArray[#i] := 0;
END_FOR;

//das angegebene Bit im Array setzen
BoolArray[#index] := 1;

Harald
 
Und wenn auf ner 1500 bzw 1200 laufen sollte, könnte mans vollsymbolisch ohne temporäres Array machen.
Hab da mal was gebastelt. Da ich nebenbei noch Ferngesehen habe musst du es selber testen. Sollte aber so funktionieren.
Code:
FUNCTION "1outofN" : Void{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      anyDB : Any;
      Auswahl : Byte;
      Enable : Bool;
   END_VAR


   VAR_TEMP 
      anyDB_temp : Any;
      panyDB AT anyDB_temp : "ANY_POINTER";
      index : Int;
   END_VAR




BEGIN
	#anyDB_temp := #anyDB;
	#panyDB.Bereichstyp := 16#84;
	
	FOR #index := 0 TO #panyDB.Anzahl_Werte * 8 DO
	    POKE_BOOL(area:=#panyDB.Bereichstyp,
	              dbNumber:=#panyDB.DB_Nr,
	              byteOffset:=#index / 8 + DWORD_TO_INT(SHR(IN := SHL(IN := #panyDB.Startadresse,N := 13), N := 16)),
	              bitOffset:=#index MOD 8 + DWORD_TO_INT(SHR(IN := SHL(IN := #panyDB.Startadresse,N := 29), N := 29)),
	              value:=0);
	END_FOR;
	
	IF #Enable THEN
	    POKE_BOOL(area := #panyDB.Bereichstyp,
	              dbNumber := #panyDB.DB_Nr,
	              byteOffset := BYTE_TO_INT(#Auswahl) / 8 + DWORD_TO_INT(SHR(IN := SHL(IN := #panyDB.Startadresse, N := 13), N := 16)),
	                bitOffset := BYTE_TO_INT(#Auswahl) MOD 8 + DWORD_TO_INT(SHR(IN := SHL(IN := #panyDB.Startadresse, N := 29), N := 29)),
	              value := 1);
	END_IF;
	
END_FUNCTION

Aufruf z.B. so.
Code:
// die Byteanzahl gibt an bis wohin die Bits im DB gelöscht werden sollen.
// Hier also von dbx0.0 bis dbx 5.0
// wenn man von dbx 0.2 anfängt wird dann auch bis dbx 5.2 gelöscht
// da Bitadresse in Auswahl auch 0 sein kann muss man ja auch angeben wenn man alles auf null setzen will
// ENABLE = 0 setzt alles im bereich auf null


"1outofN"(anyDB := p#db5.dbx0.0 BYte 5, 
          Auswahl := "testbyte",
          Enable:="testbool");


Anypointer UDT
Code:
TYPE "ANY_POINTER"
VERSION : 0.1
   STRUCT
      SyntaxID : Byte;
      Bereichstyp : Byte;
      Anzahl_Werte : UInt;
      DB_Nr : UInt;
      Startadresse : DWord;
   END_STRUCT;


END_TYPE
 
Zurück
Oben