TIMER0_OVF_vect is an interrupt handler that is executed when the Timer/Counter0(TCNT0) overflows. It is used to manage uptimes of the Arduino.
As the TCNT0 is an 8bit Timer/Counter, it overflows after each 256 increments. The division ratio is set to 64, the TCNT0 is incremented every 64 clocks. As a result, this handler is executed each 256 * 64 = 16384 clocks.
Source Code
The TIMER0_OVF_vect is defined in hardware/arduino/avr/cores/arduino/wiring.c as below.
// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
// the overflow handler is called every 256 ticks.
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
// the whole number of milliseconds per timer0 overflow
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
// the fractional number of milliseconds per timer0 overflow. we shift right
// by three to fit these numbers into a byte. (for the clock speeds we care
// about - 8 and 16 MHz - this doesn't lose precision.)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)
volatileunsignedlongtimer0_overflow_count=0;volatileunsignedlongtimer0_millis=0;staticunsignedchartimer0_fract=0;ISR(TIMER0_OVF_vect){// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsignedlongm=timer0_millis;unsignedcharf=timer0_fract;m+=MILLIS_INC;f+=FRACT_INC;if(f>=FRACT_MAX){f-=FRACT_MAX;m+=1;}timer0_fract=f;timer0_millis=m;timer0_overflow_count++;}
The MICROSECONDS_PER_TIMER0_OVERFLOW is a value of interval of Timer/Counter0 overflow in microseconds.
The clockCyclesToSeconds() is a macro to convert specified clock numbers to milliseconds.
The MILLIS_INC represents the interval time of Timer/Counter0 overflow in millisecgonds.
FRACT_INC stores the fractional number of milliseconds.
The timer0_overflow_count is a variable to hold the number of times that this interrupt handler is called.
The timer0_millis holds the millisecond part of the time. The timer0_fract holds the fractional part of milliseconds in microseconds.
The ISR() is a macro to define an interrupt handler.
Timer0_millis and timer0_fract are copied to m and f respectively.
18
19
20
21
22
23
ISR(TIMER0_OVF_vect){// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsignedlongm=timer0_millis;unsignedcharf=timer0_fract;
This interrupt handler is called when the Timer/Counter0 overflows.
If the f is greater than or equal to FRACT_MAX, it means the microsecond part exceed 1000.
/*
Copyright (c) 2016 garretlab.
Added source code explanation by garretlab.
*//*
wiring.c - Partial implementation of the Wiring API for the ATmega8.
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/