xmega Taktfrequenz

Gast #5494536
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).
Angehängte Dateien:
#5494555
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.
(Firma: L-E-A) #5494617
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.
(Firma: L-E-A) #5494659
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.