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


von Asuro Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

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

von Karl H. (kbuchegg)


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-Tutorial#Warteschleifen_.28delay.h.29

von asdfsdfa (Gast)


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

von Karl H. (kbuchegg)


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 :-)

von Ber (Gast)


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

von Ber (Gast)


Lesenswert?

Mist, zu langsam ;-)

von Vlad T. (vlad_tepesch)


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.

von Stefan B. (stefan) Benutzerseite


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
1
#include "asuro.h"
2
3
int main(void) 
4
{
5
  Init();
6
  while(1)
7
  {
8
    StatusLED(RED);
9
    Msleep(1000); // 1s = 1000 ms Warten
10
    StatusLED(GREEN);   
11
    Msleep(1000);
12
  }
13
  return 0;
14
}

von asdfsdfa (Gast)


Lesenswert?

mist die habsch übersehen

tschuldigung

wer macht denn auch sowas

von Asuro Anfänger (Gast)


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
1
  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.

von Stefan B. (stefan) Benutzerseite


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.

von Asuro Anfänger (Gast)


Lesenswert?

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

Nein, wo kann ich da nachsehen?

von Stefan B. (stefan) Benutzerseite


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.org/msg02900.html
https://www.redhat.com/docs/manuals/enterprise/RHEL-3-Manual/devtools/s1-assembler-listings.html

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/Linksammlung#Disassembler

von Michael_ (Gast)


Lesenswert?

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

von Εrnst B. (ernst)


Lesenswert?

Asuro Anfänger schrieb:

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

Wie schon weiter oben geschrieben.
Die schleife ist funktionell identisch mit einem einfachen
1
  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.

von Asuro Anfänger (Gast)


Lesenswert?

@ Εrnst B✶ (ernst)

Danke, mit volatile ist ein guter Tip.

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

von Timo (Gast)


Lesenswert?

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

von Asuro Anfänger (Gast)


Lesenswert?

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


ich dachte eher etwas wie nop oder so!

von rtfm (Gast)


Lesenswert?

asm ("nop");

von Timo (Gast)


Lesenswert?

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

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.