Forum: Mikrocontroller und Digitale Elektronik CTC Timer Ein- und Auschalten


von limbo! (Gast)


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

von MeinerEiner (Gast)


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.

von limbo! (Gast)


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

von Karl H. (kbuchegg)


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

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.