micros()

Abstract

The micros() returns the number of microseconds since the board has booted.

Source Code

The micros() is defined in hardware/arduino/avr/cores/arduino/wiring.c as below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
unsigned long micros() {
    unsigned long m;
    uint8_t oldSREG = SREG, t;
     
    cli();
    m = timer0_overflow_count;
    t = TCNT0;
 
    if ((TIFR0 & _BV(TOV0)) && (t < 255))
        m++;
 
    SREG = oldSREG;
     
    return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

The millis() has no input argument and returns unsigned long value.

First it reserves the status register SREG.

1
2
3
unsigned long micros() {
    unsigned long m;
    uint8_t oldSREG = SREG, t;

The SREG is a status register of ATMega328P.

Next it disables interrupt, copies the timer0_overflow_count which holds the

5
6
7
8
    cli();
    m = timer0_overflow_count;
    t = TCNT0;
}

The cli() is a macro that executes an assembler macro to disable interrupt.

The timer0_overflow_count is the number of times of the overflow of Timer/Counter0. The value of timer0_overflow_count is set by an interrupt handler named TIMER0_OVF_vect.

TCNT0 is a register that is incremented at regular intervals. The division ratio of Timer/Counter0 is set to 64 in Arduino Uno, the TCNT0 is incremented at every 64 clocks.

If the TOV0 bit of TIFR0 is set and TCNT0 is smaller than 255, it increments m. Then it restores the reserved status register value.

 9
10
11
12
    if ((TIFR0 & _BV(TOV0)) && (t < 255))
        m++;
 
    SREG = oldSREG;

The TOV0 bit of TIFR0 is a flag that is set when the Timer/Couter0 overflows. _BV() is a macro that shifts left 1 by specified number. If the bit is 1 and t is smaller than 255, an overflow happened and increments m.

Finally the number of microseconds is calculated and it is returned.

14
15
    return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

As the m is the number of overflows of Timer/Counter0 and it is incremented after TCNT0 is incremented 256 times, m * 256 + t = (m « 8) + t clocks have past.

TCNT0 is incremented at every 64 clocks, the number of clocks is calculated by ((m « 8) + t) times the time required to count 64 clocks.

clockCyclesPerMicrosecond() is a macro that returns clocks per 1 micro second, 64/clockCyclesPerMicrosecond() is the time to count 64 clock cycles.

Version

Arduino AVR Boards 1.8.6

License

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
  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
*/

Last Update

July 31, 2025

inserted by FC2 system