AVR Libc Home Page AVRs AVR Libc Development Pages
Main Page FAQ Library Reference Additional Documentation Example Projects

<util/delay.h>: Busy-wait delay loops


Detailed Description

    #define F_CPU 1000000UL  // 1MHz  <util/delay.h>より前に定義してください
    //#define F_CPU 14.7456E6  //14.7456MHz
    #include <util/delay.h>   
Note:
F_CPUを設定するもう1つの方法として、Makefileから与えることもできます。もちろん、この場合は、#defineは使いません。
※以下のようになります。mfileが生成するMakefileの中に含まれる以下の部分を書き換えます。
# Processor frequency.     
#     This will define a symbol, F_CPU, in all source code files equal to the 
#     processor frequency. You can then use this symbol in your source code to 
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
#     automatically to create a 32-bit value in your source code.
F_CPU = 12800000
このヘッダファイルにある関数は、busy-waitに使えるシンプルなディレイループを提供します。プログラム実行中の短いディレイを簡単に実現するのに使われます。これらはよく知られた (CPUサイクル/ループ繰り返し)値を使ったカウントダウンループとして働きます。ループウェイトなので、同時に他の処理を動かすことは出来ません。ここに述べた関数は割り込みを禁止しない点にもご注意下さい。

一般的に言って、長いディレイについてはハードウェアタイマーを使った方が適切です。この方法はCPUを占有せず、他のイベントの並行処理を許すからです。しかしながらとても短いディレイについては、ディレイタイム中のオーバーヘッドよりハードウェアタイマーのセットアップなどのオーバーヘッドの方が大きいです。

2つのインライン関数がディレイアルゴリズムのために提供されています

2つの包み込み関数によりマイクロ秒単位で直接ディレイを指定することを可能にしています。これはアプリケーションが供給するマクロ F_CPU を、CPUクロック周波数(Hz単位)として使用します。これらの関数は倍精度実数型の引数を取りますが、最適化がオンならば、浮動小数点計算はコンパイル時にすまされ、コードにはループ回数を表す整数定数が渡されるだけのコードに縮められます。

Note:
_delay_us()_delay_ms()を使うにあたり、これらの関数に与える引数はコンパイル時定数であることが望ましいです。変数を与えると、浮動小数点演算が行われそのためのランタイムが組み込まれてしまい、コードサイズが劇的に増大し、ループを起動するのにも時間がかかってしまうようになります。

Functions

void _delay_loop_1 (uint8_t __count)
void _delay_loop_2 (uint16_t __count)
void _delay_us (double __us)
void _delay_ms (double __ms)

Function Documentation

void _delay_loop_1 uint8_t  __count  ) 
 

8-bit counter __count を使ったディレイループ。256回までの繰り返しが可能です。(繰り返し値256は、0を渡すことで指定します。) ループは繰り返し当たり 3 CPUクロックで実行します。これはコンパイラがカウンタレジスタをセットアップするオーバーヘッドを考慮していません。

CPUスピードが 1MHz なら、768μsecまでのディレイが実現できます。10MHzなら76.8μsec。

void _delay_loop_2 uint16_t  __count  ) 
 

16-bit counter __count を使ったディレイループ。65536回までの繰り返しが可能です。(繰り返し値65536は、0を渡すことで指定します。) ループは繰り返し当たり 4 CPUクロックで実行します。これはコンパイラがカウンタレジスタペアをセットアップするオーバーヘッドを考慮していません。

CPUスピードが 1MHz なら、262.144msecまでのディレイが実現できます。10MHzなら26.2144msec。

void _delay_ms double  __ms  ) 
 

_delay_loop_2() を使って (__ms)ミリ秒のディレイを行う。

CPUクロック周波数 (Hz単位)を定義する定数として、(ユーザープログラム内で)マクロ F_CPU が定義されることが前提。
引数には定数を置いて下さい。小数を与えることも可能です。

最大のディレイは _delay_loop_2()の仕様に左右されます。かなり短い時間しかサポートできないので注意!
262.144/CPU_Clock(MHz) msec  (※262.144msec @ 1MHz、26.2144msec @ 10MHz、13.1072msec @ 20MHz)

void _delay_us double  __us  ) 
 

_delay_loop_1() を使って (__us)?秒のディレイを行う。

CPUクロック周波数 (Hz単位)を定義する定数として、(ユーザープログラム内で)マクロ F_CPU が定義されることが前提。
引数には定数を置いて下さい。小数を与えることも可能です。

最大のディレイは _delay_loop_1() の仕様に左右されます。かなり短い時間しかサポートできないので注意!
768/ CPU_Clock(MHz)) ?sec  (※768?sec @ 1MHz、76.8?sec @ 10MHz、38.4?sec @ 20MHz)


※訳注:
より長い時間をサポートしたければ、例えば以下のように行うことをお薦めします。

void delay_ms(uint16_t t) {
    while (t--) _delay_ms(1);
}

#define  delay_us(t)  _delay_ms(0.001*t);  // t は定数であること
_delay_us()が使える場合はこちらを使った方が誤差が小さくなります。どっちにしても数μsec以下については誤差が大きいので注意。

Automatically generated by Doxygen 1.4.1 on 23 Jan 2006.