mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMEGA8 läuft zu schnell


Autor: Asuro Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe dieses Programm eingehackt:
#include "asuro.h"
 int main(void) {
 Init();
 StatusLED(RED);
 while(1)
 {
  unsigned long int i;
  for(i=10000000;i>0;i--);
  StatusLED(RED);
  for(i=10000000;i>0;i--);
  StatusLED(GREEN);   
 };
 return 0;
 }
Der ATMEGA8 hat einen 8MHz Keramikschwinger.
Die Statusled braucht für 10 Rot-Grün-wechsel ca. 8 Sekunden.
Wie kann das sein?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Asuro Anfänger schrieb:

> Wie kann das sein?

Gute Frage.
Eigentlich sollte die LED so schnell blinken, dass du das Blinken nicht 
mehr erkennen kannst. Dies deshalb, weil der Compiler die for-Schleifen 
rausgeworfen hat, da sie offensichtlich keine Funktion erfüllen.

Hast du den Optimizer nicht eingeschaltet?


(Das war jetzt nicht ganz die Antwort, die du erwartet hast :-)
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: asdfsdfa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nö die optimierung kann heir nicht greifen da ja im körper der for 
schleife etwas ausgeführt wird  nähmlich das setzen der led  oder 
10000000x mal das selbe aber er hat ne aufgabe


die eingangsfrage lautet sicher

wieso nur 10 wechsel in 8 sekunden  obwohl doch mit mit 8mhz angetreiben 
und mit 10000000 geteilt sowaas langsames ergibt?

ganz einfach wei er nicht nur zählt sondern auch jedesmal vergelicht und 
wieder zurück zum abzeihen springt sowie i mal  die led einschaltet 
alles das braucht takte

miweasd

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
asdfsdfa schrieb:
> nö die optimierung kann heir nicht greifen da ja im körper der for
> schleife etwas ausgeführt wird  nähmlich das setzen der led

Wo soll das sein?

(Siehst du den kleinen ; am Ende der Zeile mit dem for :-)

Autor: Ber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
>nö die optimierung kann heir nicht greifen da ja im körper der for
>schleife etwas ausgeführt wird  nähmlich das setzen der led  oder
>10000000x mal das selbe aber er hat ne aufgabe
ich glaub du hast da was falsch verstanden, da ist ein ";", d.h. die 
Forschleife ist hier nur eine Verzögerung.

mfg
Ber

Autor: Ber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mist, zu langsam ;-)

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@TE:
wenn du Pausen einfügen willst
benutze die Funktionen _delay_ms und _delay_us aus dem Header 
avr/delay.h oder so

aber nur Konstanten (keine variablen) als Parameter übergeben, sonst 
funktioniert es nicht und der Code wird riesig.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Programmbibliothek des Asuro gibt es die Msleep() Funktion fürs 
Warten.

http://www.asurowiki.de/pmwiki/pub/html/index.html
http://glossar.hs-augsburg.de/Programmbibliothek_des_Asuro

#include "asuro.h"

int main(void) 
{
  Init();
  while(1)
  {
    StatusLED(RED);
    Msleep(1000); // 1s = 1000 ms Warten
    StatusLED(GREEN);   
    Msleep(1000);
  }
  return 0;
}


Autor: asdfsdfa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mist die habsch übersehen

tschuldigung

wer macht denn auch sowas

Autor: Asuro Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die netten Antworten, ich verspreche hiermit feierlich nur 
noch vorgefertigte Bibliotheksfunktionen für die Verzögerung zu 
verwenden!

Aber eine Frage bleibt noch offen:
Warum braucht
  for(i=10000000;i>0;i--);
0,4 Sekunden?
Als Diletant würde man doch erwarten, das ein Microcontroller um von 
10000000 runter auf 0 zu zählen bei 10000000 / 8MHz = 1,25 Sekunden 
braucht.

Der Fachmann würde natürlich wissen, das ein unsigned long int variable 
noch etwa Faktor 5-8 langsamer ist.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du im erzeugten ASM-Code nachgesehen, wie viele und welche 
ASM-Befehle überhaupt erzeugt wurden? Die Ausführungszeit selbst ist 
nämlich abhängig von der Version und Optimierungsstufe des benutzten 
Compilers. Anhand der Beschreibung des AVR Instruction Sets oder mit dem 
Simulator/Debugger und dessen Stoppuhr kann man im Einzelfall die 
Ausführungszeit bestimmen.

Autor: Asuro Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hast du im erzeugten ASM-Code nachgesehen, wie viele und welche
>ASM-Befehle überhaupt erzeugt wurden?

Nein, wo kann ich da nachsehen?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du den Asuro mvon Windows aus programmierst und dabei mit der 
Kombination AVR Studio/WinAVR arbeitest, dann geht das einfach 
inerhalb des AVR Studio. Dort den Simulator/Debugger aufrufen, dein 
Programm laden und die Disassembleransicht anschauen.

Wenn du unter Mac OS X oder Linux oder Windows ohne AVR Studio 
arbeitest, dann kannst du das Makefile so abändern, so dass der C 
Compiler auch ein ASM-Listing erzeugt.

http://www.mail-archive.com/avr-gcc-list@nongnu.or...
https://www.redhat.com/docs/manuals/enterprise/RHE...

Alternativ kannst du auch das fertige Binärfile mit objdump 
disassemblieren

http://gcc.gnu.org/ml/gcc-help/2002-06/msg00133.html

Alternativ kannst du auch einen Disassembler bemühen.

http://www.mikrocontroller.net/articles/Linksammlu...

Autor: Michael_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Keramikschwingern habe ich schon wundersame Sachen erlebt. 
Kontrolliere mal, ob er richtig tickt!

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Asuro Anfänger schrieb:

> Aber eine Frage bleibt noch offen:
> Warum braucht
   for(i=10000000;i>0;i--);
 
> 0,4 Sekunden?

Wie schon weiter oben geschrieben.
Die schleife ist funktionell identisch mit einem einfachen
  i=0;
Der Compiler kann das erkennen, und entsprechend ersetzen ==> Laufzeit 
fast gleich 0.

Außer natürlich du verbietest dem Compiler das Optimieren (-O0, oder 
"volatile"), dann muss der AVR die Schleife wirklich ablaufen, und das 
dauert halt.

Autor: Asuro Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Εrnst B✶ (ernst)

Danke, mit volatile ist ein guter Tip.

Eine Anschlußfrage: wie füge ich ein NOP in die Schleife ein?

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
for(i=10000000;i>0;i--)
{
  ;
}

Autor: Asuro Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
for(i=10000000;i>0;i--)
{
  ;
}


ich dachte eher etwas wie nop oder so!

Autor: rtfm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
asm ("nop");

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn#s Dir anders geschrieben besser gefällt:
asm volatile ("nop");

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.