質問:
__delay_cyclesはどのように機能しますか?
diciu
2013-01-03 19:49:57 UTC
view on stackexchange narkive permalink

msp430g2553 を使用しており、クロックを1Mhzに設定しています:

  BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ;  

500万サイクルの時間を計りましたが、予想外に約6秒かかりました(5を期待していました)。使用したループは次のとおりです。

  int i; for(i = 0 ; i<5000; i ++)__ delay_cycles(1000);  

割り込みの使用について読みました(おそらくTimer_Aなどに基づいています)が、今は避けたいと思います。

つまり、私の質問は、__ delay_cyclesに基づいて定数引数 sleep を実装するにはどうすればよいですか?

後の編集

アセンブリ:

  void delay1000(){__ delay_cycles(1000);}  

is:

  delay1000: 0c3b4:04 12 PUSH R4 0c3b6:04 41 MOV SP、R4 0c3b8:24 53 INCD R4 0c3ba:3f 40 4c 01 MOV#0x014c、R15 // 332 10進数(1000/3 -> DEC、TST、JNZ)0c3be:1f 83 DEC R15 0c3c0:0f 93 TST R15 0c3c2:fd 23 JNZ delay1000 + 0xa 0c3c4:03 43 NOP 0c3c6:03 43 NOP 0c3c8:34 41 POP R4 0c3ca:30 41 RET  
二 答え:
Passerby
2013-01-03 21:04:39 UTC
view on stackexchange narkive permalink

MSP430最適化C / C ++コンパイラv3.1ユーザーズガイド(SLAU132c.pdf)の109ページから:

__ delay_cycles組み込みは、指定されたサイクル数を正確に消費するコードを挿入します副作用はありません。遅延するサイクル数は、コンパイル時定数でなければなりません。

これは、サイクルを使い果たすように特別に設計された組み込み関数です。少なくともそのサイクル数の間は良いはずです。 1000を別のものに変更できます(定数である必要があり、変数にすることはできません)。 forループと関数呼び出しの両方が遅延に追加されます。

さらに:

はい、コードでは小さな「オフセット」と「ゲイン」エラーが発生しますあなたが得る実際の遅れで。このコードは、正の方向への非常に小さなエラーで、特定の最小遅延を保証するのに適しています。そのため、ループ内の遅延はかなり大きく( "ms")選択されました。デッドオン遅延が必要な場合は、タイマーを使用するのが最善の方法です。ただし、何らかの理由でSW遅延を使用したい場合は、C関数を測定するのではなく、アセンブラーで関数をコーディングすることをお勧めします。関数自体で、呼び出しとループのオーバーヘッドの「オフセット」エラーと「ゲイン」エラーを補正できます。また、IDEには、遅延関数の分析に使用できるサイクルカウンター関数があります。ただし、SWの遅延については、割り込みが発生し(有効になっている場合)、結果として観察可能な遅延が変わる可能性があることに注意してください。

サポートフォーラムのTI従業員。

答えてくれてありがとう。 msp430では、1つの命令が常に1サイクル以内に実行されますか?
命令、最適化、コンパイルオプション、または言語によって異なりますが、__ delay_cyclesのような組み込み関数は、「nops」(1サイクル)と同様に、その目的のために高度に最適化されています。高次の数学はより多くを要し、2/4/8/16以外のものを含む数学はより多くを要します。ポートビットの変更時間にビットが見つかりました:ASMではこれをより速く行うことはできません。ポートでのビット演算は通常、CまたはASMの4サイクルかかります。ポートの低いニブルを使用する場合、CPUは定数ジェネレーター(1,2,4,8)を使用して、サイクル(およびコード)を節約します。したがって、実行できる最速は3サイクル/ビット演算です。
Oli Glaser
2013-01-03 19:55:05 UTC
view on stackexchange narkive permalink

コードの分解を見てください。forループが数サイクルかかるいくつかの命令を追加することを覚えておいてください。 5000ループでは、これらの余分なサイクルが合計されます。また、 delay_cycles()の実装方法は、大きな違いを生む可能性があります。
シミュレータで各ループのサイクルをカウントし、計算を行い、適切な値を渡すことで追加されたサイクルを補正できます。 。

もちろん、正確なタイミングを取得するための最良の方法は割り込みを使用することですが、今のところ割り込みを避けたいと言っています。

この特定のマイクロコントローラーについてはわかりませんが、このようなループはCPUのパイプラインを壊し、比較的大きなタイミングエラーを引き起こす可能性があります。
それは私たちが知らない__delay_1000の内容に依存します。外側のループに関する限り、MSP430では心配するパイプラインはあまりありません。
このような違いを説明するために単純なループ比較を期待していませんでしたが、__ delay_cyclesがどのように実装されているかを調べた後、それは理にかなっています。答えてくれてありがとう。
@diciu-はい、その通りです。このような大きな違いは、すべて追加された命令によるものではありません-これらの遅延ルーチンは、非常に広い範囲のタイムスケールに対応するために作成するのが難しいため、極端な端で精度が失われることがよくありますスケールの。ただし、実装/逆アセンブルを確認できる限り、コードが意図したとおりに機能するように調整できます。


このQ&Aは英語から自動的に翻訳されました。オリジナルのコンテンツはstackexchangeで入手できます。これは、配布されているcc by-sa 3.0ライセンスに感謝します。
Loading...