Forum: Compiler & IDEs sbi und cbi fkt. umschreiben


von Adam (Gast)


Lesenswert?

Hallo,
ich habe einen etwas älteren C Code der mit dem Funktionen sbi und cbi
arbeitet.
Kann mir jemand sagen wie ich diesen Teil umschreiben muss, damit der
neue gcc das compilierne kann?
Hier ein Beispiel:

sbi(PORTD, PD3);
cbi(PORTD, PD2);

Danke vorab,
Adam

von Quix01 (Gast)


Lesenswert?

PORTD |= (1<<3)  // set bit 3
PORTD &= ~(1<<3) // clear bit 3

Ciao Thomas.

von johnny.m (Gast)


Lesenswert?

PORTD |= 1 << PD3;
PORTD &= ~(1 << PD3);

von Quix01 (Gast)


Lesenswert?

Da waren wir gleichschnell und haben beide den Fehler drin, dass PD2
gelöscht werden soll grins

Ciao Thomas.

von johnny.m (Gast)


Lesenswert?

Oh yeah, aber ich denke, das wichtigste ist das Prinzip...

von Quix01 (Gast)


Lesenswert?

@ johnny.m
seh ich genau so.

Ich hab meist folgendes Makro zum Bit-Löschen definiert, um mir die
Schreibarbeit bissel zu vereinfachen:
#define DEL(X)  &= ~(X)

Im Code:
  PORTD DEL(1<<PD2)

Ciao Thomas.

von Quix01 (Gast)


Lesenswert?

mit Semikolon natürlich

  PORTD DEL(1<<PD2);


Die Hitze, stöhn...

von johnny.m (Gast)


Lesenswert?

Dann lieber gleich

#define SBI(REG, BIT) REG |= 1 << BIT
#define CBI(REG, BIT) REG &= ~(1 << BIT)
...
SBI(PORTD, PD3);
CBI(PORTD, PD2);

Gruß

Johnny

von Peter D. (peda)


Lesenswert?


von Adam (Gast)


Lesenswert?

Okey, danke Jungs :)

von Andre (Gast)


Lesenswert?

hallo, das stimmt das Prinzip ist das Wichtigste...
Aber ich verstehe es nicht, vielleicht fehlen mir einfach die nötigen
Grunkenntnissse, könnt mir jemand vielleicht erklären warum

PORTD |= 1 << PD3;
PORTD &= ~(1 << PD3);

das mach was es macht?


Dankeschön Andre

von Karl heinz B. (kbucheg)


Lesenswert?

PD3  kommt von einem ordinären
#define PD3  3

überall wo also PD3 steht, ersetzt der Präprozessor
diesen Text 'PD3' mit '3'

damit wird   1 << PD3
zu           1 << 3

und das macht: nimm eine 1 und schieb diese 1 binär dreimal
nach links. Aus  0b00000001  wird also  0b00001000

A |= B
ist die Kurzform für   A = A | B

wobei | eine ODER Verknüpfung darstellt. Im Gegensatz zu
|| wird diese aber auf Bitebene durchgeführt, dh. die
gleichwertigen Bits der beiden Partner werden miteinander
ODER-Verknüpft.
Du weist schon:

    A    B   |   A | B
  -----------+---------
    0    0   |     0
    1    0   |     1
    0    1   |     1
    1    1   |     1

In dieser Tabelle ist im Ergebnis genau dann eine 1, wenn
entweder A ODER B ODER Beide 1 waren. Und genau das will
man hier.

Wenn ich

   PORTD = PORTD | 0b00001000;

mache, dann wird an die Bitposition 3 auf jeden Fall eine 1
gesetzt, gleichgültig was vorher in PORTD stand. (Die anderen
Bits bleiben so wie sie sind. Schau in die Tabelle: Wenn B 0
ist, dann ist das Ergebnis identisch mit dem Zustand von A)

---------------------------------

PORTD &= ~( 1 << PD3 );

~ macht eine binäre Negation. D.h. alle Bits werden umgedreht.
aus  0b00001000  wird also  0b11110111
A &= B ist wieder eine Kurzform. Diesmal für A = A & B

und das & steht für binäres UND

    A    B   |  A&B
   ----------+------
    0    0   |   0
    1    0   |   0
    0    1   |   0
    1    1   |   1

Das Ergebnis ist genau dann 1, wenn A UND B 1 waren.
Schau dir die Tabelle genauer an. In den Zeilen in
denen B 0 ist, ist das Ergebnis auf jeden Fall 0.
In den Zeilen in denen B einen Wert von 1 hat, ist
der Ergebnis identisch mit dem Zustand von A.

Jetzt sollte schon klar sein, was

   PORTD = PORTD & 0b11110111

macht. Überall dort wo in der Maske 0b11110111 eine 1
steht, ist das Ergebnis identisch mit PORTD an dieser
Bitposition. Überall dort wo in der Maske eine 0 steht,
wird das betreffende Bit im Ergebnis auf jeden Fall auf
0 gesetzt.

von johnny.m (Gast)


Lesenswert?

@Karl Heinz:
Wann kommt eigentlich Dein Buch raus??? Hast Du irgendwo ne Datenbank,
in der für jede Frage so ne schön erklärte Antwort steht? Und dann
immer diese schönen Beispiele aus dem täglichen Leben...

von Andre (Gast)


Lesenswert?

@Karl Heinz
Super, danke für die wirklich gut verständliche Erklärung und die Mühe
die du dir gemacht hast.

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.