TwinCat 2.11 Einzelne Bits in Variablen (Array) ansprechen

Beren

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


ich habe folgendes Problem:

Ich möchte eine Funktion schreiben, die als Eingangsparameter

VAR_INPUT
DigitArray : ARRAY[0..63] OF BOOL;
END_VAR

erhält und als Rückgabewert

FUNCTION iba_Digitalsignale : ARRAY [0..3] OF UINT

ausgibt.

In der Funktion soll
Bit 0 des "Array of Bool" dem Bit 0 des Rückgabewerts zugewiesen werden
Bit 1 des "Array of Bool" dem Bit 1 des Rückgabewerts zugewiesen werden
...
Bit 63 des "Array of Bool" dem Bit 63 des Rückgabewerts zugewiesen werden

Wenn ich eine Bitweise Zuweisung programmiere bekommen ich den Fehler

"Unzulässiger Datentyp 'ARRAY[0..3] OF UINT' für direkten Bitzugriff. "

Ich darf also nicht die einzelnen Bits adressieren. Wie geht man bei soetwas vor?

Vielen Dank im voraus!
 
Okay, ich glaub ich habs. So in der Richtung müsste es klappen (Code am Pad getippt). Ich probier das morgen mal aus.


Code:
DigBit:=0;
For word:=0 To 3
   For bit:=0 To 15
      iba_Digitalsignale[word].bit:=DigitArray[digBit];
      digBit:=digBit+1;
   Next bit
Next word
 
Okay, ich glaub ich habs. So in der Richtung müsste es klappen (Code am Pad getippt). Ich probier das morgen mal aus.


Code:
DigBit:=0;
For word:=0 To 3
   For bit:=0 To 15
      iba_Digitalsignale[word].bit:=DigitArray[digBit];
      digBit:=digBit+1;
   Next bit
Next word

Das wird nicht funktionieren. Der Bit-Index muss eine Konstante sein.

In der TcSystem.Lib gibt es die Funktion CSETBIT32 mit der du Arbeiten könntest.

z.B.
Code:
FOR word := 0 TO 3 DO
  FOR bit := 0 TO 15 DO
    iba_Digitalsignale[word] := DWORD_TO_UINT(CSETBIT32( UINT_TO_DWORD(iba_Digitalsignale[word]), bit, DigitArray[digBit]));
    digBit := digBit +1;
  END_FOR
END_FOR

Man könnte sich auch selber was basteln

Code:
FOR word := 0 TO 3 DO
  iba_Digitalsignale[word] := 0;
  FOR bit := 0 TO 15 DO
    iba_Digitalsignale[word] :=SHL(UINT_TO_WORD(iba_Digitalesignale[word], 1); 

    IF DigitArray[digBit] THEN
      iba_Digitalsignale[word] := iba_Digitalsignale[word] + 1;
    END_IF

    digBit := digBit +1;
  END_FOR
END_FOR

Ohne Gewähr
 
Zuletzt bearbeitet:
Der Hinweis mit dem SHL war gut. Ich probiers mal so:

Code:
FUNCTION iba_64BoolTo4Uint : ARRAY[0..3] OF UINT
VAR_INPUT
    DigitArray : ARRAY[0..63] OF BOOL;
END_VAR
VAR
    signalCount: INT;
    wordCount: INT;
    bitCount: INT;
END_VAR


signalCount:=0;
FOR wordCount:=0 TO 3 DO
	FOR bitCount:=0 TO 15 DO
		IF DigitArray[signalCount] THEN
			iba_64BoolTo4Uint[wordCount].0:=TRUE;
		ELSE
			iba_64BoolTo4Uint[wordCount].0:=FALSE;
		END_IF;
		iba_64BoolTo4Uint[wordCount]:=SHL(UINT_TO_WORD(iba_64BoolTo4Uint[wordCount]),1);
		signalCount:=signalCount+1;
	END_FOR;
END_FOR;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Dann stehen in den einzelnen UINTS des Funktionsergebnisses die Bits aber in der umgekehrten Reihenfolge, also BOOL[0] in BITS[0].15, BOOL[15] in BITS[0].0 usw.
Also besser Bit 15 schreiben und rechts schieben. Dabei allerdings erst schieben, dann schreiben, sonst verschwindet das erste Bit der bitCount-Schleife im Datenorkus.
Code:
FUNCTION iba_64BoolTo4Uint : ARRAY[0..3] OF UINT
VAR_INPUT
    DigitArray : ARRAY[0..63] OF BOOL;
END_VAR
VAR
    signalCount: INT;
    wordCount: INT;
    bitCount: INT;
END_VAR


signalCount:=0;
FOR wordCount:=0 TO 3 DO
    FOR bitCount:=0 TO 15 DO
        iba_64BoolTo4Uint[wordCount]:=SHR(UINT_TO_WORD(iba_64BoolTo4Uint[wordCount]),1);
        IF DigitArray[signalCount] THEN
            iba_64BoolTo4Uint[wordCount].15:=TRUE;
        ELSE
            iba_64BoolTo4Uint[wordCount].15:=FALSE;
        END_IF;
(* 
oder einfacher
iba_64BoolTo4Uint[wordCount].15:=DigitArray[signalCount];
*)
       signalCount:=signalCount+1;
     END_FOR;
END_FOR;
 
Zuletzt bearbeitet:
Danke, aber auch noch nicht ganz korrekt. Hatte heute Inbetriebnahme und hab die Funktion getestet. ROR mit Bit Operator .0 war die Lösung. Kann die Endfassung nachher nochmal posten.
 
Nabend!

Hier der für mich funktionierende Code. Vielen Dank nochmal an alle!

Code:
FUNCTION iba_256BoolTo16Uint : ARRAY[0..15] OF UINT
VAR_INPUT
                DigitalSignal : ARRAY[0..255] OF BOOL;
END_VAR
VAR
                signalCount:INT;
                wordCount:INT;
                bitCount:INT;
END_VAR
 
signalCount:=0;
FOR wordCount:=0 TO 15 DO
                FOR bitCount:=0 TO 15 DO
                               iba_256BoolTo16Uint[wordCount].15:=DigitalSignal[signalCount];                              
                               iba_256BoolTo16Uint[wordCount]:=ROL(UINT_TO_WORD(iba_256BoolTo16Uint[wordCount]),1);
                               signalCount:=signalCount+1;
                END_FOR;
END_FOR;
 
(* Wenn Bitreihenfolge in iba nicht passt, ROR und Bitoperator 0 !!! *)
 
Zuletzt bearbeitet:
Zurück
Oben