I know this is a problem that has come up many times but I can't seem to get this code fragment to update the count variable on an ATMEGA328P. I am using an Arduino Uno as a development board, with the LED on pin 13 set to flash for debugging. I have confirmed the timer and LED part work by toggling port B pin 5 in the ISR routine.
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t count;
void init_100us_tick(void) {
TCCR0A = _BV(WGM01) | _BV(WGM00); // WGM mode 7 with OCRA as top
TCCR0B = _BV(WGM02) | _BV(CS01); // CLK / 8 prescaler
TIMSK0 = _BV(OCIE0B) | _BV(TOIE0); // Interrupt enabled on OCR0A
OCR0A = 200; // 16 MHz / 8 / 200 = 100 us
sei(); // Enable interrupts
}
ISR(TIMER0_COMPB_vect) {
count++;
}
int main(void) {
DDRB |= _BV(DDB5); // PB5 output
init_100us_tick(); // Initialise 100 us tick
count = 0; // In case of micro reset
for (;;) {
if (count >= 100) { // Every 10 ms
count = 0;
PORTB ^= _BV(DDB5); // Toggle PB5
}
}
return 0;
}
This is being compiled and burned to an Arduino Uno with the following:
avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o test.o test.c
avr-gcc -mmcu=atmega328p test.o -o test
avr-objcopy -O ihex -R .eeprom test test.hex
avrdude -F -V -c arduino -p ATMEGA328P -P /dev/ttyUSB0 -b 115200 -U flash:w:test.hex
I have tried disabling the optimisation with no effect. AVR-GCC is version 4.9.2
Interrupt enabled on OCR0A
- don't forget to change the comments if you change the code! You have an interrupt onTIMER0_COMPB_vect
!