Arduino:micros()よりも優れたマイクロ秒の解像度?


11

micros()のドキュメントでは、戻り値は常に4の倍数になることに注意しています。

より高い解像度のマイクロ秒クリック、できれば1マイクロ秒レベルまでのクリックを取得する方法はありますか?

AVRレベルまで下がっても問題ありません。


1
タイトルを完全に英語の質問にしたのに、なぜタグから始めるのを主張するのですか?
stevenvh

4
謝罪スティーブン、質問を簡潔かつ明確に表現するのに良い方法だと私は心から思った(そして考えた)。これについては多くの議論があり、ジェフはいくつかのケースでそれが求める良い方法であることに同意しました。議論はここにあります。ヒートマップは、これらのスタイルの質問に対して、動作環境を強調することは価値があると私に確信させたものです。meta.stackexchange.com/questions/10647/writing-good-titles/… しかし、あなたの優れた答えへの敬意から、それが最善だと思われる場合は、元に戻したいと思います。
Mark Harrison、

Pulsein()関数に使用できますか?パルス長を1usec未満の分解能で測定する必要があります。

このスペースは、上部の質問への回答用に予約されています。何か質問がある場合は、自分で質問してください。
Olin Lathrop

回答:


9

はい、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のデータシートは基本的なリソースです。この記事はあなたに(そして私にくれた!)良いスタートを切るでしょう。


4

マーク、私はArduino Atmega328 Timer2に基づいて関数の新しいセットを書き、オーバーフロー割り込みを使用して、精度を0.5usにすることにしました。私のコードはここからダウンロードして利用できます:

http://electricrcaircraftguy.blogspot.com/2014/02/Timer2Counter-more-precise-Arduino-micros-function.html

簡単な説明は次のとおりです。「micros()」置換関数で0.5usの精度を得るために「ライブラリ」を作成しました。これにより、PWMまたはPPM信号を読み取る反復可能な結果を​​1us以内で取得できます。インターネットに匹敵するものが見つからなかった(または使いやすく、サーボライブラリを介してPWM信号を書き込むArduinoの機能を維持した)ため、これがArduinoとラジオコントロールの世界への私の最初の主要な貢献だと思います。」


3

(質問で述べたように)AVRレベルへのドロップダウンが許容できる場合は、タイマーを設定して、AVRのクロックのティックを取得することもできます。

ATMegasやATTinysによって異なるため、AVRのデータシートを参照する必要があります。ただし、手順は常に同じです。あなたがする必要があるのは:

  • 使用するプリスケーラーを決定します(たとえば、1に設定します。つまり、実際のCPUクロック速度が必要な場合はプリスケーリングを行いません)。TCCRのドキュメントを参照してください。
  • タイマーオーバーフロー割り込み、割り込みハンドラーを設定し、割り込みをグローバルにアクティブ化する
  • タイマー/カウンター制御レジスターのタイマーをアクティブにする 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  
   */
}

FeeJaiに感謝します。Arduinoスケッチのコンテキスト内でこれらの割り込みを設定できますか?
Mark Harrison、

1
私はarduinoフレームワークに精通していません。ただし、内部ですべてのタイマーを設定しない場合は、設定できます。それ以外の場合は、タイマーレジスタを読み取って自分で計算できます。
FeeJai

はい、Arduinoで完全なC ++でプログラミングしておりTIMSKTOIE0などのすべてのレジスタとシンボルを使用できます(atmega328pデータシートからタイマー設定をコピーします)。ISR()マクロを使用できないようですが、代わりにarduino.cc/en/Reference/AttachInterruptを使用してください
joeforker
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.