micros()

概要

micros()は、内部で保持しているArduinoを起動してからの時間をマイクロ秒単位で返します。

micros()のリファレンスはこちらをご覧ください。

ソースコード

micros()は、hardware/arduino/avr/cores/arduino/wiring.c に定義されています。以下に全ソースコードを示します。

 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());
}

micros()には、入力はありません。unsigned longを返します。

まず、状態レジスタを保存します。

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

SREGは、ATMega328Pの状態レジスタです。

次に、割り込みを禁止した後、timer0_overflow_countをmにコピーし、tにTCNT0の値を代入します。

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

cli()は割り込みを禁止するアセンブラ命令を実行するマクロです。

timer0_overflow_countは、タイマ/カウンタ0がオーバーフローを起こした回数です。タイマ/カウンタ0の割り込みハンドラで設定されます。

TCNT0は、一定期間ごとにインクリメントされる8ビットのレジスタです。Arduino Unoでは、タイマ/カウンタ0の分周比を64に設定しているので、64クロックごとにTCNT0が1インクリメントされます。

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

TIFR0のTOV0ビットは、タイマ/カウンタ0がオーバーフローを起こしたときに設定されるフラグです。_BV()は、1を指定したビット数だけ左シフトするマクロです。このビットが1かつtが255未満の場合は、オーバーフローを起こしているので、mをインクリメントします。micros()の最初にcli()で割り込みを禁止しているので、micros()実行中にオーバーフローを起こしても割り込みハンドラが起動されず、timer0_overflow_countがインクリメントされないためだと思われます。

最後に、今までの情報からArduinoを起動してからの時間をマイクロ秒に変換して返します。

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

mは、タイマ/カウンタ0がオーバーフローした回数で、TCNT0が256回インクリメントされるたびに1増えるので、m*256 + t = (m « 8) + t タイマクロック分の時刻が経過したことになります。

TCNT0は、64クロックに1回インクリメントされるため、(m « 8) + tに64クロックに要する時間を掛けることで、Arduinoを起動してからの時間が出てきます。

clockCyclesPerMicrosecond()は、1マイクロ秒あたりのクロック数を表すマクロなので、64 / clockCyclesPerMicrosecond()は、64クロックサイクルに要する時間をマイクロ秒で表すことになります。

バージョン

Arduino AVR Boards 1.8.6

ライセンス

 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
*/

最終更新日

July 31, 2025

inserted by FC2 system