Go Down

Topic: TCCR1A setta OC1A, non costante (Read 215 times) previous topic - next topic

ekjk

Sep 07, 2016, 10:06 am Last Edit: Sep 07, 2016, 10:11 am by ekjk
Ciao ragazzi,
sono di nuovo alle prese col timer 1 su atmega328.

Il gioco è questo: sul fronte di discesa (falling) di un segnale su external INT0 chiamo una isr (SensorINPUT) ke mi fa partire il timer 1 in compare mode con prescaler 8.
Quando il timer 1 arriva a OCR1A lancia la sua ISR dove deve abbassare il pin 9 (oc1a) di uscita che normalmente ho impostato con pull up nel setup.
Quindi al primo giro entra in (!CoilOff) perchè CoilOff=false e porta pin9 basso perchè nel setup TCCR1A=(1 << COM1A1);
Poi Ricarica OCR1A=4000; per far si che timer1 porti pin9 alto dopo 2ms e lancia il conteggio settando TCCR1B e setta TCCR1A = (1 << COM1A1) | (1 << COM1A0); in modo che pin9 si alzi quando il timer è arrivato alla fine conteggio.
Arrivato a 4000 count la ISR entra dove CoilOff=true dove viene fermato il timer e reimpostato TCCR1A=(1 << COM1A1); in modo che il pin9 vada bassa alla prossima fine conteggio. Qui si carica OCR1A=1000;
All'arrivo del nuovo segnale d'ingresso viene fatto partire il timer che arrivato a 1000 count fa abbassare il pin9.

tutto funziona, ma spesso ho la situazione come visualizzata in foto: segnale d'ingresso blu e uscita giallo.
L'uscita a volte non è presente oppure sta alta più del dovuto.
Qui i link alle immagini
https://postimg.org/image/z5clizqyz/
https://postimg.org/image/hqsdaptu3/


Ho fatto diverse prove ma non riesco a risolvere, e questa configurazione è la più veloce in quanto il timer stesso gestisce il pin9 e non perdo tempo nel alzare e abbassare l'uscita con digitalWrite.

Il problema suddetto non persiste se uso digitalWrite invece di settare TCCR1A.

Dove sbaglio?


Code: [Select]

void SensorINPUT() //lancia il timer 1: OCR1A è caricato con delay
{
  TCCR1B = (1 << WGM12) | (1 << CS11); // CTC, OCR1A as top, prescaler 8, start timer

  Actual_time = micros();
 
  CoilOff=false;
}

ISR(TIMER1_COMPA_vect)
{
  if (!CoilOff) // turn on coil after Toff (dopo il segnale s_in il contatore quando arrivato a delay di OCR1A entra qui e setta di alzare l'uscita dopo Toff)
  {
    TCCR1B = 0;                          // stop timer
    TCCR1A = 0;
    TCNT1 = 98;                          // initial value of the timer to compensate delay
    TCCR1A = (1 << COM1A1) | (1 << COM1A0);    // Set OC1A at compare match

    OCR1A = 4000;
    TCCR1B = (1 << WGM12) | (1 << CS11); // CTC, OCR1A as top, prescaler 8, start timer

  }
  else // turn off coil after Delay (setta di abbassare l'uscita dopo il delay di OCR1A)
  {
    TCCR1B = 0;                         // stop timer
    TCCR1A = 0;
    TCNT1 = 98;                         // initial value of the timer to compensate delay
    TCCR1A = (1 << COM1A1);             // Clear OC1A at compare match

  
    OCR1A = 1000;
  }

  CoilOff = !CoilOff;
}

Go Up