Bool-Array in Byte-Array

Techniker

Level-2
Beiträge
84
Reaktionspunkte
16
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich hab ein kleines Problem mit einem Bool-Array. Ich wollte die Werte
eines Bool-Arrays in ein Byte-Array transferieren. Da aber ein Bool intern
den Speicher von der Größe eines Bytes belegt, ist das etwas schwieriger.

z.B.: Testbool ARRAY[1..80] of BOOL
Testbyte ARRAY[1..10] of BYTE

Von Hand zu Fuss ist das kein Problem:

Testbyte[9].7:= Testbool[72];

aber das ganze sollte natürlich automatisch ablaufen in einem FB, wo ich
nur noch Quelle, Ziel und Anzahl eingebe.

Programmiersoftware:XSoft 2.3.3 (Codesys)

Für ein paar Denkanstösse bin ich sehr Dankbar.


Schöne Grüße
 
z.B.: Testbool ARRAY[1..80] of BOOL
Testbyte ARRAY[1..10] of BYTE

Von Hand zu Fuss ist das kein Problem:

Testbyte[9].7:= Testbool[72];


So vielleicht ? :


VAR i: INT;
Testbyte: ARRAY[1..80] OF BYTE;
Testbool: ARRAY[1..80] OF BOOL;
END_VAR


FOR i := 1 TO 80 DO
Testbyte := BOOL_TO_BYTE(Testbool);
END_FOR
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zitat:
VAR i: INT;
Testbyte: ARRAY[1..80] OF BYTE;
Testbool: ARRAY[1..80] OF BOOL;
END_VAR


FOR i := 1 TO 80 DO
Testbyte := BOOL_TO_BYTE(Testbool);
END_FOR


Nein, so bestimmt nicht.
So belegt ja jedes einzelne Bit ein ganzes Byte!
Das wäre nicht Sinn der Sache.

Hier mal ein kleiner Ausschnitt aus meinen Überlegungen:
Code:
VAR_INPUT
	pBool_array		: DWORD;		(* Adresse des Bool-Arrays *)
	pByte_array		: DWORD;		(* Adresse des Byte-Arrays *)
	iwOffset_Bool		: UINT;			(* Ab diesem Element soll kopiert werden *)
	iwOffset_Byte		: UINT;
	iwBool_Anzahl	: UINT;			(* Anzahl der Elemente, die kopiert werden sollen *)
END_VAR
VAR_OUTPUT
END_VAR
VAR
	pt_Bool		: POINTER TO  BOOL;
	pt_Byte		: POINTER TO  BYTE;
	index			: UINT;
	Hilfsbit				: BOOL;
	Hilfsbyte			: BYTE;
END_VAR



(* Adresse des Bool- und Byte-Array an Pointer übergeben *)
pt_Bool:= pBool_array + iwOffset_Bool;
pt_Byte:= pByte_array + iwOffset_Byte;


Hilfsbyte:= pt_Byte^;

(* Elemente des Bool-Array abfragen (nur soviele wie in der Anzahl steht, vom Offset an *)
	FOR index:= iwOffset_Bool TO iwOffset_Bool + iwBool_Anzahl - 1  DO

		Hilfsbit:= pt_Bool^;
(*		Hilfsbyte:= pt_Byte^; *)

		(* Wert an die richtige Bitposition im Byte schieben und mit dem alten Bytewert verknüpfen *)
	IF Hilfsbit THEN
		Hilfsbyte:= Hilfsbyte OR SHL(1, index - iwOffset_Bool MOD 8);
	ELSE
		Hilfsbyte:= Hilfsbyte AND NOT SHL(1,index - iwOffset_Bool MOD 8);
	END_IF;
	(* Neue Adresse berechnen (Pointermanipulation)*)
	pt_Bool:= pt_Bool + 1;
	IF (index  MOD 8) = 0 THEN
		IF index - iwOffset_Bool > 0 THEN
			pt_Byte:= pt_Byte + 1;
		END_IF
	END_IF;
END_FOR;

Das Auswerten der einzelnen Bits und "packen" in ein Byte funktioniert
prima. Nur das Beschreiben des Zieles ist ein Problem. Der Baustein
soll universal einsetzbar sein, und Somit keine festen Array-Grenzen als
Ein-oder Ausgänge haben. Quelle und Ziel sollen über Pointer adressiert
werden.
 
ohne mir deinen code jetzt genauer anzusehen.

du kannst das bool array doch ohne problem byte,word,dword weise ansprechen.

nehmen wir an dein array beginnt bei dbx0.0
wenn du nun schreibst
L DBB 0
lädst du die ersten 8 bit des arrays.
 

Nun ja, die gewünschte Variante birgt auch Risiken (das in undefinierten Bereichen geschrieben wird).

Hier noch eine andere Variante mit statischen Array-Grenzen, die den Zweck ansonsten erfüllt:


(* ======= Variablendeklaration ======== *)

VAR i,j: INT;
b: BYTE;
TestByte: ARRAY[1..10] OF BYTE;
TestBool: ARRAY[1..80] OF BOOL;

Muster: BYTE;
END_VAR




(* ======= Programm ======== *)

FOR i := 0 TO 9 DO (* Anzahl Bytes = 10 *)
b := 0;
FOR j := 0 TO 7 DO (* Anzahl Bits je Byte = 8 *)
Muster := INT_TO_BYTE(SHL(1, j));
IF Testbool[(i * 8) + j + 1] THEN
b := b OR Muster;
END_IF
END_FOR (* j *)
Testbyte[i + 1] := b;
END_FOR (* i *)
 
Code:
(* ======= Variablendeklaration ======== *)

VAR i,j: INT;
b: BYTE;
TestByte: ARRAY[1..10] OF BYTE;
TestBool: ARRAY[1..80] OF BOOL;

Muster: BYTE;
END_VAR




(* ======= Programm ======== *)

FOR i := 0 TO 9 DO (* Anzahl Bytes = 10 *)
b := 0;
FOR j := 0 TO 7 DO (* Anzahl Bits je Byte = 8 *)
Muster := INT_TO_BYTE(SHL(1, j));
IF Testbool[(i * 8) + j + 1] THEN
b := b OR Muster;
else
b := b and not Muster; <==
END_IF
END_FOR (* j *)
Testbyte[i + 1] := b;
END_FOR (* i *)


Das ist soweit ok. Das Rücksetzen des Bit hab ich noch eingefügt.
Aber so bin ich natürlich nicht flexibel. Ich hab 2 verschieden große
Array's und die sollen dann ab einem bestimmten Offset des Byte-Array's
eingefügt werden.

Mfg
 
Zuviel Werbung?
-> Hier kostenlos registrieren

Das rücksetzen ist nicht nötig, da b bei jedem Neustart der inneren (FOR j :=) - Schleife auf 0 gesetzt wird!

Wenn man statt b := 0 geschrieben hätte: b := Testbyte[i + 1];
müsste man tatsächlich diesen AND NOT - Part einfügen.
 
Gibts da keine fertige Library-Funktion dafür??

Zumindest bei B&R gibts sowas schon fertig.....
 
Zurück
Oben