Playing with Arduino
A page to record my playing with Arduino
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 1.8.10

Last Update

November 28, 2019



inserted by FC2 system