CTC Timer Ein- und Auschalten

Gast #1494485
Lesenswert?

Hallo Leute!

Hab da ein kleines Problem. Ich will eine 7-Segment Stoppuhr 
programmieren, die den CTC Counter verwendet. Ein und ausgeschalten wird 
das ganze über den externen Interrupt INT0. Mit einem normalen Counter 
hat das ganze schon funktioniert. Allerdings war das viel zu ungenau. 
Also wollte ich es mit CTC versuchen.
Das Problem: Beim Betätigen der Taste kommt er zwar in die ISR von INT0 
aber startet den Timer nicht!

Hier mal der relevante Code:

ISR(INT0_vect)
{
  if(OCIE1A)      //Wenn timerinterrupt läuft
  {
    TIMSK= (0 << OCIE1A);  //Timerinterrupt ausschalten
  }else
  {
    TIMSK= (1 << OCIE1A);  //ansonsten Timerinterrupt einschalten
  }
  _delay_ms(20); //Schalterentprellen
}


int main (void) {

//*****************
// Initialisierung
//*****************

   DDRB = 0xFF;   //PORTB auf Ausgang setzen (7-Segmente)
   DDRC = 0xFF;    //PORTC auf Ausgang für Segmentwahl

   //Interrupt konfigurieren
   MCUCR = (1<<ISC01);  //Int0 auf fallende Flanke konfigurieren
   GICR = (1<<INT0);  //Int0 aktivieren

   //Timer Configurerien
   OCR1A = 39999;
   TCCR1B=( 1 << WGM12 ) | ( 1 << CS10 );
   TIMSK= (0 << OCIE1A);

   sei();


Was mach ich falsch?

Grüße
Markus
Gast #1494492
Lesenswert?

Evtl. könnten es die beiden Zeilen sein:
   TIMSK= (0 << OCIE1A);  //Timerinterrupt ausschalten
   TIMSK= (1 << OCIE1A);  //ansonsten Timerinterrupt einschalten

Würd ich anders schreiben:

    TIMSK &= ~(1 << OCIE1A);  //Timerinterrupt ausschalten
    TIMSK |=  (1 << OCIE1A);  //ansonsten Timerinterrupt einschalten

Und ne delay hat in ner ISR nix zu suchen.
Wird die ISR aufgerufen, während sie noch läuft, gibts Chaos.


Ausserdem ist die Abfrage if(OCIE1A) immer wahr, da OCIE1A ein fester 
Wert ist und sich nie ändern wird.
Gast #1494516
Lesenswert?

Hallo!

Aja vielen Dank für deine Antwort.
Das delay wurde jetzt gelöscht - funktioniert auch ohne.
Obwohl das
TIMSK= (0 << OCIE1A);  //Timerinterrupt ausschalten
TIMSK= (1 << OCIE1A);  //ansonsten Timerinterrupt einschalten

funktioniert, hab ich es jetzt umgeschrieben auf deine Art.

Und das if(OCIE1A) wurde jetzt auf if(TIMSK == 0b00010000) umgeändert. 
Jetzt klappt alles ganz toll!

Vielen Dank für die Hilfe!
Grüße
Markus
#1494532
Lesenswert?

limbo! schrieb:

> Das delay wurde jetzt gelöscht - funktioniert auch ohne.
> Obwohl das
> TIMSK= (0 << OCIE1A);  //Timerinterrupt ausschalten
> TIMSK= (1 << OCIE1A);  //ansonsten Timerinterrupt einschalten
>
> funktioniert,

aber nur zufällig.
Eine 0 kann man nach links schieben sooft man will, sie bleibt immer 
eine 0.

> TIMSK= (0 << OCIE1A);  //Timerinterrupt ausschalten

ist also nichts anderes als
  TIMSK = 0;

Dein Glück ist, dass du noch keine anderen BIts in TIMSK benutzt hast.


> Und das if(OCIE1A) wurde jetzt auf if(TIMSK == 0b00010000) umgeändert.
> Jetzt klappt alles ganz toll!

Autsch.
Weiter unten hast du das so schön geschrieben. Warum nicht hier?

   if( TIMSK & ( 1 << OCIE1A ) )

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