Timer CTC Mode

Hallo,

Ich versuche gerade mit dem Timer1 im CTC Modus die Zeiten eines Pins High/Low zu steuern.

Später soll in der IRQ ein array ausgelesen werden, mit dem das OCR1A Register beschrieben wird.
Das Ergebnis ist aber nicht wie erwartet.

#define SETOUTPUT DDRB|=(1<<DDB0)
#define SETPIN PORTB|=(1<<PB0)
#define CLEARPIN PORTB&=~(1<<PB0)



void timerint()
{
TCNT1 = 0x0000;  
TCCR1B = (1<<WGM12) | (1<<CS11);      // CTC-Mode; Prescaler 8

TIMSK1  = (1<<OCIE1A);                 // Timer-Compare Interrupt an
 
OCR1A = 1000;                         
sei();
}

ISR (TIMER1_COMPA_vect)
{
static uint16_t lange;  
static uint8_t Kanal; 
static boolean Pin_HIGH; 

  switch (Pin_HIGH)
     {
      case (true): OCR1A=1000;
                   Pin_HIGH=false;
                       CLEARPIN;
                        break;  
       
      case (false):OCR1A=500; 
                   Pin_HIGH=true;SETPIN; 
       
       
     }  
}

Ich sehe mit dem Saleae schon Impulse, bei diesem Code oben erwarte ich ein Tastverhältnis von 2:1.
Ist aber nahezu ein 1:1.
Ist es erlaubt in der IRQ das Compare Register zu verändern ?

Wenn TIMER1_COMPA_vect ausgeführt wird, also Compare Match wird in diesem Modus das TCNT1 auf 0 gestellt, oder ?

PS:
Man könnte den OC1 Pin auch direkt togglen (etc), dies ist aber nicht die Ursache warum das nicht funktioniert

Ist das Arduino oder rein AVR C?

Auf dem Arduino solltest du unbedingt noch das TCCR1A Register auf 0 setzen. Da ist vieles durch PWM vorbesetzt. Verlasse sich da nie darauf dass ein Register 0 ist.

Ist es erlaubt in der IRQ das Compare Register zu verändern ?

Ja

Serenifly:
Ist das Arduino oder rein AVR C?

Ist Arduino :confused:

Verlasse sich da nie darauf dass ein Register 0 ist.

Wie recht du hast, jetzt funktioniert es. Danke !
Ich suche den Fehler schon seit Stunden :astonished:
Hatte aber den Vorteil, fast alles die AVR Timer gelesen zu haben

Ist mir auch schon passiert. Da ist dann mindestens eines der WGM Bits in dem Register gesetzt und der Timer befindet sich in einem ganz anderen Modus.

EDIT:
Und deswegen:

Wenn TIMER1_COMPA_vect ausgeführt wird, also Compare Match wird in diesem Modus das TCNT1 auf 0 gestellt, oder ?

Nein. Das Rücksetzen findet auch ohne Interrupt statt.

Nein. Das Rücksetzen findet auch ohne Interrupt statt.

Ob dieser Interrupt aktiv ist oder nicht spielt hier keine Rolle, das war mir schon klar.

Bei meiner Fehlersuche hatte ich den Verdacht, das in der IRQ TCNT1 > OCR1A sein könnte.
Normalerweise aber nicht möglich, da die ISR (TIMER1_COMPA_vect) immer dann angesprungen wird wenn TCNT1 0 ist.

Wenn man längere erfolglose Fehlersuche betreibt, lässt das rationiale Denken eben rapide nach. :wink: