Go Down

Topic: Timer 1 usato due volte in modi diversi (Read 3 times) previous topic - next topic

ekjk

Qualche idea?

questo è il codice che uso ora, ma che calcola gli rpm solo dopo aver generato l'impulso di uscita.
Code: [Select]

void counterISR()
{     
  TCCR1B |= (1 << CS11);   
  val=!val;
  fire=true;
}

ISR(TIMER1_COMPA_vect)
{
  if(!NotRun && fire) PORTD = PORTD | B00010000;
  else PORTD =PORTD & B11101111;
 
  TCCR1B &= ~(1 << CS11); 
 
  fire=false;
  flag=true;
 
  if(val) tempo_iniziale=micros();

  if(!val)tempo_finale=micros();
         
  if(tempo_finale>=tempo_iniziale) {freq=(int)(1000000.0/(tempo_finale-tempo_iniziale));}
  if(tempo_finale<tempo_iniziale) {freq=(int)(1000000.0/(tempo_iniziale-tempo_finale));}
         
  if(freq<0) freq=0;
  if(freq>250) freq=250;
}


al fronte di salita in ingresso si va in counterISR dove abilito il conteggio di timer 1 in ctc.
Quando timer1 arriva a OCR1A (settata di volta in volta nel loop in base alla freq di rotazione) si passa in TIMER1_COMPA_vect che alza il pin di uscita così ritardato del valore che voglio e poi calcolo la freq di rotazione...lo faccio così perchè introduco meno ritardo rispetto a farla quando arriva il primo fronte nell counterISR.

Facendo così però, il ritardo che applico (OCR1A) è calcolato sulla frequenza tra un fronte e quello successivo e quindi il timer applica il vero valore di ritardo solamente al secondo fronte, perchè al primo fronte OCR1A non è settato al valore giusto in quanto per ricavare tale valore serve la frequenza che viene calcolata solo all'arrivo del fronte successivo, il secondo.

leo72

Forse con la pulseIn potresti risolvere. Su che ordine di grandezza di tempi stiamo ragionando? La pulseIn misura da 10 uS in su. Sarebbero sufficienti?
Stavo poi ragionando sul modo con cui usi il timer 1.
Che cosa faresti con CS11? Quel flag è usato per impostare il prescaler, non la modalità di funzionamento del timer

ekjk

Ho provato con la pulseIn() a misurare la durata dell'impulso, sotto i 10us non ci vado mai, ma ho notato che il codice rallenta molto.

CS11 lo metto a zero per fermare il timer (dato che secondo il prescaler che uso anche gli altri CS sono a zero) che sennò continuerebbe a contare generando un pwm.

leo72


Ho provato con la pulseIn() a misurare la durata dell'impulso, sotto i 10us non ci vado mai, ma ho notato che il codice rallenta molto.

Il codice rallenta perché la pulseIn ferma tutto e si mette in attesa dell'impulso, misurandone poi la durata.

Quote

CS11 lo metto a zero per fermare il timer (dato che secondo il prescaler che uso anche gli altri CS sono a zero) che sennò continuerebbe a contare generando un pwm.

Ah, ho capito. Togli il segnale di clock al timer.
Ricordati però che quando riattivi il timer dandogli il clock (mettendo CS12 ad 1), il timer potrebbe non ripartire subito, subendo un certo ritardo proporzionale al fattore di prescaler. Tu usi un prescaler di 256, mi pare.
void counterISR da chi viene chiamata?

ekjk

Ciao,
io uso un prescaler = 8, il tick diventa quindi 0.5us.
void counterISR viene chiamata da attachInterrupt sul pin 3 e su fronte RISING.


Go Up