avr ersterer schritt
  avr
 
avr-libc Versionen kleiner 1.6

Die Wartezeit der Funktion _delay_ms() ist auf 262,14ms/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 13,1ms warten. Die Wartezeit der Funktion _delay_us() ist auf 768us/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 38,4us warten. Längere Wartezeiten müssen dann über einen mehrfachen Aufruf in einer Schleife gelöst werden.

Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus

#include <avr/io.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert 
   (z.&nbsp;B. durch Übergabe als Parameter zum Compiler innerhalb 
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
   "nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 3686400 definiert"
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
#endif
#include <util/delay.h>     /* in älteren avr-libc Versionen <avr/delay.h> */ 
 
/*
 lange, variable Verzögerungszeit, Einheit in Millisekunden
 
Die maximale Zeit pro Funktionsaufruf ist begrenzt auf 
262.14 ms / F_CPU in MHz (im Beispiel: 
262.1 / 3.6864 = max. 71 ms) 
 
Daher wird die kleine Warteschleife mehrfach aufgerufen,
um auf eine längere Wartezeit zu kommen. Die zusätzliche 
Prüfung der Schleifenbedingung lässt die Wartezeit geringfügig
ungenau werden (macht hier vielleicht 2-3ms aus).
*/
 
void long_delay(uint16_t ms)
{
    for(; ms>0; ms--) _delay_ms(1);
}
 
int main( void )
{
    DDRB = ( 1 << PB0 );        // PB0 an PORTB als Ausgang setzen
 
    while( 1 )                  // Endlosschleife
    {                
        PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
        long_delay(1000);       // Eine Sekunde warten...
    }
 
    return 0;
}

[Bearbeiten] avr-libc Versionen ab 1.6

_delay_ms() kann mit einem Argument bis 6553,5 ms (= 6,5535 Sekunden) benutzt werden. Wird die früher gültige Grenze von 262,14 ms/F_CPU (in MHz) überschritten, so arbeitet _delay_ms() einfach etwas ungenauer und zählt nur noch mit einer Auflösung von 1/10 ms. Eine Verzögerung von 1000,10 ms ließe sich nicht mehr von einer von 1000,19 ms unterscheiden. Ein Verlust, der sich im Allgemeinen verschmerzen lässt. Dem Programmierer wird keine Rückmeldung gegeben, dass die Funktion ggf. gröber arbeitet, d.h. wenn es darauf ankommt, bitte den Parameter wie bisher geschickt wählen.

Die Funktion _delay_us() wurde ebenfalls erweitert. Wenn deren maximal als genau behandelbares Argument überschritten wird, benutzt diese intern _delay_ms(). Damit gelten in diesem Fall die _delay_ms() Einschränkungen.

Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus, avr-libc ab Version 1.6

#include <avr/io.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert 
   (z.&nbsp;B. durch Übergabe als Parameter zum Compiler innerhalb 
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
   "nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 3686400 definiert"
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
#endif
#include <util/delay.h>
 
int main( void )
{
    DDRB = ( 1 << PB0 );        // PB0 an PORTB als Ausgang setzen
 
    while( 1 ) {                // Endlosschleife
        PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
        _delay_ms(1000);        // Eine Sekunde +/-1/10000 Sekunde warten...
                                // funktioniert nicht mit Bibliotheken vor 1.6
 
    }
    return 0;
}


 

 
  Heute waren schon 1 Besucher (12 Hits) hier!  
 
Diese Webseite wurde kostenlos mit Homepage-Baukasten.de erstellt. Willst du auch eine eigene Webseite?
Gratis anmelden