micros()のドキュメントでは、戻り値は常に4の倍数になることに注意しています。
より高い解像度のマイクロ秒クリック、できれば1マイクロ秒レベルまでのクリックを取得する方法はありますか?
AVRレベルまで下がっても問題ありません。
micros()のドキュメントでは、戻り値は常に4の倍数になることに注意しています。
より高い解像度のマイクロ秒クリック、できれば1マイクロ秒レベルまでのクリックを取得する方法はありますか?
AVRレベルまで下がっても問題ありません。
回答:
はい、Arduinoの基本クロックレートによって異なります。たとえば、これはATMega2560のカウンタータイマー2のプリスケーリング後のカウンタータイマー入力周波数と期間、および16MHzの基本クロックレートです。タイマーには、次の表に示すように、周波数/周期を決定する「プリスケーラー」値オプションが組み込まれています。
TCCR2B bits 2-0 Prescaler Freq [KHz], Period [usec] after prescale
0x0 (TC stopped) -- --
0x1 1 16000. 0.0625
0x2 8 2000. 0.500
0x3 32 500. 2.000
0x4 64 250. 4.000
0x5 128 125. 8.000
0x6 256 62.5 16.000
0x7 1024 15.625 64.000
より良いタイミング解決のために、TCNT2と呼ばれる値を使用します。タイマーが8ビットであるため、0から255までのカウンターが組み込まれています。カウンターがTCNT2によって割り当てられた値に達すると、割り込みをトリガーします。この割り込みはTIMER2_OVF_vectと呼ばれます。
この情報が与えられた場合、結果の割り込みレートは16MHz /(プリスケーラー*(255-TCNT2))になります。
タイマーを完全な16MHz(62.5nSec)で動作させることもできますが、必要以上に高速です。(255-2)の初期カウントの2MHzは、1MHzの割り込み率を与えます。ISRでそれを2で割ります。
extern uint32_t MicroSecClock = 0;
ISR(TIMER2_OVF_vect) {// this is a built in function that gets called when the timer gets to the overflow counter number
static uint_8 count; // interrupt counter
if( (++count & 0x01) == 0 ) // bump the interrupt counter
++MicroSecClock; // & count uSec every other time.
digitalWrite(53,toggle);// pin 53 is arbitrary
TCNT2 = 253; // this tells the timer when to trigger the interrupt. when the counter gets to 253 out of 255(because the timer is 8 bit) the timmer will trigger an interrupt
TIFR2 = 0x00; // clear timer overflow flag
};
MCUのデータシートは基本的なリソースです。この記事はあなたに(そして私にくれた!)良いスタートを切るでしょう。
マーク、私はArduino Atmega328 Timer2に基づいて関数の新しいセットを書き、オーバーフロー割り込みを使用して、精度を0.5usにすることにしました。私のコードはここからダウンロードして利用できます:
簡単な説明は次のとおりです。「micros()」置換関数で0.5usの精度を得るために「ライブラリ」を作成しました。これにより、PWMまたはPPM信号を読み取る反復可能な結果を1us以内で取得できます。インターネットに匹敵するものが見つからなかった(または使いやすく、サーボライブラリを介してPWM信号を書き込むArduinoの機能を維持した)ため、これがArduinoとラジオコントロールの世界への私の最初の主要な貢献だと思います。」
(質問で述べたように)AVRレベルへのドロップダウンが許容できる場合は、タイマーを設定して、AVRのクロックのティックを取得することもできます。
ATMegasやATTinysによって異なるため、AVRのデータシートを参照する必要があります。ただし、手順は常に同じです。あなたがする必要があるのは:
TCCR
この方法では、タイマーレジスタから正確なティックを取得できますが、オーバーフローを手動でカウントする必要があります。これは、テクノロジーによって可能な限り正確です。
以下は古いAT90S2313のコード例ですが、基本的に何をすべきかについて良いヒントを与えてくれます:
/* uC: AT90S2313 */
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
// set up timer 0
TCCR0 = (1<<CS01); // Prescaler 8
// enable overflow interrupt
TIMSK |= (1<<TOIE0);
// activate interrupts
sei();
while(1)
{
/* Do whatever you like */
}
}
ISR (TIMER0_OVF_vect)
{
/*
This gets called everytime there in an overflow in the timer register
*/
}
TIMSK
、TOIE0
などのすべてのレジスタとシンボルを使用できます(atmega328pデータシートからタイマー設定をコピーします)。ISR()マクロを使用できないようですが、代わりにarduino.cc/en/Reference/AttachInterruptを使用してください。