## Examination of the Arduino micros() Function Background

To fully understand the micros() function, you first need to understand the Timer #0 overflow interrupt handler which was covered in this post.

Recall the typical Ardiuno runs on a 16MHz oscillator. Both the millis() and micros() functions base their calculations on the Arduino Timer #0, which is running with a prescale of 64. This results in the timer ticking at 64*1/16,000,000th of a second (which is 0.000004 seconds or evey 4 µs). Its important to take note of this because the resolution of micros() is therefore 4 µs.

Also recall that since the Timer #0 counter (TCNT0) is 8-bit, it “rolls over” or “overflows” after every 256 ticks. This means an overflow occurs every 1/16,000,000(oscillator) * 64(prescale) * 256(roll over) = 0.001024 seconds, or 1.024 ms, or 1024 µs.

Expand a Macro

Now, let’s do some additional math so we can substitute a number in the place of the following macro (this macro is embedded inside an Arduino hardware file):

```#define clockCyclesPerMicrosecond () ( F_CPU / 1000000L )
```

F_CPU is the oscillator frequency, and is defined during compilation. We already know this is 16,000,000, which makes:
``` clockCyclesPerMicrosecond = 16,000,000/1,000,000 = 16 ```

micros() Simplified

I’ve removed some housekeeping steps which check for the potential rare instance of an interrupt occurring during the micros() function call and substituted the expanded macro from above. What is left is simply the meat of the function, which calculates the elapsed microseconds:

```unsigned long micros() {
return((timer0_overflow_count << 8) + TCNT0)*(64/16);
}
```

Knowing all this boils the micros() calculation down to:
``` micros = (Timer #0 counter + (number of times timer #0 has overflowed * 256)) * 4 ```

Actual Arduino micros() Function:

```unsigned long micros() {
unsigned long m;
uint8_t oldSREG = SREG, t;

cli();
m = timer0_overflow_count;
#if defined(TCNT0)
t = TCNT0;
#elif defined(TCNT0L)
t = TCNT0L;
#else
#error TIMER 0 not defined
#endif

#ifdef TIFR0
if ((TIFR0 & _BV(TOV0)) && (t & 255))
m++;
#else
if ((TIFR & _BV(TOV0)) && (t & 255))
m++;
#endif

SREG = oldSREG;

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

```

Do you wish you could read and write inline assembly code for the Arduino? Check out the book with greatly expanded coverage! ## About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , , , . Bookmark the permalink.

### 7 Responses to Examination of the Arduino micros() Function

1. Beneden Dickt Danglespan says:

So the ‘micros()’ function itself already spoils the accuracy of the measurement? What’s the point then? (see my other post on FIXED POINT issue)

2. Teo says:

Hi. Is there any way I can modify this code to generate the number of nanoseconds since the arduino has started? Like an “nanos()” function…

• Control says:

Since a clock cycle will take 1/16.000.000 = 63 nanoseconds , the accuracy of your nanos function would be just 63 nanoseconds. I recommend to code your own functions with Timer0.

3. Homayon says:

How can I build micros for timer1?

• Jim Eli says:

First consider, Timer 1 is used by the servo library. Using it would invalidate the library. Second, I haven’t looked through the datasheet to see if the functionality of Timer 0 could be duplicated with Timer 1 (for example, Timer 0 is 8-bit and Timer 1 is 16-bit). Otherwise, simply transfer the setup to the Timer 1 registers.

4. Memo says:

how to get timer0_overflow_count because I tried this function with another name and it didn’t work

• Jim Eli says:

timer0_overflow_count is defined inside the wiring.c file as,
``` volatile unsigned long timer0_overflow_count = 0; ```

You should be able to access this variable by placing the following definition inside your code:
``` extern volatile unsigned long timer0_overflow_count; ```