Forum: Mikrocontroller und Digitale Elektronik Mikrocontroller langsamer als erwartet


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Gert (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Guten Abend.

Hab hier einen Mega8 der mit einem internen Takt von 4MHz läuft.

Hab ein Programm geschrieben das immer den Port B.3 invertiert.
while(1){

PORTB.3=~PORTB.3
}

Am Oszi gemessen bekomme ich nur eine Rechecksignal mit ca. 63 kHz. Das 
wundert mich ein wenig, eigentlich hätte ich ja mit mindestens einem 
dreistellingen kHz-Wert gerechnet. So viele Befehle stecken doch da 
nicht dahinter, oder?

Gert

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
> Das wundert mich ein wenig, eigentlich hätte ich ja mit mindestens einem
> dreistellingen kHz-Wert gerechnet. So viele Befehle stecken doch da
> nicht dahinter, oder?
Wissen ist Macht!
Schau dir das Assembler-Listing an.

von Gert (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ist das eigentlich neuerdings Mode, in Rätseln zu sprechen?

von JUPP (Gast)


Bewertung
0 lesenswert
nicht lesenswert
wer weiß, wer weiß :P

von spess53 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ist das eigentlich neuerdings Mode, in Rätseln zu sprechen?

Welchen Teil hast du nicht verstanden?

MfG Spess

P.S. CKDIV8 noch gesetzt?

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
spess53 wrote:
> Welchen Teil hast du nicht verstanden?

Ich tippe auf:

Lothar Miller wrote:
> Schau dir das Assembler-Listing an.

bin mir aber noch nicht ganz sicher...

von Falk B. (falk)


Bewertung
0 lesenswert
nicht lesenswert
@Gert (Gast)

>dreistellingen kHz-Wert gerechnet. So viele Befehle stecken doch da
>nicht dahinter, oder?

Wenn der Compiler was taugt dauert die Schleife 5 Takte, macht effektiv 
einen Teiler durch 10 = 400 kHz.
Und du bist sicher, dass dein AVR auf 4 MHz läuft? Die meisten laufen ab 
Werk mit 1MHz.
Poste mal VOLLSTÄNDIGEN Code.

MFG
Falk

von Gert (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Jupp ... der lief nicht auf 4MHz. Danke für den Tipp.
Hab's jetzt

CKSEL3=0
CKSEL2=0
CKSEL1=1
CKSEL0=1

eingestellt. Das sollten ja 4MHz sein, wenn ich das im Datenblatt 
richtig verstanden habe.
Messe jetzt ca 260 kHZ...

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Ist aber immer noch nicht das Optimum, zeig mal das Assembler Listing.

bzw. schau mal wie schnell das hier bei dir ist:
#include <avr/io.h>

int main(void){
 DDRB |= (1<<DDB3);
 while(1){
  if (PORTB & (1<<PB3)) PORTB &= ~(1<<PB3);
  else PORTB |= (1<<PB3);
 }
 return 0;
}

von Klaus (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Falk  wrote:

>Wenn der Compiler was taugt dauert die Schleife 5 Takte

Gert wrote:

>Messe jetzt ca 260 kHZ...

ups... da ist noch ein 6ter. ;)

Marke:
  cbi xx     ;1 Takt
  sbi xx     ;1 Takt
  rjmp Marke ;2 Takte

es geht auch mit 4 Takten -> 1MHz/2 =500KHz

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Aus meinem Beispiel oben macht der Compiler auch nur 3 bis 4 Takte:

6:          if (PORTB & (1<<PB3)) PORTB &= ~(1<<PB3);
+00000030:   9BC3        SBIS    0x18,3
+00000031:   C002        RJMP    PC+0x0003

+00000032:   98C3        CBI     0x18,3
+00000033:   CFFC        RJMP    PC-0x0003

7:          else PORTB |= (1<<PB3);
+00000034:   9AC3        SBI     0x18,3
+00000035:   CFFA        RJMP    PC-0x0005

also entweder 30, 32, 33 oder 30, 31, 34, 35...

von eProfi (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Leute, wenn es um das schnelle Toggeln eine Ports geht, gibt es bei den 
neueren AVRs einen Befehl dafür: das Schreiben eines 1-Bits ins 
PIN-Register (glaub ich zumindest, bitte selbst nachschauen: Toggle).
Dann sollte es in 2 oder 3 Zyklen gehen.

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Nur dass Gert offenkundig keinen GCC verwendet. Bleibt abzuwarten, was 
sein Compiler draus gemacht hat. Und ob die Optimierung überhaupt 
eingeschaltet war.

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Tim T. wrote:

> also entweder 30, 32, 33 oder 30, 31, 34, 35...

Was auf 6 bzw. 7 Takte rausläuft (CBI,SBI,RJMP=2).

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
A. K. wrote:
> Was auf 6 bzw. 7 Takte rausläuft (CBI,SBI,RJMP=2).

Stimmt, da hast du recht. Es sind 7 Takte für einen Zyklus ergo 
irgendwas um 571 kHz und damit etwas mehr als doppelt soviel wie vom OP 
gemessen...

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
eProfi wrote:

> Leute, wenn es um das schnelle Toggeln eine Ports geht, gibt es bei den
> neueren AVRs einen Befehl dafür: das Schreiben eines 1-Bits ins
> PIN-Register (glaub ich zumindest, bitte selbst nachschauen: Toggle).

Nützt aber nix beim Mega8. Ausserdem dürfte es hier nicht um Wettrennen 
gehen, sondern um ein Missverhältnis zwischen Erwartung und Realität.

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Tim T. wrote:

> Stimmt, da hast du recht. Es sind 7 Takte für einen Zyklus ergo
> irgendwas um 571 kHz und damit etwas mehr als doppelt soviel wie vom OP
> gemessen...

Nö. Der Gesamtzyklus sind 6+7=13 Takte, also rund 300KHz am Pin.

von Klaus (Gast)


Bewertung
0 lesenswert
nicht lesenswert
ich korregiere mich lieber selber

Marke:
  cbi xx     ;2 Takt
  sbi xx     ;2 Takt
  rjmp Marke ;2 Takte

=6 Takte  sorry Klaus ;(

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
A. K. wrote:
> Tim T. wrote:
>
>> Stimmt, da hast du recht. Es sind 7 Takte für einen Zyklus ergo
>> irgendwas um 571 kHz und damit etwas mehr als doppelt soviel wie vom OP
>> gemessen...
>
> Nö. Der Gesamtzyklus sind 6+7=13 Takte, also rund 300KHz am Pin.

Stimmt, ich hab da bei den 2 Taktern gepennt, es sind natürlich 13 Takte 
und 307 kHz am Pin :)

von Klaus (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Da eine "L" + eine "H" Periode zuerzeugen ist.

gild

(nach meiner Rechnung) (4MTakte/6Takte) / 2 rund 333KHz

von Gert (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Benutze CodeVisionAVR ...
#include <avr/io.h>

int main(void){
 DDRB |= (1<<DDB3);
 while(1){
  if (PORTB & (1<<PB3)) PORTB &= ~(1<<PB3);
  else PORTB |= (1<<PB3);
 }
 return 0;
}


... es werden lauter Feldermeldungen angezeigt

von Forenbeobachter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> ... es werden lauter Feldermeldungen angezeigt

Das ist ja schön. Google mal nach "Fehlermeldung". Die Lösung deines 
Problems sollte sich relativ weit oben unter den Suchergebnissen 
befinden, denk ich mal.

von AmFeld (Gast)


Bewertung
0 lesenswert
nicht lesenswert
"Feldermeldungen"en sind doch üblich.

... von ungefähr 4.540.000 für Feldermeldung

Bist du nicht anpassungsfähig oder ein Erbsenzähler ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.