Forum: Mikrocontroller und Digitale Elektronik xmega Taktfrequenz


von Peet (Gast)


Angehängte Dateien:

Lesenswert?

Folgender Code ergibt die Messung im Anhang (gemessen am Ausgangspin):

1
#include <avr/io.h>
2
#define F_CPU 32000000UL
3
#include <util/delay.h>
4
5
int main( void )
6
{
7
  
8
  OSC.CTRL |= OSC_RC32MEN_bm;
9
  while(!(OSC.STATUS & OSC_RC32MRDY_bm));
10
  CCP = CCP_IOREG_gc;
11
  CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
12
  
13
  PORTD.DIRSET = 0b00010000 ; 
14
  
15
  while(1){ 
16
    PORTD.OUTSET = 0b00010000 ;
17
    PORTD.OUTCLR = 0b00010000 ; 
18
  }
19
}

Warum habe ich solch lange Schaltzeiten bei 32MHz?
Zum Vergleich: Ein Atmega88A mit "gleichem" Code liefert bei 20MHz ein 
fast identisches Ergebnis (was ja auch nachvollziehbar ist).

von Jim M. (turboj)


Lesenswert?

Schau mal nach was der für Assembler Code generiert. Der Rücksprung 
dauert, das ist normal.

Außerdem brauchen viele schnellere µCs 2 Takte zum Schreiben auf 
Peripherie -> Datenblatt.

Schnelles Oszi wäre besser - auf dem geposteten Bild sehe ich keine Rise 
oder Fall Time, was komplett unglaubwürdig ist. Reale Signale von einem 
µC haben "runde" Ecken bei Zeitauflösung in ns.

von Faster! (Gast)


Lesenswert?

Nimm die PLL.
64MHz vertragen die xmegas noch..

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Peet schrieb:

> Warum habe ich solch lange Schaltzeiten bei 32MHz?

Welchen Optimierungs-Level hast Du aktiviert? Poste doch bitte auch 
Deinen Compiler-Aufruf.

Grüßle
Volker

Nachtrag: Ohne Optimierung funktioniert der Zugriff auf das geschützte 
Register für die Taktumstellung nicht, wird also aktiviert sein.

Mein avr-gcc erzeugt für die Schleife folgenden Code

.L3:
        std Z+5,r24
        std Z+6,r24
        rjmp .L3

Wobei jeder Assembler-Befehl 2 Taktzyklen benötigt und die Schleife 
somit
187,5ns benötigt.

Problem ist wohl, dass die Portrgeister 2 Bytes zur Adressierung 
benötigen und somit hier über das Indexregister zugegriffen wird, mit 
dem entsprechenden Bedarf an Taktzyklen.

: Bearbeitet durch User
von Peet (Gast)


Lesenswert?

Danke Volker, dann werde ich wohl damit leben müssen. Vielleicht 
probiere ich das mit der PLL noch..

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Peet schrieb:
> dann werde ich wohl damit leben müssen. Vielleicht
> probiere ich das mit der PLL noch..

Die Verwendung des Toggle-Registers bringt leider auch nichts, außer 
dass dar Takt symmetrisch wird (50% Tastverhältnis), dafür aber 8 Zyklen 
dauert. Wenn nur wenige Taktzyklen benötigt werden, könntest Du alle 
Toggle-Zugriffe hintereinander schreiben (Loop unrolling).

Vielleicht bringt die Verwendung eines virtuellen Ports eine 
Verbesserung, da deren Adressen beim 32a4u auf 0x0010, 0x0014, 0x0018 
und 0x001C liegen.
Leider kennen die virtuellen Ports keine Set- und Clear-Register. Du 
müsstest also alle Ausgangsportpins beschreiben.

Grüßle
Volker

Nachtrag: Tatsächlich, beim Zugriff auf einen virtuellen Port

   VPORT1.OUT = 0b00010000 ;
   VPORT1.OUT = 0;

Liefert avr-gcc:

.L3:
       out 0x15,r24
       out 0x15,__zero_reg__
       rjmp .L3

Jetzt habe ich endlich verstanden, welchen Sinn diese virtuellen Ports 
haben :-)

...und noch ein Nachtrag zum Nachtrag: Bei den VPORT-Registern 
funktionieren die Bit-Setz und -Löschbefehle

    VPORT1.OUT |=  0b00010000;
    VPORT1.OUT &= ~0b00010000;

liefert somit

.L3:
        sbi 0x15,4
        cbi 0x15,4
        rjmp .L3

und sollte somit die gleiche Performance wie beim AVR liefern.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Jim M. schrieb:
> Schnelles Oszi wäre besser - auf dem geposteten Bild

Das ist offensichtlich handgemalt.

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.