Forum: Mikrocontroller und Digitale Elektronik Bitmanipulation in C# Programm (Visual Studio)


von Stefan S. (sschultewolter)


Lesenswert?

Hallo, ich habe das Problem in einem C# Programm, dass ich einzelne Bits 
nicht löschen kann. Er merkert, dass der Konstantenwert "-4" nicht in 
"byte" konvertiert werden kann. Problem wird hier sein, dass er mit 
32Bit arbeiten will. Das möchte ich aber nicht ;) Die Variable habe ich 
als Byte (uint8_t).
1
 
2
       byte cmd; // global
3
        private void b_on_Click(object sender, EventArgs e)
4
        {
5
            cmd &= ~(0x03); // Loesche die ersten beiden Bits
6
            cmd |= (0x02);  // Setze das zweite Bit
7
        }
8
9
        private void b_pir_Click(object sender, EventArgs e)
10
        {
11
            cmd &= ~(0x03); // Loesche die ersten beiden Bits
12
            cmd |= (0x03);  // Setze die ersten beiden Bits
13
        }
14
15
        private void b_off_Click(object sender, EventArgs e)
16
        {
17
            cmd &= ~(0x03); // Loesche die ersten beiden Bits
18
            cmd |= (0x01);  // Setze das erste Bit
19
        }

Kann man das ganze irgendwie casten auf 8Bit?

von Mein grosses V. (vorbild)


Lesenswert?

Stefan S. schrieb:
> Er merkert, dass der Konstantenwert "-4" nicht in
> "byte" konvertiert werden kann.

Natürlich meckert er. Byte ist unsigned und -4 ist signed.
Das ist doch kein C, wo man alles überall reinschreiben kann.

Warum machst du das nicht in int? Auf dem Niveau Speicher sparen beim PC 
ist doch geradezu lächerlich.

von Stefan S. (sschultewolter)


Lesenswert?

Ja, der Speicher ist für das Tool uninteressant. Also gibt es so keine 
direkte Möglichkeit? Ich hab das cmd nun einfach bereits selber als int 
deklariert. Nun kann ich das Bitschupsen machen. Aber die anderen 24 Bit 
sind absolut über -.-

von W.A. (Gast)


Lesenswert?

Stefan S. schrieb:
> Aber die anderen 24 Bit sind absolut über -.-

Bei einem 32-Bit Speicherzugriff gibt es aber kein Geld zurück, wenn man 
24 davon nicht benutzt.

von Mein grosses V. (vorbild)


Lesenswert?

Stefan S. schrieb:
> Aber die anderen 24 Bit
> sind absolut über

Es sind sogar 30.

Stefan S. schrieb:
> cmd &= ~(0x03);

Du benutzt 2 Bit. Selbst bei einem Attiny13 würdest du dir keine 
Gedanken über die übrigbleibenden 6 Bit machen.

Also lass es bei 32 Bit. Das tut dem Gigabyte-Monster nicht weh. Wenn 
die Variablen aus Performance-Gründen( Stichwort Address Alignment) 
nicht ohnehin grundsätzlich in 32 oder sogar 64 Bit gespeichert werden.

: Bearbeitet durch User
von derElf (Gast)


Lesenswert?

Stefan S. schrieb:
> byte cmd; // global
>         private void b_on_Click(object sender, EventArgs e)
>         {
>             cmd &= ~(0x03); // Loesche die ersten beiden Bits
>             cmd |= (0x02);  // Setze das zweite Bit
>         }
>
>         private void b_pir_Click(object sender, EventArgs e)
>         {
>             cmd &= ~(0x03); // Loesche die ersten beiden Bits
>             cmd |= (0x03);  // Setze die ersten beiden Bits
>         }
>
>         private void b_off_Click(object sender, EventArgs e)
>         {
>             cmd &= ~(0x03); // Loesche die ersten beiden Bits
>             cmd |= (0x01);  // Setze das erste Bit
>         }

wenn mich meine erinnerung nicht täuscht, kann man das auch casten:
1
private void b_on_Click(object sender, EventArgs e)
2
         {
3
             cmd &= (byte) ~(0x03); // Loesche die ersten beiden Bits
4
             cmd |= (byte) (0x02);  // Setze das zweite Bit
5
         }

von Roland .. (rowland)


Lesenswert?

Es funktioniert, indem man dem Compiler aus der Bitweise negierten Zahl 
in jedem Fall eine Positive macht:

byte cmd = 255;
cmd &= ~0x03 & 0xFF;

von Stefan S. (sschultewolter)


Lesenswert?

Hallo derElf,

nein casten kann man die unäre (~) Anweisung nicht. Bei dem | Operand 
wäre es hingegen möglich.

Hallo vorbild,
nicht ganz richtig mit den 30 Bits. Aber das konntest du auch nicht 
durch die Glaskugel erkennen ;) Ich nutze ein Byte für diverse 
Einstellungen. Also nicht nur für die 2 Bits.

Das ganze wird dann über die Serielle Schnittstelle an einen Tiny841 
gesendet, der daraus entsprechend WS2812B/APA102C ansteuert.

           dataToSend = String.Format("{0:x02},{1:x02},{2:x02},{3:x02}", 
(byte)cmd, red, green, blue);

Habe cmd hier mal sicherheitshalter auf Byte gecastet. Am Attinty soll 
nur ein String ankommen in Form von ff,ff,ff,ff\n

von derElf (Gast)


Lesenswert?

eigentlich wollte ich auch das Ergebnis der ~ Operation nach byte 
casten, das muss dann anscheinend Syntaxmäßig anders geschrieben werden.

von Grobi (Gast)


Lesenswert?

Also soweit mir bekannt ist das Ergebniss von bitwise and / or in c# 
immer ein int (Int32 - 4 byte) du kannst also im Prinzip schon genauso 
bits löschen und setzen wie in c musst nur auf das casten in den 
richtigen Ziel-Datentyp achten z.B.:
in c :cmd &= (byte) ~(0x03);
in c# : cmd = (byte)(cmd & ~0x03); natürlich nur wenn cmd als byte 
deklariert wurde.

von Grobi (Gast)


Lesenswert?

es sollte heißen:
in c: cmd &= ~(0x03);
in c# : cmd = (byte)(cmd & ~0x03); natürlich nur wenn cmd als byte
deklariert wurde.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.