Forum: Mikrocontroller und Digitale Elektronik PC Tastatur Bibliothek - Verständnis Frage


von Manuel B. (desteini)


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!

von Mat (Gast)


Lesenswert?

Hallo,

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.

lg Mat

von Mat (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch ein Auszug aus dem Datenblatt des Atmega16.
Da siehst du die Adresse des Registers und die Bezeichung dazu.

gruß

von Manuel B. (desteini)


Lesenswert?

Oh Gott... Danke!

Ewig drann gesessen und jetzt ist es so offensichtlich. Danke Mat!

von Karl H. (kbuchegg)


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.

von Manuel B. (desteini)


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.

von spess53 (Gast)


Angehängte Dateien:

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

von Peter II (Gast)


Lesenswert?

spess53 schrieb:
> Es gibt aber auch Ausnahmen, z.B. ATMega 128.

auch Tiny465 ist anders

> Each port pin consists of four register bits: DDxn, PORTxn, PUExn, and
> PINxn.

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.