mikrocontroller.net

Forum: Compiler & IDEs mega8 Timer Interrupt funktioniert nicht.


Autor: Dominik S. (dominik-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen. Habe ein kleines Problem. Die ISR des Timers 0 wird 
einfach nicht aufgerufen. Ich weiß einfach nicht wo der Fehler sein 
soll.

Hier mein Code:
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>

ISR(TIMER0_OVF_vect)
{
  PORTD = 0x00;
}

int main(void)
{
  DDRC = 0b00111100;
  DDRD = 0b11111111;

  TCCR0 |= (1 << CS00) | (1 << CS01);
  TIMSK |= TOIE0;
  sei();

  PORTD = 0xFF;

  while(1);
}

Zur Info: An Port D hängen LEDs. Sie werden testweise am Anfang 
eingeschaltet und sollten durch die erste ISR wieder aus gehen.

Wo steckt der Fehler??

Gruß, Dominik

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bist Du sicher, dass die LEDs low-side an den Pins hängen? Nur dann 
schaltest Du sie aus, wenn Du eine Null in das Portregister schreibst. 
Wenn die LEDs high-side dranhängen (wie z.B. beim STK500), dann ist es 
genau andersrum.

Autor: Dominik S. (dominik-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin mir zu 1000% ganz sicher, dass ich sie Lowside angelötet habe 
und sie funktionieren auch alle acht.

Autor: loetkolben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Zeile ist falsch:
  TIMSK |= TOIE0;

sollte so sein, da TOIE0 das Bit 0 ist.
  TIMSK |= (1 << TOIE0);

gruß,
Loetkolben

Autor: Dominik S. (dominik-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank, das wars. Keine Ahnung warum ich das an der Stelle falsch 
geschrieben habe...

Autor: Heiko H. (mail23)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe auch mal noch eine Frage zur Timerverwendung. Und zwar habe ich 
versucht dieses Beispiel ( 
http://www.mikrocontroller.net/mc-project/Pages/AV... 
) auf meinen Atmega8 und AVR-Studio 4 anzupassen.

Es wird zwar ohne Fehler compiliert, aber der Simulator meckert: AVR 
Simulator: Uninitialized stack pointer used at 0x0061 ... und ähnliche 
Fehler (screen01)

Auch wenn ich den Code übertrage, tut sich am PortB nicht. Was mache ich 
falsch? Stimmt evtl. etwas mit den Fuse-Bits nicht (screen02)?



Hier mein Code:

#include <avr/io.h>
#include <avr/interrupt.h>

volatile char count, i;

int main (void) {
  DDRB = 255;
  TIMSK = (1<<TOIE0);
  TCNT0 = 0;
  TCCR0 = (1<<CS00) | (1<<CS01);
  sei();
  while (1) {
  i=1;
  }
  return 0;
}

ISR (TIMER0_OVF_vect) {
  if (count == 1) {
    PORTB = 255;
    count--;
    return;
  }
  if (count == 0) {
    PORTB = 0;
    count++;
    return;
  }
}

Autor: Heiko H. (mail23)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch screen02

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Heiko B.

Ich kann den Fehler mit AVR-Studio 4.12 SP2 und WinAVR 20071222 
nicht nachvollziehen.

Die Adresse 0x000061 liegt bei meinem Disassembler-Listing in der ISR 
und in der Nähe des 1. return. Probiere mal die ISR so umzuschreiben, 
dass die ISR nur an einer Stelle verlassen wird z.B. so:

ISR (TIMER0_OVF_vect) {
  if (count == 1) {
    PORTB = 255;
    count--;
  }
  else if (count == 0) {
    PORTB = 0;
    count++;
  }
}

Autor: Hmm... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR (TIMER0_OVF_vect) {
  if (count == 1) {
    PORTB = 255;
    count--;
    return;
  }
  if (count == 0) {
    PORTB = 0;
    count++;
    return;
  }
}

Das ginge bei den neueren AVRs auch einfacher:
ISR (TIMER0_OVF_vect) {
  PINB = 0xff;
}

Damit lassen sich Optimierungs-Bedingte Fehler einfacher ausschliessen 
wenn man eh nur einen Pin toggeln möchte.

Autor: Stefan B. (stefan) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ADD: Disassembler-Listing im Anhang (ohne Optimierung, Atmega8, 1 Mhz)

0x0061 ist auch die Lage der Variablen count im RAM. Möglicherweise 
liegt da dein Problem begraben. Es würde vielleicht helfen, dein 
Disassembler-Listing zu sehen. An den Fuses wird dieses Problem nicht 
hängen.

Autor: Heiko H. (mail23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

danke für deine unterstützung. Leider kommt ein ähnlicher Fehler, wenn 
ich mit else if arbeite. Sind deine Fuse-Bits genauso gesetzt wie meine?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du bist doch im Simulator (screen01.JPG), welche Rolle spielen da die 
Fuses? Ich habe an den Fuses nichts geändert, als ich von Build nach 
Start Debugging im Simulator gewechselt bin. Es würde vielleicht helfen, 
dein Disassembler-Listing zu sehen.

Autor: Heiko H. (mail23)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So musste jetzt erst mal gucken, wie man an das Disassambler-Listing 
dran kommt. Hier ist nun meins:

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aufruf von main() aus dem AVR Startupcode heraus, nach den ganzen 
Initialisierungen wird mit CALL gemacht. Und das mosert der Debugger an.
+00000061:   940E0067    CALL    0x00000067       Call subroutine

Wenn du meine Disassembler-Listing anschaust, dort wird statt CALL ein 
RCALL gemacht und alle JMP am Anfang sind RJMPs.

Es wurde bei deinem Listing beim Kopilieren eine AVR Architektur 
benutzt, für die das (avr-lic interne) Makro _AVR_HAVE_JMP_CALL_ 
definiert ist.

Ich kann mir fast nur vorstellen, dass bei dir als Device kein Atmega8 
sondern ein anderer AVR eingestellt ist. Der Atmega8 braucht die 
Architektur avr4 und bei der ist dieses Makro nicht definiert. In 
einem korrekten Listing für Atmega8 müssen RJMP und RCALL auftauchen.

Kontrolliere bitte mal die Seite (Menü) -> Project -> Configuration 
Options in AVR-Studio, ob du wirklich den atmega8 eingestellt hast. 
Dann einmal alles sauber machen (Clean bei Build...) und neu übersetzen.

Autor: Heiko H. (mail23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

danke für deine Hilfe. Es war wie du es sagtest. Ich hatte tatsächlich 
den falschen Controller eingestellt. Jetzt funktioniert das ganze 
einwandfrei.

Hier nochmal für alle die es intressiert der Code: Ich nutze das 
AVR-Studio Version 4.14. Es wird der Timer0 beim Atmega8 verwendet. 
Alles Pins des PortB blinken bei einer Prozessorfrequenz von 4 MHz mit 
ca. 0,5 Hz. Es ist lediglich ein erstes Beispielprogramm zur Verwendung 
des Timer0. Die genaue Ausgangsfreqenz habe ich nicht ermittelt.

/*Testprogramm Timer0
  Bei einer Prozessorfrequenz von 4 MHz, wird an Port B eine
  Blinkfrequenz von ca. 0,5 Hz ausgegeben*/

#include <avr/io.h>
#include <avr/interrupt.h>

volatile char count=0;
volatile char zeitvorgabe=32;    //32 => ca. 0,5 Hz bei Prozessorfreq. 4 
MHz (16 => ca. 1 Hz)
volatile char zeitvorgabe_halbe=0;

/*volatile Variablen können im Zyklischen-Programm und in
Interruptroutinen verwendet werden*/

int main (void) {    //Zyklische-Programm
  DDRB = 255;      //PortB als Ausgangsport definieren
  TIMSK = (1<<TOIE0);  //Beim Timeroverflow von Timer0 Interruptroutine 
starten
  TCNT0 = 0;      //Timer0 Register auf Null setzen
  TCCR0 = (1<<CS00) | (1<<CS02);  //Vorteiler einstellen (Prozesorfreq. 
durch 1024)
  sei();        //Globale Interrupt-Freigabe setzen
  zeitvorgabe_halbe=zeitvorgabe/2;  //Berechnung zur Zeitvorgaben
  while (1) {}      //Endlosschleife Zyklische Programm
  return 0;        //Rückgabewert der main-Funktion
}

ISR (TIMER0_OVF_vect) {  //InterruptServiceRoutine für Timeroverflow0
  if (count >= zeitvorgabe) {
   count = 0;
    return;
  }
  else if (count >= (zeitvorgabe_halbe)) {
    PORTB = 0;    //LEDs an (STK 500)
    count++;
    return;
  }
  else {
    PORTB = 255;  //LEDs aus (STK 500)
   count++;
    return;
  }
}

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.