TransWikia.com

Timer0 overflow interrupt not working

Arduino Asked by Simon Tagne on December 29, 2020

I try to use the Timer0 of an Arduino Leonardo (ATmega32u) to trigger an interrupt at regular intervals, using plain avr-gcc (not the arduino library). I try to blink the built-in LED as test, but it does not light up.

If I place a PINC=0x80; in the main function, the LED turns up, but not if I do it from the interrupt.
What am I doing wrong?

EDIT : The LED turns on with TCCR0B = (1 << CS00);, (no prescaler) or TCCR0B = (1 << CS01) (prescaler /8), but it does not with TCCR0B = (1 << CS00) | (1 << CS02); (prescaler /1024, what I want). At 16MHz CPU frequency the resulting frequency should be more than 15kHz, so I should see it instantly.

Here is my code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>

ISR(TIMER0_OVF_vect)
{
    PINC = 0x80;
}

int main()
{
    DDRC = 0b10000000;

    //Start Timer 0 @ 15625 Hz
    TCCR0A = 0;
    TCCR0B = (0b101 << CS00);
    TIMSK0 = (1 << TOIE0);
    sei();

    while(true); // Avoid return from main
}

One Answer

I just found the answer here : https://www.avrfreaks.net/forum/atmega32u4-arduino-leonardo-strange-timer-behavior

It seems that the USB connection generates higher-priority interrupts. I still don't know why the interrupts do work at higher frequency.

Solutions include powering the board from a USB charger or other power source rather than through the computer USB or adding the following code before the interrupt enable :

// Clear usb interrupt flags
USBINT = 0;
UDINT  = 0;
for (uint8_t i = 0; i < 6; i++)
{ // For each USB endpoint
    UENUM = i; // select the _i-th endpoint
    UEINTX = UEIENX = 0; // Clear interrupt flags for that endpoint
}

Thanks to those who helped me !

Answered by Simon Tagne on December 29, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP