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
}
1 Answer 1
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 !
-
I think the interrupt handler is missing when the bootloader exits, so avr-gcc defaults to reset the board, which might result in higher frequency to switch on the led while at lower frequency the board is reset before the first interrupt.Simon Tagne– Simon Tagne04/24/2018 20:13:50Commented Apr 24, 2018 at 20:13
Explore related questions
See similar questions with these tags.
0b101 << CS00
looks like bad code. Personally; I’d use(1 << CS00) | (1 << CS02)