Forum: Mikrocontroller und Digitale Elektronik Zerteilen von Variablen, bitweises zerlegen


von Uwe S. (tribe589)


Lesenswert?

Hallo liebe Mikrocontroller Gemeinde,

ich habe ein kleines Projekt bei dem ich Nachrichten über den Can 
geschickt bekommen und empfange Sie mit dem dsPIC4011.
Jetzt enthalten die CAN Botschaften:
z.B. ID 600 Nachricht 8 Byte Lang.
In dieser 8Byte langen Nachricht sind aber mehrere Informationen 
enthalten.
z.B. sind die ersten 3 Bit der 64Bit langen Nachricht die eine 
Information.
Die einzelnen Informationen möchte ich einzelnt auf Variablen speichern.
z.B.
led1_status = "ersten drei bits";
led2_status = "nächsten drei bits";

Nur ich weiß nicht wie ich die 64bit lange Nachricht so zerlege, dass 
z.B. die Variable led1_status nur 101 enthält, falls das die ersten drei 
bits waren.
Gibt es dafür Funktionen von Teile der 64bit Nachricht "abzuschneiden"?
Wie würdet ihr vorgehen?

Man könnte ja davon ausgehen das ich die Nachricht auf eine Variable 
geschrieben habe:

nachricht = 0x1223544291587456;
wie bekomme ich jetzt die ersten drei bits auf die variable led1_status?

von Peter II (Gast)


Lesenswert?

Uwe S. schrieb:
> nachricht = 0x1223544291587456;
> wie bekomme ich jetzt die ersten drei bits auf die variable led1_status?

http://www.mikrocontroller.net/articles/Bitmanipulation

nachricht = 0x1223544291587456;

uint8_t t = nachricht & 3;

von Peter II (Gast)


Lesenswert?

> wie bekomme ich jetzt die ersten drei bits auf die variable led1_status?
oh die erste drei bits.


nachricht = 0x1223544291587456;

uint8_t t = nachricht >> 61;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter II schrieb:
> uint8_t t = nachricht & 3;

Das sind die letzten zwei Bits.

Hilfreich ist das jetzt nicht gerade.

von Peter II (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Hilfreich ist das jetzt nicht gerade.

wurde schon korrigiert.

von E. T. (jadeaffenjaeger)


Lesenswert?

grundsätzlich, also in Pseudocode und ohne unterschidliche 
Variablentypen:

led_status = nachricht & 0x07

Erklärung: Du nimmst die Nachricht und wendest ein logisches UND an, 
zusammen mit einer Zahl, bei der nur die unteren 3 Bits gesetzt sind. 
Dadurch bleiben die unteren 3 Bits gleich, der Rest wird zu Null.

von ?!? (Gast)


Lesenswert?

E. T. schrieb:
> grundsätzlich, also in Pseudocode und ohne unterschidliche
> Variablentypen:
>
> led_status = nachricht & 0x07
>
> Erklärung: Du nimmst die Nachricht und wendest ein logisches UND an,
> zusammen mit einer Zahl, bei der nur die unteren 3 Bits gesetzt sind.
> Dadurch bleiben die unteren 3 Bits gleich, der Rest wird zu Null.

Das sind wieder die letzten drei Bits. Wenn er aber die ersten drei 
haben möchte, dann ist die (zweite) Lösung von Peter II richtig.
Prinzipiell gilt aber: die benötigten Bits maskieren und bei Bedarf nach 
unten schieben.

von E. T. (jadeaffenjaeger)


Lesenswert?

Stimmt. Hatte ich missverstanden.

von Sebastian W. (wangnick)


Lesenswert?

Uwe S. schrieb:
> nachricht = 0x1223544291587456;
> wie bekomme ich jetzt die ersten drei bits auf die variable led1_status?

Oder du benutzt ein https://de.wikipedia.org/wiki/Bitfeld.

LG, Sebastian

von Robert L. (lrlr)


Lesenswert?

es gibt eine offizielle Definition was bei einem Byte/Word/usw.
das "erste" und das "letzte" bit ist?

von Ulrich F. (Gast)


Lesenswert?

So, oder so ähnlich, geht nicht?
struct bitmap
 unsigned int led1 : 3;
 unsigned int led2 : 3;
 unsigned long rest : 56;
};
Bin ich zu Arduino verwöhnt?
;-)

von Frank (Gast)


Lesenswert?

Ulrich F. schrieb:
> Bin ich zu Arduino verwöhnt?
> ;-)

Das ist normales C! Bitfelder wurden ja schon genannt und werden auch 
oft verwendet. Oft auch noch mit einer Union überlagert.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Robert L. schrieb:
> es gibt eine offizielle Definition was bei einem Byte/Word/usw.
> das "erste" und das "letzte" bit ist?

Ist bei der Zahl 1234 die eins die erste oder letzte Ziffer?

Üblich ist es, die 1 (also die höherwertigste Stelle) als erste, und die 
4 (also die niederwertigste Stelle) als letzte zu bezeichnen, was an der 
Reihenfolge der Darstellung liegt; wir schreiben (und lesen) nunmal von 
links nach rechts, und vom deutschen einer/zehner-Zahlendreher 
abgesehen, sprechen wir Zahlen auch soherum aus.

Das ist eben eintausendzweihundertvierunddreißig ... und nicht 
vierunddreißigzweihunderteintausend.

Werden Bits gezielt numeriert, geschieht das aber andersherum, da ist 
Bit 0 das niederwertigste und Bit 7 (15, 31, 63) das höchstwertigste.


Mit anderen Worten: Es kommt immer auf die sprachliche Präzision und den 
Kontext an.

von Ulrich F. (Gast)


Lesenswert?

Frank schrieb:
> Das ist normales C!
Ich weiß....

Frank schrieb:
> Bitfelder wurden ja schon genannt  .......
Die Antworten haben sich überschnitten.

Frank schrieb:
> Oft auch noch mit einer Union überlagert.
Ja.
Zahlreich im Einsatz, und hier auch vermutlich sinnvoll.

Frank schrieb:
> Bin ich zu Arduino verwöhnt?
Das war eher ideologisch gemeint, nicht so sehr technisch.

Ich finde das schieben doof. Ins besondere mit verstreuten Konstanten im 
Code recht unübersichtlich und damit fehlerträchtig.
Von mir aus darf der Compiler das gerne im Hintergrund erledigen.

von Volker S. (vloki)


Lesenswert?

Frank schrieb:
> Bitfelder wurden ja schon genannt und werden auch
> oft verwendet. Oft auch noch mit einer Union überlagert.

Das ganze kommt mir irgendwie sehr bekannt vor ->
Beitrag "Struktur für Programmierung des dsPIC30F Familie Daten auslesen und richtig abspeichern"

von ?!? (Gast)


Lesenswert?

Ulrich F. schrieb:
> Ich finde das schieben doof. Ins besondere mit verstreuten Konstanten im
> Code recht unübersichtlich und damit fehlerträchtig.

Ja, wenn du es wirklich mit numerischen Konstanten machst, stimmt das. 
Aber man kann sich ja die Konstanten mit Namen definieren, z.B.
1
#define LED12  3
2
led_status = nachricht >> LED12 & 0x07

von Karl (Gast)


Lesenswert?

Ulrich F. schrieb:
> Ich finde das schieben doof. Ins besondere mit verstreuten Konstanten im
> Code recht unübersichtlich und damit fehlerträchtig.
> Von mir aus darf der Compiler das gerne im Hintergrund erledigen.

Dann kapsel doch jeweils die Auswertung in einzelnen Funktionen oder du 
machst es wie beim Arduino objektorientiert in C++.

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.