www.mikrocontroller.net

Forum: Compiler & IDEs Definition von 2 Bit in einem 8bit Register


Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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





Autor: j-x (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in c++ gehts so:

xyz = (a3<<6)+(a2<<4)+(a1<<2)+a0

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja dann machst du ja ein Bit-Shift

Aber dadurch ist A1 etc. immer noch nicht definiert

Autor: j-x (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auslesen wär dann so (zumindest in c++ gehts nicht anders)
int a1= (xyz&0b00001100)>>2; //ob man das & braucht weis ich nicht

Autor: Ronny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#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.

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ich habe mal versucht das an einem konkreten Beispiel umzusetzen.
Leider Ohne erfolg

LEDOUT0 ist ein register des PCA9635

#define LEDOUT0    0x14

struct leds0_3 {
  unsigned char LDR0:2;
  unsigned char LDR1:2;
  unsigned char LDR2:2;
  unsigned char LDR3:2;
} 

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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.