Fragen zu Registern/Ports/Portmanipulation

Hallo,

ich versuche mich momentan in die Register- Portansprache einzulesen und habe ein paar Fragen, ob ich es so richtig verstehe oder aber auf dem Holzweg bin.

Ich habe leider kein für mich verständliches Arduino-Video diesbezüglich auf Youtube gefunden und mir deshalb ein paar STM32-Videos angeschaut und versuche das nun auf Atmegas zu übertragen.

Sollte ich die falschen Wörter verwenden, bitte ich dies zu verzeihen, Controller zu programmieren ist für mich mehr oder weniger Neuland ich möchte aber auch direkt “möglichst tief” das Ganze versuchen zu verstehen.

Ich schreibe hier nur in Bezug auf einen Atmega328P.

Hier meine erste Frage:

In der Arduino-IDE schreibt man ja als beispielsweise:

pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);

wäre dies gleichzusetzen mit:

DDRD = B11101000 (Also Ports 0 bis 7 von rechts gelesen)

was wiederum identisch wäre zu:

DDRD |= 1<<3; oder auch DDRD &= ~(0<<3);
DDRD |= 1<<5; oder auch DDRD &= ~(0<<5);
DDRD |= 1<<6; oder auch DDRD &= ~(0<<6);
DDRD |= 1<<7; oder auch DDRD &= ~(0<<7);

und das Ganze invertiert:

pinMode(3, INPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);

wäre gleichzusetzen mit:

DDRD = B00010111 (Also Ports 0 bis 7 von rechts gelesen)

was wiederum identisch wäre zu:

DDRD |= 0<<3; oder auch DDRD &= ~(1<<3); (zu lesen als “und 0 auf 3 bzw und nicht 1 auf 3”)
DDRD |= 0<<5; oder auch DDRD &= ~(1<<5);
DDRD |= 0<<6; oder auch DDRD &= ~(1<<6);
DDRD |= 0<<7; oder auch DDRD &= ~(1<<7);

?

Frage 2:

Das bedeutet, ich muss meinen Code für jeden “Prozessor” individuell aufbauen, da diese ja unterschiedliche Register haben? Atmega328, Atmega2520, Atmega32, etc…

Ich muss ergo in den “Datasheets” bzw. “Dokumentationen” der einzelnen Prozessoren schauen, welche Ausgangsports in welchem Register liegen.

Habe ich dies so richtig verstanden?

Frage 3:

Das obige kann ich aber wiederum 1:1 auf folgendes übertragen:

PORTD = B11101000;

ist identisch zu:

digitalWrite(3, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
(und die 0er aus dem Register entsprechend als “LOW”)

Gruß,
Stefan

Hallo thefreak,
zu Frage 1:

DDRD = B11101000

ist nicht das Gleiche wie

DDRD |= 1 << 3
DDRD |= 1 << 5
DDRD |= 1 << 6
DDRD |= 1 << 7

Beim oberen Beispiel wird das Register überschrieben, beim unteren wird nur der Bit an der 3. (5., 6., 7.) Stelle auf 1 gesetzt.

The_Programmer:
Hallo thefreak,
zu Frage 1:

DDRD = B11101000

ist nicht das Gleiche wie

DDRD |= 1 << 3
DDRD |= 1 << 5
DDRD |= 1 << 6
DDRD |= 1 << 7

Beim oberen Beispiel wird das Register überschrieben, beim unteren wird nur der Bit an der 3. (5., 6., 7.) Stelle auf 1 gesetzt.

Bedeutet dann, alle anderen bleiben so wie sie waren?

Ergo:

DDRD = B11101000;
DDRD |= 0 << 3;

→ DDRD = B11100000;

Gruß,
Stefan

DDRD = B11101000;
DDRD &= ~(1 << 3);

→ DDRD = B11100000;

Ich muss ergo in den “Datasheets” bzw. “Dokumentationen” der einzelnen Prozessoren schauen, welche Ausgangsports in welchem Register liegen.

Es gibt auch nette Zusammenfassungen dafür:

Oder wenn du mit Google Image Search nach dem dem Board (z.B. “Arduino Mega”) und “Pin mapping” suchst

Das ist Unsinn:

DDRD |= 0<<3

Das schiebt eine 0 drei mal nach links. Macht wieder 0. Das ist nicht das gleiche wie eine 1 nach links schieben und dann alle Bits invertieren.

Der Grund weshalb man eine 1 nach links schiebt ist um eine Bitmaske für das entsprechende Bit zu bekommen. Dazu gibt es auch das AVR Makro _BV() (bit value) oder das Arduino Makro bit()

UND mit dem invertieren Byte setzt das entsprechende Bit auf 0

Hier [Projekt] Schnelle Digital Eingabe/Ausgabe - Deutsch - Arduino Forum habe ich mal zu dem Thema was verbrochen.

Ihr seid großartig!

Es klickt!

Danke,
Stefan

Mal ganz deutlich:

Byte: 1100 0011
Bitmaske für Bit 1 (1 << 1): 0000 0010
Bitmaske invertiert: 1111 1101

1100 0011
&
1111 1101
=
1100 0001

Wie man sieht wurde Bit 1 auf 0 gesetzt

thefreak:
[...] ich möchte aber auch direkt "möglichst tief" das Ganze versuchen zu verstehen.

Ich glaube für dich wäre es ganz gut damit anzufangen, die grundlegenden Operatoren für die Bitmanipulation zu lernen:
http://playground.arduino.cc/Code/BitMath

zu Frage 2
Ja, Du mußt bei jedem Controller nachschauen wie er aufgebaut ist und welches Pin an welchen Port hängt.

Grüße Uwe