Blink with Interrupt on Leonardo

I'm trying to get the Blink concept working with a timer interrupt on the Leonardo. But it does not seem to work. What am I doing wrong?

void setup() {
  TCCR1A = 0;
  TCCR1B = 0;
  bitSet(TCCR1A, CS12);  // 256 prescaler
  OCR1A = 62500;
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
}

ISR(TIMER1_COMPA_vect) {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

Another problem with this example is that it "nukes" the USB connection, no idea how to revive the Leo again...
The latter is solved: after restarting the IDE I was able to reload regular Blink with a well timed press of RESET after compilation.

You forgot to enable the Timer 1 overflow compare match interrupt, and to set the appropriate timer mode.

You might find these snippets useful. The ATmega328/32U4 data sheets have all the details.

volatile unsigned int timer1_counter;

ISR(TIMER1_OVF_vect)        // interrupt service routine
{
  TCNT1 = timer1_counter;   // preload timer
   //do something else
}

void setup() {
  cli();           // disable all interrupts
  TCCR1A = 0; //clear control registers, set mode 0
  TCCR1B = 0;

  // Set timer1_counter to the correct value for desired interrupt interval
  //timer1_counter = 64886;   // preload timer 65536-16MHz/256/100Hz
  //timer1_counter = 64286;   // preload timer 65536-16MHz/256/50Hz
  timer1_counter = 34286;   // preload timer 65536-16MHz/256/2Hz

  TCNT1 = timer1_counter;   // preload timer
  TCCR1B = (1 << CS12);    // 256 prescaler
  TIMSK1 = (1 << TOIE1);   // enable timer overflow interrupt
  sei();             // enable all interrupts
...
}

I'm a bit puzzled by your directions. So instead of having a compare value of 31250 your don't set it up to compare but to overflow, and you fill it with 65535-31250 on overflow?
Why is that? The timer has a compare option, which in my opinion creates better readibility of the code.

One of the problems was most examples for the UNO use PB5, whereas Pin 13 on the LEO is PC7. This works correctly. That means with compare interrupt, not overflow, and auto-reset to 0. I also replaced the for noobs very cryptic bitshift notation for bitWrite as it is more understandable.

void setup() {
  TCCR1A=0;
  bitWrite(DDRC,PC7,1);
  bitWrite(TCCR1B,CS12,1);
  bitWrite(TCCR1B,CS11,0);
  bitWrite(TCCR1B,CS10,0);
  bitWrite(TCCR1B,WGM12,1);
  TCNT1=0;
  OCR1A=62500;
  bitWrite(TIMSK1,OCIE1A,1);
  sei();
}

void loop() {
  delay(100);
}

ISR(TIMER1_COMPA_vect) {
  bitWrite(PORTC,PC7,!bitRead(PORTC,PC7));
}

Why is that?

I chose to use timer mode 0 and an overflow interrupt. You need a different timer mode to use the OCR1A register and a compare match interrupt.

In my opinion, counting from 5 to 10 is not conceptually more difficult than counting from 0 to 5.

Unfortunately, programming the timer requires rather detailed understanding about how the timer works, in both cases. Programming notation details are much less important, and for the beginners there are timer libraries.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.