Forum: Mikrocontroller und Digitale Elektronik Wie Controller "warten" lassen?


von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Hallo,
ich beginne gerade mit dem Programmieren vom ATMEGA8. Das ISP- Flashen 
mit dem USBprog , und so funktioniert auch alles, und eine LED leuchtet 
auch schon. Nun will ich diese LED zum Blinken bringen. Dazu muss ich 
den ATMEGA8 irgendwie kurz warten lassen, bis er den Port wieder 
anschaltet, bzw. ausschaltet. Ich hab im Internet nur Lösungen gefunden, 
die mit einem Timer arbeiten, und das ist noch ein wenig zu schwierig 
für mich. Kann man den Controller auch irgendwie anders warten lassen?
Weiß jemand ein einfaches Beispiel dazu, oder ein Tutorial?
Ach ja: Ich programmiere in C, und benutze AVR Studio mit dem WinGCC- 
Plugin.
Vielen Dank schon einmal im Voraus.
Gruß, Steffen

von Michael (Gast)


Lesenswert?

_mdelay (int milliseconds)

oder so ähnlich hiess die Funktion.

Dazu brauchte man noch ein

#include <delay.h>

wenn ich mich recht entsinne.

von Robin T. (rotoe) Benutzerseite


Lesenswert?

_delay_ms(t);

#include <util/delay.h>

von J.R (Gast)


Lesenswert?

Wie schon angesprochen sind _delay_us oder _delay_ms deine 
Freunde.Weitere interessante Fragen und Antworten findes du hier :

http://www.mikrocontroller.net/articles/AVR-Tutorial

schönes Wochenende
J.R

von J.R (Gast)


Lesenswert?


von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Vielen Dank für die schnellen Antorten, hat mir schon sehr 
weitergeholfen!!!!!

J.R wrote:
> Wie schon angesprochen sind _delay_us oder _delay_ms deine
> Freunde.Weitere interessante Fragen und Antworten findes du hier :
>
> http://www.mikrocontroller.net/articles/AVR-Tutorial
>
> schönes Wochenende
> J.R

Ja, das Tutorial ist schon sehr gut, aber leider sind alle Beispiele in 
Assembler, und da versteh ich kein Wort ;-).

Ich hab mein Programm jetzt mal mit _delay_ms umgeschrieben, aber ich 
muss doch noch irgendwie die CPU Frequenz einstellen, damit alles 
korrekt funktioniert. Wie macht man das?

Vielen Dank schon einmal im Voraus.
Gruß, Steffen

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Ok, inzwischen hab ichs herausgefunden. Es geht mit #define F_CPU. Das 
Programm läuft auch tadellos. Das einzigste, was mich wundert, ist dass 
mit dem kleinen Programm hier,
1
#include <avr/io.h>          // (1)
2
#include <util/delay.h>
3
#define F_CPU 1000000 
4
int main (void) {            // (2)
5
 
6
   DDRB  = 0xff;             // (3)
7
   while(1) {
8
   _delay_ms(1000);
9
   PORTB = 0x01;             // (4)
10
   _delay_ms(1000);
11
   PORTB = 0x00;
12
   }
13
   }
nach dem Builden folgende Meldung kommt:

Build started 27.6.2008 at 15:19:20
AVR Memory Usage
----------------
Device: atmega8
Program:    3376 bytes (41.2% Full)
(.text + .data + .bootloader)
Data:          8 bytes (0.8% Full)
(.data + .bss + .noinit)
Build succeeded with 0 Warnings...

Bedeutet das jetzt, das mit diesem kleinen Programm schon 41,2% des 
ATMEGA8 voll sind, oder erst 0,8%?
Vielen Dank schon einmal im Voraus.
Gruß, Steffen

von J.R (Gast)


Lesenswert?

schau dir die Dokumentation zu _delay_ms an. (Hat was mit dem 
Wertebereich zu tun)

von yalu (Gast)


Lesenswert?

> Bedeutet das jetzt, das mit diesem kleinen Programm schon 41,2% des
> ATMEGA8 voll sind, oder erst 0,8%?

Ersteres :)

Das Programm wird aber gewaltig schrumpfen, wenn die die Optimierung
des Compilers aktivierst. Da das fast jeder, der zum ersten mal mit
den Delay-Funktionen hantiert, falsch macht, wird bei neueren
AVR-Libc-Versionen die Warnung

  "Compiler optimizations disabled; functions from <util/delay.h>
  won't work as designed"

ausgegeben.

von holger (Gast)


Lesenswert?

Du könntest auch die delay-Funktion durch folgendes ersetzten:


i=0;
while (i<1000){
 i++;
}




bzw. verschachtelt

i=c=0;
while (i<1000){
   while (c<1000){
      i++;
   }
   c++;
}

Ist dann zwar nicht auf die mikrosekuinde genau, aber für eine LED 
reicht es allemal aus!

von Peter D. (peda)


Lesenswert?

holger wrote:

> Ist dann zwar nicht auf die mikrosekuinde genau, aber für eine LED
> reicht es allemal aus!

Da wird Dir der GCC aber was husten.
Ohne volatile fliegt das in hohem Bogen raus.


Peter

von Stefan E. (sternst)


Lesenswert?

Und die zweite Variante wird er wohl direkt in eine Endlosschleife 
optimieren. ;-)

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Vielen Dank für die Antworten erstmal!!
holger wrote:
> Du könntest auch die delay-Funktion durch folgendes ersetzten:

> i=0;
> while (i<1000){
>  i++;
> }

> bzw. verschachtelt
>
> i=c=0;
> while (i<1000){
>    while (c<1000){
>       i++;
>    }
>    c++;
> }
>
> Ist dann zwar nicht auf die mikrosekuinde genau, aber für eine LED
> reicht es allemal aus!
Genau so dachte ich es mir am Anfang auch, das man einfach eine Schleife 
macht, die eine Weile braucht, bis sie komplett hochgehzählt hat, und 
dadurch Zeit verbrät. Allerdings ist das meiner Meinung nach ziemlich 
provisorisch, deswegen hab ich eben noch nach der "professionellen" 
Lösung gesucht.
@ yalu: Genau die Meldung, die du gepostet hast, kam bei mir auch. Als 
ich dann die CPU Frequenz eingegeben habe, hat er den Build dann ohne 
Warnung gemacht. Wie aktiviert man denn die Optmierung des Compilers???
Vielen Dank schon einmal im Voraus.
Gruß, Steffen

von J.R (Gast)


Lesenswert?

im AVR Studio unter Projekteinstellunegn ?

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Ok, danke an alle!!!
Nun hab ich die Optimierung auf 3 eingestellt, und nun hat mein Programm 
nur noch eine Größe von 154 bytes, und belegt damit 1.9% des 
Controllers. Das Program wird mit 3 Warnings gebuildet, läuft aber 
trotzdem ohne Probleme.
Gruß, Steffen

von Peter (Gast)


Lesenswert?

Hallo,
@Stefan 3 ist nicht unbedingt das besten. Ich könnte mir vorstellen das 
die Delay.h für die Optimierung s geschrieben wurde da dies 
normalerweise Standert ist.
Wo der genaue Unterschied bei den Optimierungen ist kann ich dir leider 
nicht sagen. Vieleicht weis des einer von usneren Experten.
Gruß
Peter

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Ok, ich hab das Projekt nun mit -0s Optimiert. Nun klappt alles, so wie 
es sein soll, nur ich hab ein wenig Probleme mit dieser dämlich 
aufgebauten Bargrafledanzeige. Naja, ich werd mir jetzt warsch noch ne 
andere holen, mit der klappts dann hoffentlich besser. Also nochmals 
vielen Dank an alle!!!!
Gruß, Steffen

von yalu (Gast)


Lesenswert?

Die Optimierungsstufen 1, 2 und 3 optimieren die Geschwindigkeit, s
optimiert die Code-Größe, wobei bei 1, 2 und s das eine meist mit dem
anderen einher geht. Für AVRs sind deswegen 2 oder s meistens richtig,
sie liefern beide ähnlich kompakten und schnellen Code. Welche von
beiden man nimmt, ist eine Frage des Geschmacks bzw. des
Ausprobierens.

Die Stufe 3 versucht, ohne Rücksicht auf die Code-Größe noch ein paar
weitere Prozessorzyklen herauszuschinden. Da werden dann bspw.
Schleifen auseinandergewickelt (loop unrolling), d. h. mehrere
Schleifenrümpfe einfach hintereinanderkopiert. Das spart zwar etwas
Schleifenoverhead ein, dafür wird der Code u.U. deutlich länger. Wenn
man noch viel Flash-Speicher übrig hat, kann man ihn natürlich auf
diese Weise nutzen, anstatt ihn vergammeln zu lassen.

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Ach so, das war warscheinlich der Grund weshalb mein Programm nicht 
einwandfrei lief. Ich habe nämlich Optimierungsstufe 3 eingestellt, und 
das war für mein Programm vielleicht nicht so gut. Nun hab ich Stufe s, 
und mit der klappts einwandfrei.
Gruß, Steffen

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.