Pages: [1]   Go Down
Author Topic: Delay segnale variabile  (Read 346 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 0
Posts: 261
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti,
vi rompo ancora  smiley

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

Code:
// 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

Code:
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

Code:
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
« Last Edit: December 31, 2012, 08:07:23 am by ekjk » Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 110
Posts: 6989
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Chiedi a Leo72. E' lui l'esperto di Timer.  smiley-wink
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Pages: [1]   Go Up
Jump to: