0
\$\begingroup\$

I want to set up two timers running two ISR-s with different resolutions. One timer for counting milliseconds for clock time, another for counting microseconds when requested.
I've set up Timer1 and Timer2 in CTC mode, but timer with microseconds(Timer2) gets higher priority and timer with milliseconds is ignored(Timer1). Whereas they work separately well.

The setup:

void timer1CtcInit(void)
{

  TCCR1B = 0;
  TCCR1A = 0;


  //set CTC mode
  TCCR1B |= (1 << WGM12);
  // enable compare match interrupt
  TIMSK1 |= (1 << OCIE1A);


  // set OCR0A value for 100 msec
  OCR1A = 0x0619;
  //set 1024 prescaler
  TCCR1B |= (( 1 << CS10) | (1 << CS12));
}
void timer2CtcInit(void)
{

  //Timer 2 interrupt service routine CTC settings, 1 uS:
  TCCR2A = 0;
  TCCR2B = 0;
  //set CTC mode
  TCCR2A |= (1 << WGM21);
  //prescaler 1 for timer2
  TCCR2B |= (1 << CS20);

  // value for 1 usec
  OCR2A = 0x0f;

  //set compare match for register OCRA
  TIMSK2 |= (1 << OCIE2A);
}

ISRs:

ISR(TIMER2_COMPA_vect){
  if (timerFlag){
    tmr2Count++;
  }
}

ISR(TIMER1_COMPA_vect){
  tmr1Count++;
}
\$\endgroup\$
  • \$\begingroup\$ As a quick fix to get something going using methods you know and understand well, you might consider the idea of setting up just one timer (the fast one) and then decrement a counter value in it to decide when to invoke code associated with the slower timing you want. \$\endgroup\$ – jonk Oct 6 '17 at 6:49
  • \$\begingroup\$ Are tmr<n>Count declared volatile? \$\endgroup\$ – Ignacio Vazquez-Abrams Oct 6 '17 at 6:51
  • \$\begingroup\$ @IgnacioVazquez-Abrams Yes, both counter variables are volatile \$\endgroup\$ – flowian Oct 6 '17 at 7:13
  • \$\begingroup\$ @jonk Can't use fast timer because it is started and stopped at certain events, so it would be complicated to get exact values. \$\endgroup\$ – flowian Oct 6 '17 at 7:16
  • 1
    \$\begingroup\$ Using an AVR clocked at 16MHz to count micro-seconds in software is the wrong way to do it. You only have 16 instructions available between each interrupt occurring - it's no surprise your other ISR never gets to run. Set the prescaler to either 8 or 32 (and live with either half or double the time resolution you want) and just let the counter count by itself in hardware - no interrupts or software counter incrementing. Let the hardware do the hard work ... \$\endgroup\$ – brhans Oct 7 '17 at 2:23
0
\$\begingroup\$

Thanks to @brhans for bringing awareness of prescalers.
I think what happened was that interrupt setup with no prescaler was being depleted by other functions which took many mcu cycles to complete. The conflict was resolved by setting microseconds timer to 20 us instead of 1 and setting prescaler to 32. For timer with milliseconds prescaler was set to 256.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.