mikrocontroller.net

Forum: Compiler & IDEs Delay in AVR Studio


Autor: norton (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich bin neu in der yC Welt und habe Probleme mit der _delay_ms(1) 
Funktion.
Ich verwende:
AVR Studio 4.13 Service Pack 2 Build 571 mit GCC
AVR ISP mkII Programmer
ATmega48

Ich möchte eine LED am PORTB zum blinken bringen und verwende folgenden 
Code:
#include <avr/io.h>
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert!"
#define F_CPU 8000000UL
#endif
#include <util/delay.h>
 
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 = 0x00;      // Testeintrag1
        //PORTB = 0x01;      // Testeintrag2
        PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.B. angeschlossene LED
        long_delay(1000);       // Eine Sekunde warten...
    }
 
    return 0;
}

Ich habe die Optimierung auf Os gestellt,
den Takt (F_CPU) richtig eingestellt,
und keine zu grossen Delaywerte laut delay.h verwendet.

Wenn ich das Programm übertrage blinkt die LED nicht. Wenn ich anstatt 
des Toggelns den Testeintrag1 oder Testeintrag2 verwende kann ich die 
LED ein bzw. ausschalten.
Es sieht so aus als würde das Programm nie über die Funktion 
long_delay() kommen. (alles was nachher kommt wird nicht mehr 
ausgeführt)

Ich hoffe jemand kann mir weiterhelfen. Mir fallen keine Möglichkeiten 
mehr ein was ich noch umstellen oder umkonfigurieren könnte.

Danke Norton

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richtigen CPU-Typ eingestellt?  Wenn du das z. B. für einen ATmega88
compilierst und linkst, wird der Stack ins Nirvana gesetzt und das
Dingens stürzt bei der Rückkehr aus der ersten gerufenen Funktion
ab.

Autor: norton (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich überall (Projekt- und Programmer- Einstellungen) auf ATmega48 
eingestellt.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt keinen offensichtlichen Fehler darin.  Kannst du das ELF-File
mal posten?

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sicher bist du dir, dass der Controller tatsächlich mit 8 MHz
läuft? Man kann mit den Fusen auch sehr niedrige Taktraten einstellen.
Kontrolliere, falls noch nicht getan, die Inhalte der drei Fuse-Bytes.

Autor: norton (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier die Fuses Einstellungen

Autor: norton (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier habe ich das ELF File das das AVR Studio erstellt hat. Scheint aber 
sehr kryptisch zu sein.
Wie kommt man im normalfall zu diesem File?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, aber das stammt aus einer anderen C-Quelle als deine da oben,
nicht?  Ungefähr so:
#include <avr/io.h>
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert!"
#define F_CPU 8000000UL
#endif
#include <util/delay.h>

void long_delay(uint16_t ms) {
    for(; ms>0; ms--) _delay_ms(1);
}

void LED_ein( void ) {
    PORTB = 0;
}

void LED_aus( void ) {
    PORTB = ( 1 << PB0 );
}

int main( void )
{
    DDRB = ( 1 << PB0 ) | ( 1 << PB1 ) | ( 1 << PB2 ) |
           ( 1 << PB4 );        // Bits 0, 1, 2 und 4 PORTB als Ausgang setzen
    PORTB = ( 1 << PB2 ) | ( 1 << PB3) |
            ( 1 << PB5 ) | ( 1 << PB6 ) | ( 1 << PB7);

    while( 1 ) {                // Endlosschleife
        PORTB = 0x00;      // Testeintrag1
        PORTB = 0x01;      // Testeintrag2
        //PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.B. angeschlossene LED
        //long_delay(1000);       // Eine Sekunde warten...
    }

    return 0;
}

Mich interessiert aber vor allem das Ergebnis, wenn du long_delay()
auch wirklich rufst.

Die Stackinitialisierung für den ATmega48 stimmt übrigens.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach, guck an: Dein High-Fuse-Byte steht auf 0xCE, d.h. der Watchdog
ist an. Da in dein Programm mit dem Watchdog nichts macht, resettet er
den Controller jedesmal schon bevor der erste Delay abgelaufen ist.

Probier's mal mit dem Wert 0xDE.

Autor: norton (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe den Watchdog abgeschaltet und funktioniert leider immer noch nicht.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du danach auch einen power cycle gemacht?  Einen Wachhund, der
einmal gebissen hat, wird man so schnell nicht wieder los... nur
durch eine korrekte Behandlung oder einen power-on reset.

Autor: norton (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist sicher der Watchdog, denn wenn ich in der long_delay() 
funktion den Watchdog resetiere funktioniert die Funktion.
void long_delay(uint16_t ms) {
    for(; ms>0; ms--)
  {
    _delay_ms(1);
    wdt_reset();
  }

Jetzt würde das ganze zwar funktionieren, aber ich würde trotzdem gerne 
wissen wie ich den Watchdog abschalten kann?
Wo muss ich ihn überall disablen und was muss ich wie reseten damit der 
Hund verschwindet?

Danke für die Hilfe!

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

Bewertung
0 lesenswert
nicht lesenswert
Es müsste eigentlich reichen, das Fusebit abzuschalten
und danach einmal Strom aus - Strom ein.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ norton (Gast)

>Jetzt würde das ganze zwar funktionieren, aber ich würde trotzdem gerne
>wissen wie ich den Watchdog abschalten kann?

Der ist bei den meisten AVRs normal ausgeschaltet. Einige können ihn per 
AVR Fuses einschalten.
Das Datenblatt ist dein Freund.

MfG
Falk

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.