www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Funktion "_delay_ms()" nicht ausreichend


Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi...

Auf meinem ATmega16, mit einem externen 8MHz Oszillator, lasse ich ein
kleines Programm laufen und möchte zwischen jedem Schritt eine gewisse
Zeit warten... Sagen wir mal 0,5s!

Die Funktion _delay_ms() ist leider dafür nicht geeignet, da für mich
die maximale Wartezeit etwa 35 ms beträgt... Habt ihr einen Vorschlag
was ich noch machen könnte?

Danke schonmal

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sie mehr,als aufrufen :-)

Autor: Korrekturleser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
+"einmal"

Autor: marc989 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

längere Delays sind in einem Programm sowieso nicht die beste lösung.
Vielleicht kannst deine Programmteile ja per Timer interrupt aufrufen?
oder du verweilst in einer whileloop in der du permanent einen
timerflag abrufst, ob dieser gesetzt wurde. zumindest ist diese zeit
dann auch genauer als eine lange nop-wait schleife.

gruß marc

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Marc...

Das mit dem Timer interrupt werde ich versuchen. Weiss zwar noch nicht
wie das funktioniert aber wozu gibt es Tutorials?? ;)

Gruss

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Korrekturleser:
"," = "m" ;-)

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ne eigene delay-Funktion mit einem freien Timer schreiben.

Beispiel für ATMega 16 mit 8 MHz:

//Erzeugen einer Wartezeit in Millisekunden (max. 16383)
void wait_ms(unsigned int msecs)
{
        //Zaehler mit 4 multiplizieren (4 x 250us = 1ms)
        msecs <<= 2;
        OCR0 = 250;     //Compare-Register laden
        TIFR |= 1 << OCF0; //Compare-Flag loeschen
        TCCR0 = 0x0a;   //Timer 0 starten, Taktteilung durch 8
        while(msecs) // Warten bis Zeit abgelaufen
        {
                //Warte bis Compare-Ereignis
                while(!(TIFR & (1 << OCF0)));
                msecs--;        //dekrementiere Zaehler
                TIFR |= 1 << OCF0; //Compare-Flag loeschen
        }
        TCCR0 = 0x00;   //Timer 0 deaktivieren
}

Mit Interrupt isses natürlich eleganter. Aber wenn der uC eh sonst nix
zu tun hat...

Autor: Korrekturleser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael: Ja so war es sicher gedacht. Hab mich schon gewundert, was das
 Komma soll ;)

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn du definitiv sowieso nichts anderes als warten willst, warum nicht
delay()? Kein Problem, dafür muss man nicht mit Timer arbeiten, aber
man kann natürlich.
Kenne deine delay-funktion nicht - ich kenne sie mit int-Parameter. Und
das bedeutet, bis zu 65535 ms max. Verzögerung.

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die _delay_ms() Funktion aus avr/delay.h hat eine maximale delay Zeit
die kleiner ist als der Wert, den man übergeben kann. Bitte im
Header-File nachlesen, da steht die Formel drin.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube Crazyhorse wollte da auf was anderes hinaus.

for (unsigned int i;i<=65535;i++);

voila

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nö.
Ich benutze CodeVision, und der delay_ms-Funktion kann ich direkt den
Wert in ms übergeben.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
achso ok. :D

PS: Wollte mir auch mal Codevision zulegen. Gibts irgndwo einen
Bericht, der mich mal so richtig von dem Compiler überzeugt? :D

Autor: leo9 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Gibts irgndwo einen
>> Bericht, der mich mal so richtig von dem Compiler überzeugt? ..

wozu einen Bericht lesen, lad dir die Demo-Version und du wirst
begeistert sein. Hat mir (als bekennenden "Pascaler") im Gegensatz
zum gcc den Einstieg in c für die Atmels mehr als erleichtert.


Grüße leo9

Autor: Simon Küppers (ohne Login) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, Demo. Gute Idee eigentlich.
Werde ich mal tun.

Kann man sich auch den erzeugten Assemblercode anschauen? Denke mal
schon..

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo und wo ist das Problem ?

Wozu gibt es denn Schleifen unter C:
void long_delay_ms( unsigned long ms )
{
  while( ms-- )
    _delay_ms( 1 );
}

Damit kommst Du bis auf 49 Tage, das sollte ja reichen.


Die Entwickler des GCC (und ich auch) denken eben, daß sehr lange
Delays schlechter Programmierstil sind, d.h. die Performance zur Sau
machen und die Programmerweiterung sehr erschweren.

Immerhin ist ein Delay von 1ms schon riesige 20.000 verlorene Zyklen
bei 20MHz, wo die CPU vieles anderes machen könnte.

Wenn man also etwas mehr programmieren will, als nur einen Timer, kommt
man mit Monsterdelays nicht weit.


Peter

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.