MTUを使ったパルス出力方法

最近ルネサスのマイコンを触り始めた初心者です。

ぜひ皆様のお力をおかしください。

 

現在 RX220 シリーズを使い、パルス出力を行おうと考えています。

出力されるパルスの周波数はリアルタイムで変化させていきたいのですが、変化させたい周波数の範囲が広く、16bit カウンタでは足りません。

そこで、カスケード接続を使い、32bit カウンタでパルス出力を行おうと思うのですが、如何せん仕様書を見てもよく理解できていません。

 

・コンベアマッチにて出力ピンをトグルしたい

・16bit のカウンタでは可変可能な周波数の範囲が狭い

・上記理由から 32bit タイマを使いたいと思い、MTU1・2 をカスケード接続する方法を試したい

・MTU2 のオーバーフローをトリガに MTU1 をカウントアップさせるが、MTU1 でコンベアマッチを設定すると上位ビットのみでの出力制御になってしまうのでは?

 

例えば、32bit でコンベアマッチできるとして、33FF00h でトグルするよう設定したい場合、MTU1 で 33h、MTU2 で FF00h と設定しても希望する動作にならないと思います。

この場合、MTU1 のカウンタが 33h に到達した時点で MTU1 で指定できるピンがトグルし、MTU2 のカウンタが FF00h に到達した時点で MTU2 で指定できるピンがトグルするという別々の動作が発生するだけだと思われます。

 

ある出力ピンを 32bit の値でコンベアマッチさせトグル出力するには、どういう方法が適切でしょうか?

教えていただければ幸いです。

よろしくお願いいたします。

Parents
  • RX220については知らないけど、RX621の経験で書きます。
     16ビットカウンタを従属接続にして32ビットカウンタは作れます。
     ダウンカウンタを作って、アンダーフローでの処理を考えます。
     反転で無くてもクロックさえ出れば簡単。もう1段カウンタを追加してそちらで反転させます。
     ハードで作るなら74HC74。
     
     難しいのはカウンタ値の再設定です。自動的に再設定できるような機能が有るかマニュアルをよく読まないと分からない。
     自動的に設定してくれなくても時間的余裕があればソフトで設定できる。
     初段に入れるクロック周期よりも短い時間でソフト処理が完了すれば良いのです。
     そのため初段のクロックはシステムクロックを分周するか、他のカウンタで分周します。
  • リカルド さま

    カスケード接続した MTU を使い、本来マッチングさせたい 32bit の値をカウンタにセットしてカウントダウンさせるということでしょうか?
    確かに、カウントダウンであれば自由な値が設定できそうです。
    仕様書を読んで検討してみたいと思います。
  • >カスケード接続した MTU を使い、本来マッチングさせたい 32bit の値をカウンタにセットしてカウントダウンさせるということでしょうか?
     
     そうです。アンダーフローした所で自動で初期値に戻れば良いのですが、それが出来なければソフトで再設定することになります。
     ソフトで再設定している時間が誤差になります。割り込みで処理すれば、ほぼ一定の処理時間となりその分を補正したデータを書き込む事も考えられます。
     しかし命令長の長短の関係で割り込みが入ってから割り込みを開始するまで一定とも限りません。
     すなわち、ジッターが生じる訳です。
     精度の良い周期にするために「初段に入れるクロック周期よりも短い時間でソフト処理が完了すれば良いのです。」と書いたのです。
     そこまでシビアな事は言わないと言うのであれば、高い周波数でカウントすれば分解能が良くなります。細かい時間を設定できます。
  • リカルド さま

    あれから色々と考え、カスケード接続した MTU のカウントダウン形式も考えてみましたが、結局 MTU1 と MTU2 で個別の割込みが発生する+カウントダウン起動要因に位相係数モードを設定する必要があり複雑になるため、別の方法を考えました。

    仕様書を眺めていて使用用途が不明だった DOC 機能をうまく使えるかもしれないと思いました。
    TIM0-1 の16bit と DOC 16bit を使うことで 32bit を実現する方法です。
    例えば 33FF00h を指定したい場合、DOC に 33h 、TIM0-1 のカウンタ値に FFFFh - FF00h を指定します。
    TIM0-1 がオーバーフローしたタイミングで割込みを発生させ、DOC 減算をコールし、DOC の値をデクリメントします。
    最終的に DOC は 0h から減算するタイミングで割込みを発生させますので、ここで出力ピンをトグルします。

    出力したい周波数は常に可変しているため、これはグローバル変数に格納しておきます。
    出力パルスを IRQ に接続して DMA の起動要因にし、グローバル変数に格納されている値を TIM0-1 DOC のレジスタにそれぞれ飛ばします。

    これが成立するかはわかりませんが、試しに実装してみたいと思います。
  • RX220の動作クロックは内蔵RCで32MHz, X-talで20MHzが最高です。
    廉価版でPLLがないため、精度を求めるなら、20MHzが最高になります。
    20MHzでは50nsが限界となりますが、1000Hz付近で0.01Hzの変化をさせようとすると10ns単位の変化が必要になります。
    つまり1000Hz付近では精度がでません。周波数の連続的な変化を求めるなら、1000Hz付近は0.1Hz程度の変化で妥協すれば、16bitで事足りるのではないでしょうか。
  • 48kHzサンプリングでサイン波(~10000Hz)出力を作成したことありますけど、
    そこそこ精度が出ていた記憶があります。sin()関数で出力値を求めてました。
    今回パルスなので、正負の変化時に出力を切り替える。とかね。
    見当違いでしたら、すみません。
  • わわいです
    まー、タイマ割り込みでコンペアマッチ値に出力極性を動的に変えていくことで、タイマ一つだけで16ビットを超える分周出力を出すってのは可能だったりします
    ましかし、ソフト的な負担が大きいんで、ちと難しいところではありますねー
  • LEONです。
    sin()関数使わずとも、引数となる角度(0度~360度範囲)を演算してますから、360度(0度)、180度越えで切り替えられますね。
    また、サンプリング毎にカウンタ更新、周波数に応じた閾値との比較で矩形波H/L出力もしてました。
    カウンタ値と閾値による比較だと、累積による誤差が大きくなってしまいます。

    要望のコンペアマッチによる切り替えではありませんけど。
  • 1000Hzで0.01Hz単位の周波数変更というのは意外とハードルが高いのです。
    机上で周波数を1サイクル時間に換算してみると...
    999.98Hz = 1.000020ms
    999.99Hz = 1.000010ms
    1000.00Hz = 1.000000ms
    という事で10nsの変化を表現できる事が必要になります。
  • LEONです。
    Higetakaさん、試算ありがとうございます。そうですね。ハードルが高いです。

    10nsは100MHz。1波長の矩形波をH/L制御するから、最低その倍の200MHz以上のサンプリングが必要。
    サンプリングによる0.01Hzの分解能を得るには、RX220の最大動作周波数32MHzでは無理っすね。

    仮に200kHzサンプリングで5us。1波長10usの差。すなわち10Hzの変化の表現がやっとです。
     1000Hz  1.0000000 ms
      990Hz  1.0101010...ms

    分解能に拘らなければ、48kHzサンプリングでもmax24kHz周波数をとりあえず表現できるんだけどなぁ。
    コンペアマッチの思考からズレてます。
Reply
  • LEONです。
    Higetakaさん、試算ありがとうございます。そうですね。ハードルが高いです。

    10nsは100MHz。1波長の矩形波をH/L制御するから、最低その倍の200MHz以上のサンプリングが必要。
    サンプリングによる0.01Hzの分解能を得るには、RX220の最大動作周波数32MHzでは無理っすね。

    仮に200kHzサンプリングで5us。1波長10usの差。すなわち10Hzの変化の表現がやっとです。
     1000Hz  1.0000000 ms
      990Hz  1.0101010...ms

    分解能に拘らなければ、48kHzサンプリングでもmax24kHz周波数をとりあえず表現できるんだけどなぁ。
    コンペアマッチの思考からズレてます。
Children
No Data