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);
}
Jo schrieb:> besser gesagt, verstehe ich nicht warum der Handler nicht freigegeben> sein soll?Jo schrieb:> (0<<OCIE0A)
Ohne ISR (Interrupthandler) keine Freigabe, da dann der Defaultvektor in
der Interruptvektortabelle auf den Resetvektor weist.
> 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?
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.
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!
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.
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
Kontrolliere auch, ob du unter Projektoptionen als Target auch den
ATMEGA168A eingestellt hast. Bei falscher Einstellung liegen die
Vektoren u.U. woanders und der Reset ist klar!
-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?
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
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!
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
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
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.
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
Es war nicht meine Absicht euch zu verwirren. Ich hab den Code auch
vorher getestet, aber es übersehen.
Hab einfach schon viel probiert.
Habs jetzt nochmal bereinigt.
Entschuldigt bitte!
Und mein Programm ist momentan einfach so klein, da ich es selbst aufs
wesentliche reduziert hab, da ich den Fehler mit den Timerinterrupts
nicht finde.