Delay segnale variabile

Ciao a tutti,
vi rompo ancora :slight_smile:

Dunque, avevo realizzato un codice che varia il delay da applicare ad un segnale d’ingresso in base alla frequenza dello stesso ed ai valori salvati in memoria.

nel setup setto il timer1 in questo modo

// initialize Timer1
    cli();          // disable global interrupts
    TCCR1A = 0;     // set entire TCCR1A register to 0
    TCCR1B = 0;     // same for TCCR1B
 
    // set compare match register to desired timer count:
    // turn on CTC mode:
    TCCR1B |= (1 << WGM12);
    TCCR1B &= ~(1 << WGM10);
    TCCR1B &= ~(1 << WGM11);
    // Set for prescaler 8:
    TCCR1B |= (1 << CS11);
    TCCR1B  &= ~(1 << CS12);
    TCCR1B  &= ~(1 << CS10);
    // enable timer compare interrupt:
    TIMSK1 |= (1 << OCIE1A);
    // enable global interrupts:
    sei();

Poi quando arriva il fronte di salita del segnale scatta una routine che esegue questo codice per resettare il timer e farlo contare fino al delay voluto

OCR1A = dt;
      TCCR1B |= (1 << WGM12);
      TCCR1B &= ~(1 << WGM10);
      TCCR1B &= ~(1 << WGM11);
      TCCR1B |= (1 << CS11);
      TCCR1B &= ~(1 << CS12);
      TCCR1B &= ~(1 << CS10);

dopo di che quando il timer1 raggiunge il valore ‚Äúdt‚ÄĚ lancio la routine

ISR(TIMER1_COMPA_vect)
{
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;
  
 
  digitalWrite(PUOUT, 1); 

}

Così alzo il pin di uscita che va a 1 dopo un certo ritardo.
Poi all‚Äôinterno del loop dopo tot microsecondi (anche se so che la funzione micros non andr√† bene perch√® utilizzo il timer 1 per un altra cosa), tiro gi√Ļ la stessa uscita con digitalWrite a 0. Non √® importante che vada gi√Ļ 100 piuttosto che 200 microsecondi dopo (poi al limite si pu√≤ vedere di migliorare questa parte).

Quello che pi√Ļ mi preme √® il fatto che dopo aver fatto
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0;

io setto il registro a 0 e quindi all’arrivo del fronte successivo devo re-inizializzarlo e questo mi porta via ben 30us…

Non esiste un modo per far si che quando ha finito di contare stia fermo a 0 o disabilitarlo in modo solo da farlo ripartire a contare da 0 al fronte successivo? Cioè senza inizializzarlo di nuovo.

Grazie mille

Chiedi a Leo72. E' lui l'esperto di Timer. ;)

Intanto manipola direttamente le porte logiche senza usare la digitalWrite, così risparmi un bel pò di us. Poi non ho capito la questione né cosa stai facendo... i timer sono di per sé contatori perenni per cui ogni volta che arrivano al valore max (che dipende dalla modalità scelta) si comportano in certe maniere, ossia possono invertire la direzione di incremento, possono ripartire da zero, ecc...) ma comunque non si fermano mai. Se vuoi bloccarli devi appunto farlo tu manualmente. Però ogni volta che fermi un timer e lo fai ripartire c'è un certo lag necessario al timer stesso per essere reinizializzato.