Forum: Compiler & IDEs Wo bleibt der Timer1 Overflow Interrupt?


von Mr Smith (Gast)


Lesenswert?

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();

}

von Alex1 (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> #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
Noch kein Account? Hier anmelden.