PC Tastatur Bibliothek - Verständnis Frage

OP #3607264
Lesenswert?

Hallo Leute,

ich bin gerade dabei die Tastatur-Routine von 
Beitrag "PC / AT-Tastatur Routine" auf meinen PIC24EP512GP806 
mit dem XC16 Compiler zu portieren.

Doch es gibt 2 Befehle, die für mich keinen Sinn ergeben.
1
#define PINOFPORT(x) (*(&x - 2))
2
#define DDROFPORT(x) (*(&x - 1))

und angewendet:
1
DDROFPORT(KEYB_DATA_PORT)&=~(1<<KEYB_DATA_PIN);
2

3

4
if (PINOFPORT(KEYB_DATA_PORT) & (1<<KEYB_DATA_PIN))
5
        data = data | 0x80;// Store a '1'
1
#define KEYB_DATA_PORT PORTD  //PORT which data-pin is connected to
2
#define KEYB_CLOCK_PIN PD2    //PIN of clock-pin
3
#define KEYB_DATA_PIN PD3    //PIN of data-pin

Meiner Meinung nach wird bei PINOFPORT die Adresse von PORTD um 2 
dekrementiert und dann auf den Wert gezeigt. Aber was für einen Sinn 
macht das, die Adresse des Ports zu dekrementieren? Die neue Adresse 
wird dann bei einem gewissen Pin (KEYB_DATA_PIN) auf 0 gesetzt.

ähnlich mit dem DDROPORT Befehlen. Ist das etwas AVR-typisches oder 
Versteh ich da etwas falsch?

Wäre für einen Rat wirklich dankbar!
#3607296
Lesenswert?

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.
OP #3607315
Lesenswert?

Super, sehr verständlich erklärt. Bei den PICs ist das so ziehmlich das 
Selbe, bloß dass die 3 Register eben TRISX (DDR), PORTX(PORT) und 
LATX(PIN) heißen. Jedoch wird der Pullup anderst gesteuert.

Gerade erst entdeckt, dass die PORT-Belegung für Ein- und Ausgänge für 
Pics invertiert ist. Beim PIC ist TRISC=0xFF; der Code für alle Pins für 
Port C ist ein Eingang, entsprechend bedeutet 0 Ausgang. Beim AVR 
scheint es andersrum zu sein.

Sehr komisch, dass das nicht einheitlich geregelt ist.
Gast #3607322
Lesenswert?

Hi

>die Register für PIN und DDR liegen halt um 1 bzw. 2 "niedriger" als das
>PORT Register.
>So liegt von einem gegebenen Port das DDR Register halt "eine" Adresse
>darunter.

Es gibt aber auch Ausnahmen, z.B. ATMega 128.

MfG Spess
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren