Forum: Mikrocontroller und Digitale Elektronik Programmgeschwindigkeit bim XMEGA viel kleiner als Taktfrequenz?


von Edimahler (Gast)


Lesenswert?

So, nun mal eine Frage an alle XMEGA-Experten:

Wenn ich folgendes Miniprogramm:
1
  cli();            // disable global Interrupts
2
3
  PORTCFG.CLKEVOUT = 0x02;
4
  while(1)
5
  {
6
    PORTE.OUT |= 0x02;
7
    PORTE.OUT &= 0xFD;
8
  }

auf meinen XMEGA32A4 lade, bekomme ich bei einem Systemtakt von 32MHz 
(intern oder extern egal) nur gerade ein Ausgangssignal mit ca. 2.6MHz 
auf PORTE.
- Der Code wurde in AVR Studio mit -Os optimiert, sollte demnach sehr 
schnell sein.
- Clock Prescaler sind alle ausgeschaltet.
- Die "Ein-" Phase vom Portpin dauert 6 Taktzyklen, die "Aus-" Phase 8 
Taktzyklen (durch den Rücksprung im while(1) bedingt).
- An PORTD7 lasse ich das Taktsignal des CPUs ausgeben, dieses beträgt 
32MHz, wie es sein sollte.

Was zum Geier mache ich bloss falsch? Thanks für jede Hilfe!
Simon

von Klaus F. (kfalser)


Lesenswert?

Eine C Zeile entspricht immer mehreren Maschinenbefehlen.
Du kannst :
- Den Assembler-Code anschauen und für die einzelnen Befehle die 
benötigten Taktzyklen laut Datenblatt zusammenzählen.
- Du lädst das Programm in AVR Studio und simulierst das Programm Step 
by Step. Der Simulator zeigt Dir die abgelaufenen Taktzkylen an.

von Daniel V. (danvet)


Lesenswert?

Jetzt hast du dir selbstein Bein gestellt:

32MHz /14Zyklen = 2,3MHz

Voila. Stimmt doch..??!!

von R. M. (exp)


Lesenswert?

passt doch

T = 1 / 32000000  [s]

Fport = 1 / (14 * T) = 2 285 714.286 [1/s] = 2.28 MHz

von Maik W. (werner01)


Lesenswert?

hihihi

von Udo R. S. (Gast)


Lesenswert?

Du musst mit der Compileroption -assembler übersetzen, dann ists 
schneller :-)

von Udo R. S. (Gast)


Lesenswert?

Oder die neuen Prozessoren mit dem 'C'-Stepping nehmen. Die können 
direkt C-Befehle in einem Taktzyklus ausführen.

von ich (Gast)


Lesenswert?

oder statt direkt auf das Ausgangsregister zu schreiben:
>PORTE.OUT |= 0x02;
Das Register zum setzen des Ausgangs beschreiben. Dann muss das 
Ausgangsregister nicht geladen und verodert werden.

PORTE.OUTSET = 0x02;

Beim löschen des Bits entsprechend

PORTE.OUTCLR = 0x02

oder gleich Toggeln

PORTE.OUTTGL = 0x02

von ich (Gast)


Lesenswert?

ach ja:
Die Register .OUTSET , .OUTCLR usw. schreiben sich selbstständig nach 
dem Ausführen des Befehls auf 0x00 zurück. Liest man diese Register, 
entspricht das glaube ich dem Wert des .IN Registers.

Wenn du das so machst, wird dein Programm etwa doppelt so schnell sein.

von Edimahler (Gast)


Lesenswert?

Wow, thanks für die vielen Hinweise!

Daniel V. schrieb:
> Jetzt hast du dir selbstein Bein gestellt:
>
> 32MHz /14Zyklen = 2,3MHz
>
> Voila. Stimmt doch..??!!

Ja, ist mir bewusst, mir gehts mehr darum, weshalb wo viele Taktzyklen 
verbraucht werden für eine Veroderung und Signalausgabe. Bei den 
AVR-Typen entsprechen ja die meisten (Assembler-)Befehle einem Takt. Und 
ich war erstaunt, dass der Unterschied zwiscehn C und Assembler trotz 
Optimierung und so einfachem Programm solch riesige Unterschiede bringen 
soll...



Maik Werner schrieb:
> hihihi

Dies war besonders geist- und hilfreich, danke! ;-)



Danke für die Hinweise mit dem "-assembler" und dem "PORTE.OUTSET" etc.!



Udo R. S. schrieb:
> Oder die neuen Prozessoren mit dem 'C'-Stepping nehmen. Die können
> direkt C-Befehle in einem Taktzyklus ausführen.

Dies klingt ebenfalls sehr interessant, wird aber von den XMEGAs nicht 
unterstützt, oder liege ich falsch?

von Justus S. (jussa)


Lesenswert?

Edimahler schrieb:
> Dies klingt ebenfalls sehr interessant, wird aber von den XMEGAs nicht
> unterstützt, oder liege ich falsch?

du weisst, welcher Tag heute ist?

von ich (Gast)


Lesenswert?

>ich war erstaunt, dass der Unterschied zwiscehn C und Assembler trotz
>Optimierung und so einfachem Programm solch riesige Unterschiede bringen
>soll...

In Assembler bist du, so wie du das Programm geschrieben hast, nicht 
schneller.

von Edimahler (Gast)


Lesenswert?

Justus Skorps schrieb:
> du weisst, welcher Tag heute ist?

Upps... ;-) Schade eigentlich...



"ich" schrieb:
> In Assembler bist du, so wie du das Programm geschrieben hast, nicht
> schneller.
>
>
>
>

Hmm, liesse sich dies doch so einfache Progrämmchen tatsächlich noch 
vereinfachen? Wie denn?

von Edimahler (Gast)


Lesenswert?

...aha ja, eben, .OUTSET / .OUTCLR usw.

Die Takte haben sich auf 3 und 5 (inkl. Programmrücksprung) reduziert, 
thanks!

Werde mich dann mal in Assembler in WinAVR einlesen müssen, habe dies 
bisher immer nur eigenstänig benutzt, ohne Einbindung in C.

von ich (Gast)


Lesenswert?

>Hmm, liesse sich dies doch so einfache Progrämmchen tatsächlich noch
>vereinfachen? Wie denn?

Das hab ich nicht behauptet. Mit DIESEN (Ausgang laden, verodern, 
rückschreiben) Befehlen gehts wohl nicht schneller. Ich meinte nur dass 
der Compiler hier schon das maximale (für diese Befehle) rausgeholt hat.

Wenn man natürlich Befehle wie PORTE.OUTSET bzw. PORTE.OUTCLR verwendet, 
geht das ganze etwa doppelt so schnell. Aber es ist dann eben ein 
anderes Programm. Trotz gleicher Funktion.

von Edimahler (Gast)


Lesenswert?

Gibts irgendwo eine schöne Übersicht über genau solche Befehle wie 
OUTSET, OUTCLR etc? Habe bisher immer das Include-File des XMEGA 
durchsucht, meist ist aber nicht ganz klar, was die entsprechenden 
Befehle auch wirklich tun...

Assembler hat noch nicht funktioniert, na, da muss ich dann selber 
nochmals durch.

So und dann wünsche ich schonmal schöne Ostern, und vielen Dank für die 
vielen tollen Hints und Ideen, echt Klasse!


Beste Grüsse und Gut-Ostereier-find
Simon

von bensch (Gast)


Lesenswert?

> Gibts irgendwo eine schöne Übersicht

Schade, dass es keine Datenblätter gibt- und in diesen auch keine Liste 
aller Befehle....

von Simon K. (simon) Benutzerseite


Lesenswert?

OUTSET/OUTCLR sind keine Befehle, sondern Register. Die findest du im 
Datenblatt. Aber viel wichtiger: Deren Namen unter AVR-GCC findest du im 
entsprechenden Header File im WinAVR inc Verzeichnis. ioxYZ.h

von swen (Gast)


Lesenswert?

damit komme ich auf 2.38mhz (lt. oszi) mitm atmega8 16mhz
1
DDRB  = 0x01;
2
3
while (1)
4
{    
5
  DDRB = (1 << DDB0);
6
  DDRB = (0 << DDB0);
7
}

von Simon K. (simon) Benutzerseite


Lesenswert?

Probier mal:
1
DDRB  = 0x01;
2
3
while (1)
4
{
5
  PINB = (1 << PB0);
6
}

Zumindest bei "neueren" AVRs geht das.

von swen (Gast)


Lesenswert?

Simon K. schrieb:
> Zumindest bei "neueren" AVRs geht das.

klappt beim atmega8(16) nicht....

von spess53 (Gast)


Lesenswert?

Hi

>klappt beim atmega8(16) nicht....

Die sind ja auch alles andere als neu.

MfG Spess

von Swen (Gast)


Lesenswert?

spess53 schrieb:
> Die sind ja auch alles andere als neu.

ach ne... neu sind die nicht iss schon klar. wollt nur mitteilen das es 
beim testen dessen am atmega8 bzw. 16 so nicht ging

von spess53 (Gast)


Lesenswert?

Hi

>ach ne... neu sind die nicht iss schon klar. wollt nur mitteilen das es
>beim testen dessen am atmega8 bzw. 16 so nicht ging

Dazu hätte ein Blick ins Datenblatt gereicht.

MfG Spess

von eklige Tunke (Gast)


Lesenswert?

Simon K. schrieb:
> Probier mal:
>
1
DDRB  = 0x01;
2
> 
3
> while (1)
4
> {
5
>   PINB = (1 << PB0);
6
> }
>
> Zumindest bei "neueren" AVRs geht das.
Muss man das verstehen?
Ich zumindest stehe gerade auffem Schlauch!

von spess53 (Gast)


Lesenswert?

Hi

>Muss man das verstehen?
>Ich zumindest stehe gerade auffem Schlauch!

The Port Input Pins I/O location is read only, while the Data Register 
and
the Data Direction Register are read/write. However, writing a logic one 
to a bit in the PINx Register, will result in a toggle in the 
corresponding
bit in the Data Register.

MfG Spess

von eklige Tunke (Gast)


Lesenswert?

spess53 schrieb:
>>Muss man das verstehen?
>>Ich zumindest stehe gerade auffem Schlauch!
> The Port Input Pins I/O location is read only, while the Data Register
> and
> the Data Direction Register are read/write. However, writing a logic one
> to a bit in the PINx Register, will result in a toggle in the
> corresponding
> bit in the Data Register.
Danke, wieder was gelernt.

von Edimahler (Gast)


Lesenswert?

Simon K. schrieb:
> Aber viel wichtiger: Deren Namen unter AVR-GCC findest du im
> entsprechenden Header File im WinAVR inc Verzeichnis. ioxYZ.h

Danke für den Tipp. Dachte bloss, es gäbe vielleicht noch etwas 
"Geordneteres", wo die Zusammengehörigkeiten bzw. der Aufbau der structs 
etwas übersichtlicher zusammengestellt ist. Geht aber auch so.


Vielen Dank euch allen erneut und beste Grüsse aus der Schweiz,
Simon

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.