Forum: Mikrocontroller und Digitale Elektronik AVR: Aus Addresse für PORTx auf DDRx/PINx schließen


von Tim  . (cpldcpu)


Lesenswert?

Ich würde in einer Library gerne das Portregister (PORTX) zur Laufzeit 
übergeben. Dabei wäre es nützlich, aus diesem die Addressen für PINx und 
DDRx zu generieren.

Auf der ersten Blick komme ich auf Folgendes:

PINx=PORTx-2
DDRx=PORTx-1

Ist das auf alle AVR Anwendbar?

von spess53 (Gast)


Lesenswert?

Hi

>Ist das auf alle AVR Anwendbar?

Mir ist bis jetzt nichts anderes unter gekommen. Allerdings haben neuere 
ATTinys pro Port ein zusätzliches Port Pull-Up Enable Control Register. 
Dessen Offset zum Port-Register ist nicht einheitlich.

MfG Spess

von Tim  . (cpldcpu)


Lesenswert?

Danke! Dann werde ich es riskieren.

von Stefan E. (sternst)


Lesenswert?

Tim    schrieb:
> Ist das auf alle AVR Anwendbar?

Es gibt zwar nur wenige Ausnahmen, aber es gibt sie.
Z.B. PORTF des Mega128.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Für eine Library zwar nicht nutzbar, aber wenn man es nur in einem
Headerfile braucht, kann man mit etwas Präprozessor-Trickserei natürlich
aus einem übergebenen Parameter (bspw. »A«) dann alle drei IO-Namen
ableiten.  Hier mal ein Stückchen aus einem realen Projekt, bei dem
auf den Boards die Anschlüsse der LEDs querbeet verstreut waren:
1
/* LED port/pin assignment */
2
#define LED_PORT_BIT_0                  D, 5
3
#define LED_PORT_BIT_1                  D, 7
4
#define LED_PORT_BIT_2                  B, 4
5
#define LED_PORT_BIT_3                  G, 0
6
#define LED_PORT_BIT_4                  E, 6
7
8
/* Helper macros */
9
#define CONCAT_PORT_(r, p) r##p
10
#define CONCAT_PORT(r, p, b) CONCAT_PORT_(r, p)
11
#define LED_BITMASK_(p, b) (1 << (b))
12
13
/* LED port/bit access macros */
14
#define LED_BITMASK(x)                  LED_BITMASK_(x)
15
#define LED_PORT(x)                     CONCAT_PORT(PORT, x)
16
#define LED_DDR(x)                      CONCAT_PORT(DDR, x)
17
18
void led_init(void)
19
{
20
    /* Switch LEDs off. LEDs are low active. */
21
    LED_DDR(LED_PORT_BIT_0)  |= LED_BITMASK(LED_PORT_BIT_0);
22
    LED_PORT(LED_PORT_BIT_0) |= LED_BITMASK(LED_PORT_BIT_0);
23
24
    LED_DDR(LED_PORT_BIT_1)  |= LED_BITMASK(LED_PORT_BIT_1);
25
    LED_PORT(LED_PORT_BIT_1) |= LED_BITMASK(LED_PORT_BIT_1);
26
27
    LED_DDR(LED_PORT_BIT_2)  |= LED_BITMASK(LED_PORT_BIT_2);
28
    LED_PORT(LED_PORT_BIT_2) |= LED_BITMASK(LED_PORT_BIT_2);
29
30
    LED_DDR(LED_PORT_BIT_3)  |= LED_BITMASK(LED_PORT_BIT_3);
31
    LED_PORT(LED_PORT_BIT_3) |= LED_BITMASK(LED_PORT_BIT_3);
32
33
    LED_DDR(LED_PORT_BIT_4)  |= LED_BITMASK(LED_PORT_BIT_4);
34
    LED_PORT(LED_PORT_BIT_4) |= LED_BITMASK(LED_PORT_BIT_4);
35
}

von spess53 (Gast)


Lesenswert?

Hi

>Es gibt zwar nur wenige Ausnahmen, aber es gibt sie.
>Z.B. PORTF des Mega128.

Stimmt, Das ist der Nachfolger des ATMega103. Und der hatte kein 
PortF-Register. Wie auch kein PinC-Register.

MfG Spess

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.