Ich bin am verzweifeln, weshalb tritt der Timer1 Overlfow Interrupt nie ein? Please help. ;------------------------------------ #include <avr/io.h> #include <stdint.h> #include <avr/signal.h> #include <avr/delay.h> #include <avr/interrupt.h> void Inc_min (void); //Alles unsigned 8 Bit Integer Variabeln volatile uint8_t min_1er; volatile uint8_t min_10er; volatile uint8_t h_1er; volatile uint8_t h_10er volatile uint8_t Sec_Counter; int main(void) { //Datenrichtungen Ports DDRB = 0x01; //PB0 -->Led cli(); TCNT1H = 0xC2; TCNT1L = 0xF7; //Zähler mit 49911 laden TCCR1B = 0x05; //f:1024, Timer1 starten TIMSK |= (1 << 7); //TOV1 Interrupt freigeben sei(); //Interrupts generell erlauben do //Hauptprogramm Schleife { // Schleife des Hauptprogramm } while (1); } SIGNAL (SIG_OVERFLOW1) { cli(); PORTB = 1; // Led dran, zur optischen Kontroller ob Interrupt jemals passiert Inc_min(); TCNT1L = 0xF7; //Zähler vorladen TCCR1B = 0x05; //f:1024, Timer1 starten TIMSK |= (1 << 7); //TOV1 Interrupt enable sei(); }
Hallo... hier ist die initialisierung von meiner Routine. Nur noch die generellen Intrrupts frei geben. // functions for Timer1 #define TIMER_1_CNT 0xff64; // 0.01 sec, use AVRcalc to calculate these values // (TCNT1H=0xff, TCNT1L=0x64) /* this constants should be in <avr/io8515.h> !! */ #define TMC16_CK1024 (_BV(CS12) + _BV(CS10)) void InitTimer1 (void) { TCCR1A = 0x00; // disable PWM and Compare Output Mode TCCR1B = TMC16_CK1024; // use CLK/1024 prescale value TCNT1 = TIMER_1_CNT // reset TCNT1 high/low byte TIMSK = _BV(TOIE1); // enable TCNT1 overflow } Alex
> #define TIMER_1_CNT 0xff64; // 0.01 sec, use AVRcalc to
calculate
Pah. Nimm besser den Präprozessor, als nicht nachvollziehbare
Hexwerte da reinzuschreiben.
1 | #include <stdint.h> |
2 | |
3 | #define F_CPU 16000000ul
|
4 | #define TMR1_PRE 1024 /* prescaler */ |
5 | #define HZ 100 /* clock rate, i.e. 0.01 s ticks */ |
6 | #define TIMER_1_CNT ((uint16_t)(-(F_CPU / TMR1_PRE / HZ)))
|
Insgesamt würde ich die Methode aber nicht empfehlen. Die Genauigkeit leidet unter der Interrupt-Latenz (du musst also eigentlich zu TIMER_1_CNT noch einen `fuzz factor' addieren). Für alle Timer, die es besitzen, nimmt man besser den output compare zusammen mit dem CTC-Modus (clear timer on compare match), dann bist du komplett unabhängig von der Interruptlatenz. Außerdem kann dir die Hardware gleich ohne Interrupt dann schon deine LED einschalten :-) (am OC1A-Ausgang). > SIGNAL (SIG_OVERFLOW1) > > { > > cli(); Unnütz. Interrupts sind bereits abgeklemmt. > Inc_min(); Ungünstig. Durch den Aufruf einer Funktion zwingst du den Compiler, alle gemäß ABI durch die Funktion änderbaren Register zu retten. > TIMSK |= (1 << 7); //TOV1 Interrupt enable Erstens lieber symbolische Werte benutzen, das reduziert die Irrtumswahrscheinlichkeit und macht den Code für andere (und dich selbst :) lesbarer. Zweitens, falls der Kommentar mit der Realität übereinstimmt überflüssig -- der overflow-Interrupt war ja schon freigeschaltet. > sei(); Auch unnütz. Das RETI am Ende der ISR gibt die Interrupts eh' wieder frei. So ganz verstehe ich aber nicht, warum die ISR nicht triggern soll. Der Zeitkonstantenwirrwar ist etwas unübersichtlich. Bist du dir sicher, dass du lange genug gewartet hast? Was für ein Prozessor ist das eigentlich?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.