Show Posts
Pages: [1]
1  Using Arduino / Programming Questions / Re: Leonardo Timer trouble... on: October 02, 2012, 09:00:34 am
@fungus: The TCNT register is not set, but the TCNT3 register is as shown above. That doesn't throw any interrupts on it's own does it?

@Nick: SCORE, thanks for the tip!

I added the line
   TIFR3 = (1 << OCF3A);
before reenabling the timer3 compare and it works like a charm now.
2  Using Arduino / Programming Questions / Leonardo Timer trouble... on: October 01, 2012, 06:48:11 pm
After way more time than I want to admit, I'm ready to admit defeat on an apparent timer bug in the ATmega32u4 (Leonardo). I'm trying to setup two timers (1 & 3) to work together, and for some reason timer3 seems to call the compare ISR almost immediately in some cases.

The program is expected to produce a 1kHz pulse of minimum duration on pin 9, and a 500e-6s duration pulse on pin 4 for every 100 pulses of pin 9. The result is as expected, except that the pulse on pin 4 only has 10e-6s duration MOST of the time, and occasionally 15 to 20e-6s duration. Maybe there's some other interrupt interfering?

This is an excerpted function from a larger program which was exhibiting this weird behavior, so I cut it down to the simplest demo of the problem and haven't been able to sort it out still. It needs to use the timers because timing is critical and doing this in software with the other requirements does not seem possible.

Code to reproduce the problem is:
Code:
  const int tmr1Pin = 9;
  const int tmr3Pin = 4;
  volatile int tcntx = 0;

// the setup routine runs once when you press reset:
void setup() {
  pinMode(tmr1Pin,      OUTPUT);   digitalWrite(tmr1Pin,LOW);
  pinMode(tmr3Pin,      OUTPUT);   digitalWrite(tmr3Pin,LOW);

  cli();          // disable global interrupts
  GTCCR = 0; // clear Timer Sync Mode to restart all timers and prescalers
  GTCCR = (1 << TSM); // set Timer Sync Mode to pause all timers

    TCCR1A = 0;
    TCCR1B = (1 << CS10); // prescaler=1 -> use system clock speed
    TCCR1B|= (1 << WGM12); // turn on CTC mode, TOP=OCR1A (ie resets at OCR1A)
      OCR1A = 16000; // set compare match register to desired timer count (16000/16MHz=1ms)
    TIMSK1 = (1 << OCIE1A); // enable timer compare interrupt

    TCCR3A = 0; // leave OC3A to software control
    TCCR3B = (1 << CS30); // prescaler=1 -> use system clock speed
    TCCR3B|= (1 << WGM32); // turn on CTC mode, TOP=OCR3A
      OCR3A = 8000;

  // turn off other interrupts
    // TIMSK0 = 0; // timer 0
    // USBCON = 0; // USB interrupts (now you need to press the reset button to program...)
    // at least one more is still on but I can't find it...

  GTCCR = 0; // clear Timer Sync Mode to restart all timers and prescalers
  sei();          // enable global interrupts
}

ISR(TIMER1_COMPA_vect) { // called after gate time has expired
  digitalWrite(tmr1Pin,HIGH);  digitalWrite(tmr1Pin,LOW);
  if (tcntx > 100) {
    tcntx=0;
    TCNT3=0;
    digitalWrite(tmr3Pin,HIGH);
    TIMSK3 = (1 << OCIE3A); // enable timer compare interrupt
  } else {
    tcntx++;
  } 
}

ISR(TIMER3_COMPA_vect) { // called after gate time has expired
  digitalWrite(tmr3Pin,LOW);
  TIMSK3 = 0;
}


// the loop routine runs over and over again forever:
void loop() {
} // end loop()


Strangely enough, if the three lines for setting up timer3 in the timer1 ISR are moved outside of the conditional statement so that they are called every pulse, timer3 behaves as expected for the first couple of pulses but then reverts to the above problematic operation.

Code:

  const int tmr1Pin = 9;
  const int tmr3Pin = 4;
  volatile int tcntx = 0;

// the setup routine runs once when you press reset:
void setup() {
  pinMode(tmr1Pin,      OUTPUT);   digitalWrite(tmr1Pin,LOW);
  pinMode(tmr3Pin,      OUTPUT);   digitalWrite(tmr3Pin,LOW);

  cli();          // disable global interrupts
  GTCCR = 0; // clear Timer Sync Mode to restart all timers and prescalers
  GTCCR = (1 << TSM); // set Timer Sync Mode to pause all timers

    TCCR1A = 0;
    TCCR1B = (1 << CS10); // prescaler=1 -> use system clock speed
    TCCR1B|= (1 << WGM12); // turn on CTC mode, TOP=OCR1A (ie resets at OCR1A)
      OCR1A = 16000; // set compare match register to desired timer count (16000/16MHz=1ms)
    TIMSK1 = (1 << OCIE1A); // enable timer compare interrupt

    TCCR3A = 0; // leave OC3A to software control
    TCCR3B = (1 << CS30); // prescaler=1 -> use system clock speed
    TCCR3B|= (1 << WGM32); // turn on CTC mode, TOP=OCR3A
      OCR3A = 8000;

  // turn off other interrupts
    // TIMSK0 = 0; // timer 0
    // USBCON = 0; // USB interrupts (now you need to press the reset button to program...)
    // at least one more is still on but I can't find it...

  GTCCR = 0; // clear Timer Sync Mode to restart all timers and prescalers
  sei();          // enable global interrupts
}

ISR(TIMER1_COMPA_vect) { // called after gate time has expired
  digitalWrite(tmr1Pin,HIGH);  digitalWrite(tmr1Pin,LOW);
  if (tcntx > 100) {
    tcntx=0;
  } else {
    tcntx++;
  } 
    TCNT3=0;
    digitalWrite(tmr3Pin,HIGH);
    TIMSK3 = (1 << OCIE3A); // enable timer compare interrupt
}

ISR(TIMER3_COMPA_vect) { // called after gate time has expired
  digitalWrite(tmr3Pin,LOW);
  TIMSK3 = 0;
}


// the loop routine runs over and over again forever:
void loop() {
} // end loop()

Any ideas?
3  Development / Other Software Development / Re: PWM frequency library on: August 13, 2012, 04:52:12 pm
What's the deal with this not working on the Leonardo?
Pages: [1]