Ein physikalicher Port auf einem AVR besteht aus 3 Registern
* dem DDRx Register, in welchem festgelegt wird, welcher Pin ein Ausgang
und welcher ein Eingang sein soll
* einem PORTx Register, das 2 Funktionen erfüllt
a) bei einem auf Ausgang geschaltetem Pin, legt man dort fest, ob der
Pin auf 0 oder auf 1 sein soll.
b) Bei einem auf Eingang geschaltetem Pin, kann man über das
Portregister für diesen Pin einen Pullup zu bzw. wegschalten
* einem PINx Register
von dort erfährt man den Zustand jedes Pins, bzw. bei neueren AVR kann
man damit einen auf Ausgang geschalteten Pin toggeln
Wichtig ist:
die 3 Register gehören zusammen.
Benutzt man also in einem Programm irgendeine I/O Funktion an einem Pin,
dann muss man meistens 3 Register anpassen, mindestens aber 2
1 | #define LED_DDR DDRB
|
2 | #define LED_PORT PORTB
|
und das ist genau 1 Angabe zuviel. Denn hier darf der Programmierer
keinen Fehler machen. Die Angabe des DDR Registers muss zum PORT
Register passen. Wenn nicht, hat man einen Fehler.
Lässt sich aber die Bezeichnung (bzw. die Adresse) zb des DDRB Registers
direkt aus der Angabe 'Ich will den Port B benutzen' errechnen, dann
kann es damit zu keinem derartigen Fehler mehr kommen.
-> defensives Programmieren. Man sichert sich als Programmierer gegen
seine eigenen Fehler ab und gestaltet den Code so, dass man sich selbst
möglichst keine Fehlermöglichkeit mehr offen lässt.