Probleme mit Interrupts

Gast #2477967
Lesenswert?

Hey Zusammen!
Ich habe Probleme mit dem Timer 0 im Zusammenhang mit AVR Studio. Ich 
hab versucht ein früheres Programm das mal funktioniert hat (nicht auf 
AVR Studio programmiert) mittels AVR Studio zu programmieren, da das 
Alte nicht mehr vorhanden ist.

Der Timer 0 zählt auch hoch, aber es wird nie ein Interrupt ausgelöst.

Bin schon ziemlich am Verzweifeln!

Besten Dank schon mal!

Unten mal der Code:


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

int main (void)
{
  IO_Init ();      //Hardware initialisieren
  wdt_disable()

  TCCR0A = 0;
  TCCR0B |= (0<<WGM02)|(1<<CS02) |(0<<CS01) | (0<<CS00);
  TIMSK0 |= (0<<OCIE0A)|(1<<TOIE0);
  sei();

  while(1)
  {
  }

  return(0);
}

ISR (TIMER0_OVF_vect)
{
  PORTD |= (1<<PD2);
}
Gast #2477989
Lesenswert?

>   PORTD |= (1<<PD2);

Du überwachst wahrscheinlich PD2, um festzustellen, ob der Interrupt 
kommt oder nicht?

>   IO_Init ();      //Hardware initialisieren

Wird da auch DDRD für PD2 auf Ausgang gesetzt?

> TCCR0B |= (0<<WGM02)|(1<<CS02) |(0<<CS01) | (0<<CS00);

Prescaler 256
Angenommen du arbeitest mit der Werkseinstellung (1 MHz interner Takt)
1000000/256/256 = 6,6 ms
Hast du ein Messgerät, um das Pintoggeln alle 6,6 ms festzustellen?
Gast #2477994
Lesenswert?

Genau ich überwache den Interrupt jetzt vorläufit mal mit dem PD2, den 
ich auch als Ausgang konfiguriert habe.
Ich habe auch ein Oszilloskop dran, aber mindestens einmal sollte die 
Lammpe ja angehen, dann weiß ich auch ob der Interrupt gekommen ist oder 
nicht. Bis jetzt geht sie nie an.
Gast #2477996
Lesenswert?

Dann setze den Ausgang mal im Hauptprogramm und warte, bis der Interrupt 
sie ausschaltet. Wenn das Setzen im hauptprogramm nicht funktioniert ist 
der Interrupt unschuldig. Dann ist vielleicht die Schaltung fehlerhaft!
Gast #2478008
Lesenswert?

Wenn der Watchdog mal per Fuse WDTON an war (Inhalt der Fuses?), dann 
die Fuse disablen (Schaltung stromlos machen nicht vergessen! 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Watchdog#WDTON_Fuse_zur.C3.BCcksetzen)

Oder wenn der Watchdog per Software aktiv war das wdt_disable() noch 
früher machen 
(http://www.mikrocontroller.net/articles/AVR-Tutorial:_Watchdog#WDT_nach_einem_Reset).

Was macht das Programm im Simulator?
Gast #2478016
Lesenswert?

Geh im Simulator in den Disassembler, nicht in das C-Fenster und 
kontrolliere im Einzelschritt: Über welchen Vektor macht er den Sprung 
nach Init. Anhand der Vektornummer über den der Sprung passiert findest 
du raus, welche ISR fehlt. Die Zuordnung Vektornummer findest du im 
Datenblatt und in avr/include/avr/iomx8.h.
Gast #2478024
Lesenswert?

Kontrolliere in deiner Toolchain, ob es TIMER0_OVF_vect gibt oder ob es 
in deiner (älteren) Toolchain anders definiert ist.

Die Toolchain wirft zwar ggf. eine Warnung bei unbekanntem Namen, aber 
gelegentlich überliest man die, weil sie in einem anderen Fenster in der 
IDE erscheint.

Hier der "Universal"-Code für neue/alte Toolchain aus dem 
AVR-GCC-Tutorial:
1
#ifndef TIMER0_OVF_vect
2
// Für ältere WinAVR Versionen z.B. WinAVR-20071221 
3
#define TIMER0_OVF_vect TIMER0_OVF0_vect
4
#endif
Gast #2478037
Lesenswert?

-Fuses: hab ich geschaut und auch die Stelle von wdt_disable geändert
-Dissambler: hab ich auch versucht und gemerkt, dass er nach sei() in 
Assembler den Aufruf "RJMP      PC-0x0000" bringt. Das heißt der springt 
ins Nirgendwo oder?
#2478054
Lesenswert?

Da dein Programm Syntax Error enthält
1
int main (void)
2
{
3
  IO_Init ();      //Hardware initialisieren
4
  wdt_disable()

geh ich davon aus, dass das wieder mal nicht das richtige Programm ist, 
welches auf deinem µC läuft.

Korrigiert man ihn und ersetzt IO_init() durch
DDRD = (1<<PD2);
funktioniert dein Programm im SImulator
Gast #2478063
Lesenswert?

Nach dem RJMP springt er dann zu 0000001C und dreht da seine Runden und 
geht dann irgendwann wieder zum Start.
Weiß gar nicht ob das wirklich Reset ist

Hab im Anhang mal das Programm als zip.

Bin die nächste halbe Stunde mal kurz weg, aber dann wieder da.

Vielen vielen Dank schon mal für die riesen Hilfe!
Angehängte Dateien:
#2478073
Lesenswert?

Jo schrieb:

> Hab im Anhang mal das Programm als zip.

Was wird das?
1
ISR (TIMER0_OVF_vect)
2
{
3
  PORTD |= (0<<PD2);
4
}

--->     PORTD &= ~(1<<PD2);
wenn du das Bit löschen willst, dass du in main gesetzt hast.


Und du bist sicher, dass du einen einzelnen Puls am PD2 Pin im Oszi 
siehst?
Tausch das mal gegen
1
ISR (TIMER0_OVF_vect)
2
{
3
  PORTD ^= (1<<PD2);
4
}
dann toggelt das Teil und du hast alle Zeit der Welt Messungen 
vorzunehmen.



Und das
1
  PCMSK0 |= (1<<PCINT0);
2

3
....
4

5
ISR (PCINT2_vect)

macht dich nicht irgendwie stutzig?
Gast #2478084
Lesenswert?

zu ISR (TIMER0_OVF_vect):
Der PD2 soll ausgehen als Zeichen, dass der Interrupt ausgelöst wurde
Kann genauso auch umgedreht werden.


zu ISR (PCINT2_vect):
den hätte ich rauslöschen sollen. Der war als Versuch ob überhaupt 
Interrupts ausgelöst werden können und das hat funktioniertl. Tut aber 
nicht zur Sache
#2478094
Lesenswert?

Jo schrieb:

> den hätte ich rauslöschen sollen.

Du sollst in erster Linie das Programm posten, mit dem du auch 
tatsächlich testest! Sonst suchen wir Fehler, die nicht in deinem 
eigentlichen Programm enthalten sind.
Wenn du abspeckst, dann teste das abgespeckte, ob es noch die gleichen 
Symptome zeigt.

Mit dem Posten von extra für das Forum hergerichteten Code, der so nie 
getestet wurde, kann man sich hier ganz schnell unbeliebt machen.
Gast #2478096
Lesenswert?

PORTD |= (1<<PD2) mach, da dann die Lampe gesetzt bleibt. Sie wird ja 
erst ausgemacht, wenn der Controller neu initialisiert, solange ist sie 
an.

Dann sehe ich ob sie durch den Interrupt mindenstens einmal an bzw. aus 
gemacht wurde

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren