Forum: Mikrocontroller und Digitale Elektronik Xmega _delay_us: Seltsames Verhalten


von Gregor W. (gregor78)


Lesenswert?

Hallo,
ich habe mal mit meinem xmega mit der delay-Funktion gespielt, das 
Programm gibt eine Rampe über den D/A-Wandler aus. Werte kleiner als 20 
µs bewirken keine messbare Verzögerung. Die Schleife müsste alleine 
schon 1ms laufen, eine Rampe dauert aber nur 22ms.
Bei Werten größer 20 µs fehlt in der Periodendauer ein Faktor 16.
Was ist da los?
1
while (1)      //Endlosschleife, gibt eine Rampe aus
2
{
3
 DACA.CH0DATA = i;    //Wert zum Ausgeben
4
 i++;
5
 for (uint8_t j=0;  j<100; j++)
6
 {
7
  _delay_us(10);               //Verzoegerung 100x
8
 }
9
}

Den Takt habe ich auf 32MHz eingestellt.
1
//32 MHz interne Taktfrequenz ausgewählt
2
void mhz ()
3
{
4
 OSC.CTRL = 3;
5
 while(OSC.STATUS != 3)
6
  {
7
  }
8
 CCP = 0xD8;
9
 CLK.CTRL = 1;
10
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Werte kleiner als 20 µs bewirken keine messbare Verzögerung.
Das drumrum (die for-Schleife) braucht auch Zeit...

> Den Takt habe ich auf 32MHz eingestellt.
Weiß das der Compiler (#define F_CPU 32000000UL)?

Welchen Optimierungslevel hast du eingestellt?

von Gregor W. (gregor78)


Lesenswert?

Ohne for-Schleife sieht es bei kleinen delays besser aus, das war Trick 
17 mit Selbsüberlistung.

Optimierung habe ich -Os eingestellt.
1
#define F_CPU 32000000UL
 habe ich noch eingebaut.
1
while (1)      //Endlosschleife
2
{
3
 PORTB.OUTTGL = PIN0_bm;  //Ausgang umschalten
4
}
Ergibt eine Frequenz von 4MHz, egal was für einen Wert in F_CPU steht. 
Das müsste 4 Takte benötigen, damit läuft der Prozessor auf 32MHz. Aber 
wieso wird das ignoriert?

von Marius W. (mw1987)


Lesenswert?

Schau dir mal das Assembler-Listing dazu an.

Wahrscheinlich braucht die Schleife 8 Takte und daher resultiert die 
Frequenz von 4 MHz = 32 MHz / 8...

MfG
Marius

von Gregor W. (gregor78)


Angehängte Dateien:

Lesenswert?

8 Takte pro Schleifendurchlauf kann eigentlich nicht sein: Der Ausgang 
wird einmal pro Durchlauf umgeschalten, für eine ganze Periode braucht 
es 2 Durchläufe: 32MHz/(2*8Takte)=2MHz.
Ich habe es nachgemessen: es sind 4MHz. Habe mal einen Screenshot 
gemacht:

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


Lesenswert?

Gregor Wetzel schrieb:
> Ergibt eine Frequenz von 4MHz, egal was für einen Wert in F_CPU
> steht. Das müsste 4 Takte benötigen, damit läuft der Prozessor auf
> 32MHz. Aber wieso wird das ignoriert?

Was denn?  Das F_CPU?  Wo soll das denn bei dem Stückchen Code eine
Rolle spielen?

von stromflo (Gast)


Lesenswert?

Schau hier mal genau drauf!

OSC.CTRL = 3;

Wie kommst du auf OSC.CTRL = 3 bei 32 Mhz?

Also wenn ich mich jetzt nicht gnadenlos verschaut hab, musst du das 2 
bit auf eins setzen.

Schau mal Seite 87 im Datasheet XMEGA A Family!

Und damit sowas auch klarer wird kann man es auch wie folgt schreiben:

OSC.CTRL |= OSC_RC32MEN_bm;

Gruß Flo

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.