Hallo Ich schreibe mir gerade eine Register und Bit definition für den PCA9635. nun um 1 Bit zu definieren sage ich #define test 1 Was mache ich aber wenn sich eine Variable über 2 bits ersterecken soll? Beispiel: Register XYZ A3 [7:6] /Bit 7 und 6 A2 [5:4] A1 [3:2] A0 [1:0] und A1 kann die Zustände 00, 01, 10 und 11 annehmen Im Quellcode möchte ich jetzt sagen können A0 = 1 // A0 = 01 A2 = 3 // A2 = 11 XYZ |= (1<A1)|(1<A3) // XYZ = 0b00110001 Ist dies irgendwie lösbar? Gruß Julien
ja dann machst du ja ein Bit-Shift Aber dadurch ist A1 etc. immer noch nicht definiert
auslesen wär dann so (zumindest in c++ gehts nicht anders) int a1= (xyz&0b00001100)>>2; //ob man das & braucht weis ich nicht
Zunächst ein Makro um aus einem gegebenem Bit die entsprechende Zahl zu machen: #define BIT(x) (1<<x) Nun kann man ein Bit SETZEN: a |= BIT(y); // setzt das Bit Nr y in der Variable a und natürlich auch löschen: a &= ~BIT(y); // löscht das Bit Nr y in der Variable a Hintergrund sind die Wahrheitstabellen der bitweisen Operationen,die sollte man sich mal näher anschauen. x y x UND Y x ODER y x XOR y 0 | 0 | 0 | 0 | 0 1 | 0 | 0 | 1 | 1 0 | 1 | 0 | 1 | 1 1 | 1 | 1 | 1 | 0 Zusammenfassend: Mit logisch ODER wird gesetzt,mit logisch UND wird gelöscht/maskiert und mit exklusiv-oder kann man Bits toggeln.
@ Ronny: Jaja die Wahrheitstabellen und setzten löschen ist mir ja alles klar := Ist ein alter Hut. Jedoch ist mein Kernproblem nicht das Setzen oder löschen. also XYZ |= variable a Mein Problem ist ja dass ich eben diese Variable a definieren möchte. und dies kann 4 Zustände annehmen. Diese zustände sind aber egal. Siehe Oben: A3 [7:6] / A3 definiert Bit 7 und 6 A2 [5:4] A1 [3:2] A0 [1:0] Ich will ja nahher nur noch sagen A3 ist ... und dann XYZ |= A3 // --> XYZ wird mit A3 oder verknüpft Die Schwierigkeit liegt NUR dabei A3 zu definieren!! Gruß
Nachdem ich im 2.ten Anlauf immer noch nicht kapiert habe, wo dein Problem liegt, rate ich einfach mal. Du bist auf der Suche von Bitfeldern: struct Irgendwas { unsigned char A0:2; unsigned char A1:2; unsigned char A2:2; unsigned char A3:2; } struct Irgendwas MyByte; MyByte.A3 = 3; // setzt die Bits 6 und 7 in MyByte Allerdings: Bitfelder werden oft glorreich überschätzt. Mit ein paar speziellen Makros ist man meist besser bedient. Vor allem deswegen weil man sich bewusst macht, dass zum setzen dieser Bits ein paar Bit-Operationen notwendig sind, die einem bei einem Bitfeld der Compiler 'under the hood' macht.
@Karl Heinz: Vielen Dank, genau das hab ich gesucht. :) In wie weit würde sich dies jetzt auch mit einem Makro lösen lassen? Wenn es elegantere Methoden gibt bin ich auch für diese offen :) Gruß Julien
#define SET_A3(x,y) ((x)&0b00111111)|(((y)&0b00000011)<<6)) unsigned char a; SET_A3( a, 3); setzt in a die A3 Bits auf 3 Wenn du die union Lösung nimmst, macht der Compiler auch nichts anderes als dieses UND/ODER Monster da oben.
Hallo ich habe mal versucht das an einem konkreten Beispiel umzusetzen. Leider Ohne erfolg LEDOUT0 ist ein register des PCA9635
1 | #define LEDOUT0 0x14 |
2 | |
3 | struct leds0_3 { |
4 | unsigned char LDR0:2; |
5 | unsigned char LDR1:2; |
6 | unsigned char LDR2:2; |
7 | unsigned char LDR3:2; |
8 | } |
9 | |
10 | struct leds0_3 LEDOUT0; |
vielleicht gibt es da noch einen Kniff den ich nicht kenne? Geht das überhaupt wenn ich später folgednes ausführen möchte? LEDOUT0.LDR2 = 2 wenn LEDOUT0 gar keinen Datentyp hat? Gruß
Wieso soll LEDOUT0 keinen Datentyp haben?
Es hat duch einen. Es ist vom Typ "struct leds0_3"
> LEDOUT0 ist ein register des PCA9635
Das kann dann allerdings so nichts werden. Denn irgendwie
muss ja noch die Verknüpfung zu diesem Register hergestellt
werden. Wenn das ein memory mapped Register ist, dann
kann man das so machen
struct leds0_3 * LEDOUT0 = 0xund_hier_die_Adresse_vom_Register;
*LEDOUT0.LDR2 = 2;
In allen anderen Fällen, wird das aber wohl nichts werden.
Ich sagte doch, dass dieses Bitgepfriemel über Bitfelder
überschätzt wird.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.