Forum: Mikrocontroller und Digitale Elektronik AVR-Timing-Frage: PORTx so schnell wie Variablenzugriffe?


von Frank (Gast)


Lesenswert?

Sind beim ATMega Zugriffe auf PORTA...D genauso schnell wie Zugriffe auf 
Variablen im C-Code?

Hintergrund: UART0 und UART1 eines AVR sollen in Software verbunden 
werden (als ob der PC an UART0 mit dem Chip an UART1 verbunden wäre) - 
aber ohne UART-Programmierung, sondern indem Bits in PORTD in kurzer 
Endlosschleife in einem Bootloader kopiert werden: RXD1-Bit nach 
TXD0-Bit, RXD0-Bit nach TXD1-Bit. F_CPU ist 18.432MHZ, es soll bis 
115200 Baud funktionieren, Interrupts sind aus. Ich frage mich jetzt, 
was schneller ist:

A: PORTD auslesen, Bitschieberei in lokaler Variable, dann PORTD 
aktualisieren, oder
B: PORTD ohne Zwischenvariable verwenden
1
/* A */
2
3
while (...)
4
{
5
    uint8_t out = PORTD;
6
7
    if (out & BITMASK2)      // copy RXD1 (D2) to TXD0 (D1)
8
        out |=  BITMASK1;
9
    else
10
        out &= ~BITMASK1;
11
12
    if (out & BITMASK0)      // copy RXD0 (D0) to TXD1 (D3)
13
        out |=  BITMASK3;
14
    else
15
        out &= ~BITMASK3;
16
17
    PORTD = out;
18
}
19
20
/* B */
21
22
while (...)
23
{
24
    if (PORTD & BITMASK2)    // copy RXD1 (D2) to TXD0 (D1)
25
        PORTD |=  BITMASK1;
26
    else
27
        PORTD &= ~BITMASK1;
28
29
    if (PORTD & BITMASK0)    // copy RXD0 (D0) to TXD1 (D3)
30
        PORTD |=  BITMASK3;
31
    else
32
        PORTD &= ~BITMASK3;
33
}

: Bearbeitet durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Frank schrieb:
> Sind beim ATMega Zugriffe auf PORTA...D genauso schnell wie Zugriffe auf
> Variablen im C-Code?

Sie sind langsamer, schneller und gleich. Je nach Kontext.

von Peter II (Gast)


Lesenswert?

Frank schrieb:
> Ich frage mich jetzt,
> was schneller ist:

schau dir den ASM-code und dazu die Doku, dann sieht du wie viele Takte 
dafür notwendig sein.

Gefühlt würde ich sagen, sollte gehen.

von Falk B. (falk)


Lesenswert?

@ Frank (Gast)

>Sind beim ATMega Zugriffe auf PORTA...D genauso schnell wie Zugriffe auf
>Variablen im C-Code?

Ja.

>Hintergrund: UART0 und UART1 eines AVR sollen in Software verbunden
>werden (als ob der PC an UART0 mit dem Chip an UART1 verbunden wäre) -
>aber ohne UART-Programmierung, sondern indem Bits in PORTD in kurzer
>Endlosschleife in einem Bootloader kopiert werden: RXD1-Bit nach
>TXD0-Bit, RXD0-Bit nach TXD1-Bit. F_CPU ist 18.432MHZ, es soll bis
>115200 Baud funktionieren, Interrupts sind aus.

Kann man machen, auch wenn das etwas sinnfrei ist.

>Ich frage mich jetzt, was schneller ist:

ASM ;-)

>A: PORTD auslesen, Bitschieberei in lokaler Variable,

Gar nicht schieben, nur abfragen. Bei Einlesen muss es PIND sein. Beide 
Versionen dürften ansatzweise gleich schnell sein. Denn das wird alles 
auf Bitbefehle umgesetzt. Das dürfte 3 Takte / Port sein, in Summe 6 + 
Schleife, macht 8 Takte Umlaufzeit. Im Zweifel ist B einen Tick 
schneller.

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


Lesenswert?

Zwei UARTs auf einem Port D?  Normale AVRs haben sowas nicht, ist das
ein Xmega?

Bei den Xmegas liegen die Port-Adressbereiche alle im MMIO-Bereich,
sodass SBI/CBI nicht funktionieren.  Allerdings kann man sie speziell
für diesen Zweck wiederum als virtuelle Ports konfigurieren.

Ansonsten: du hast pro Bitzeit 160 CPU-Takte, das genügt allemal, egal
wie du es anstellst.  Es entsteht ja auch nur ein Jitter, kein
kumulativer Fehler.

von Frank (Gast)


Lesenswert?

> auch wenn das etwas sinnfrei ist

Danke für die ausführliche Antwort. Der Sinn ist in diesem Fall, mit 
wenig Code (da es um einen AVR-Bootloader geht) ein am AVR hängendes 
WLAN-Modul (UART0) vom PC aus (UART1) zu flashen. Also ein Bootloader, 
der sowohl den AVR als auch den WLAN-Chip flashen kann. Die Baudrate des 
WLAN-Chips ist unbekannt bzw. wechselt, mal 115200 im normalen Betrieb, 
mal 75400 Baud, wenn der Bootloader des WLAN-Chips aktiviert wird.

> Zwei UARTs auf einem Port D?  Normale AVRs haben sowas nicht, ist das ein Xmega?

Das ist ein normnaler AVR (ATMega1284P)

von Falk B. (falk)


Lesenswert?

@Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite

>Bei den Xmegas liegen die Port-Adressbereiche alle im MMIO-Bereich,
>sodass SBI/CBI nicht funktionieren.  Allerdings kann man sie speziell
>für diesen Zweck wiederum als virtuelle Ports konfigurieren.

Wenn es ein Xmega ist, kann man das auch per DMA ganz ohne CPU machen. 
Dazu gab es hier mal einen Thread.

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.