Micom Car Rally NET
MCR - Micom Car Rally
2015大会 マイコンカーラリーとは? 今から始めるマイコンカーラリー 技術情報 大会記録 MCRファン倶楽部 お問い合せ
マイコンカーラリートップへ マイコンカーラリートップへ
技術情報 >> R8C/M12A 技術情報
技術情報
アプリケーション
R8C/M12A 技術情報
上位入賞マイコンカー
参加者レポート
よくある質問(FAQ)
ダウンロード
R8C/M12A 技術情報
プロポ受信機から出力されるパルスを入力する

本内容は、神戸市立科学技術高等学校 電気情報工学科・登 弘聡先生が作成したプログラムを参考にさせていただきました。ありがとうございました。

内容
送信機からの信号を受信機で受信し、サーボを動かし、ラジコンやヘリコプターを動かします(下図)。

説明1

サーボを、R8C/M12Aマイコンに変えます。受信機からは、周期16ms、ON幅0.7〜2.3msのパルスが出力されているので、その幅をマイコンで測定します。今回は、測定したパルス幅に応じてLED 8個を点灯させます(下図)。

説明2

ワークスペース

r8cm12a_pulse_width_100.zip
ファイルを解凍し、フォルダを「c:\worksapce」に入れてください。

回路
回路を下図に示します。

回路図

プログラムの説明

タイマRJ2の設定

タイマRJ2の概要(パルス幅測定モード)を、下図に示します。

タイマRJ2(パルス幅測定モード) 概要

タイマRJ2を使って、入力端子(P1_5、P1_7、P4_6のどれか一つだけ選択)の"1"の時間(パルス幅)を測定します。測定時間は、f1を選んだときは3.2768msまで、f2を選んだときは6.5536ms、f8を選んだときは26.2144msになります。それ以上は、オーバーフローとなり測定できません(プログラムを工夫すればできます)。

これからタイマRJ2のパルス幅測定モードについて、説明します。

■TRJIO端子の選択
TRJIO端子(タイマRJ2を使ったパルス幅測定モードで、信号を入力することのできる端子)は、P1_5端子、P1_7端子、P4_6端子の3つあります。どの端子を使うかを、プログラムで設定します。
P1_5端子を入力端子にしたい場合、ポートP1_5機能選択ビット(P15SEL2,P15SEL1,P15SEL0)を下記のように設定します。忘れずに、P1_5端子の入出力設定も入力にしておきましょう(pd1を設定)。
    p15sel2 = 0;  /* P1_5をTRJIO端子にする        */
    p15sel1 = 1;
    p15sel0 = 0;

P1_7端子を入力端子にしたい場合、ポートP1_7機能選択ビット(P17SEL1,P17SEL0)を下記のように設定します。忘れずに、P1_7端子の入出力設定も入力にしておきましょう(pd1を設定)。
    p17sel1 = 1;  /* P1_7をTRJIO端子にする        */
    p17sel0 = 0;

P4_6端子を入力端子にしたい場合、ポートP4_6機能選択ビット(P46SEL2,P46SEL1,P46SEL0)を下記のように設定します。忘れずに、P4_6端子の入出力設定も入力にしておきましょう(pd4を設定)。
    p46sel2 = 1;  /* P4_6をTRJIO端子にする        */
    p46sel1 = 0;
    p46sel0 = 1;

今回は、P4_6をTRJIO端子にしています。

■タイマRJモードレジスタ(TRJMR)の設定
bit 7 6 5 4 3 2 1 0
設定
内容
  タイマRJカウントソース選択ビット
000:f1(20MHz)
001:f8(2.5MHz)
011:f2(10MHz)
  タイマRJ動作モード選択ビット
000:タイマモード
001:パルス出力モード
010:イベントカウンタモード
011:パルス幅測定モード
100:パルス周期測定モード
設定値   0 0 0   0 1 1
ビットの
名称
  TCK2_
TRJMR
TCK1_
TRJMR
TCK0_
TRJMR
  TMOD2_
TRJMR
TMOD1_
TRJMR
TMOD0_
TRJMR

タイマRJカウントソース選択ビットで、ON幅を測定する精度(細かさ)を設定します。
000…f1(20MHz)を設定します。精度は、50nsになります(今回の設定)
001…f8(2.5MHz)を設定します。精度は、400nsになります。
011…f2(10MHz)を設定します。精度は、100nsになります。

タイマRJ動作モード選択ビットは、今回はパルス幅測定モードにします。

■タイマRJ I/O制御レジスタ(TRJIOC)の設定
bit 7 6 5 4 3 2 1 0
設定
内容
              入出力極性切り換えビット
0:Lレベル幅("0"の幅)を測定
1:Hレベル幅("1"の幅)を測定
設定値               1
ビットの
名称
              TEDGSEL_TRJIOC

入出力極性切り換えビットで、"1"の幅を測るか、"0"の幅を測るか設定します。今回は"1"の幅を測ります。

■タイマRJカウンタレジスタ(TRJ)の設定
bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
初期値 0xffffを設定

タイマRJカウンタレジスタ(TRJ)を設定します。このレジスタの値が、入力信号が"1"の間、50nsごとに-1していきます(ダウンカウント)。ダウンカウントなので、初期値は最大値である0xffffにしておきます。「0xffff-TRJ」の値がON幅になります。

■タイマRJ割り込み制御レジスタ(TRJIR)の設定
bit 7 6 5 4 3 2 1 0
設定
内容
タイマRJ割り込み
許可ビット
0:割り込み禁止
1:割り込み許可
タイマRJ割り込み
要求フラグ
0:割り込み要求なし
1:割り込み要求あり
           
設定値 1              
ビットの
名称
TRJIE_TRJIR TRJIF_TRJIR            

タイマRJ割り込み許可ビットを"1"にして、割り込み許可にします。入力信号が"1"になると自動的にTRJのカウントダウンが開始され、"0"になるとカウントダウンが停止します。停止したときに割り込みを発生させ、パルス幅を計算するようにします。

■割り込み優先レベルレジスタB (ILVLB)の設定
bit 7 6 5 4 3 2 1 0
設定
内容
    周期タイマの割り込み優先レベル設定ビット
00:レベル0 (割り込み禁止)
01:レベル1
10:レベル2
11:レベル2
    タイマRJ2の割り込み優先レベル設定ビット
00:レベル0 (割り込み禁止)
01:レベル1
10:レベル2
11:レベル2
設定値 0 0 0 0 0 0 1 0
ビットの
名称
    ILVLB5 ILVLB4     ILVLB1
ILVLB0

タイマRJ2の割り込み優先レベル設定ビットを設定します。これは、複数の割り込みが発生した場合に、どの割り込みを優先させるかを設定します。今回はタイマRJ2の割り込みしか使っていませんので1以上であればどの値でも構いませんが、一応いちばん大きいレベル2にしておきます。

■タイマRJ制御レジスタ(TRJCR)の設定
bit 7 6 5 4 3 2 1 0
設定
内容
              タイマRJカウント開始ビット
0:カウント停止
1:カウント開始
設定値               1
ビットの
名称
              TSTART_TRJCR

タイマRJカウント開始ビットを"1"にして、TRJがカウントダウンするように設定します。

■全体の割り込みを許可する

タイマRJ割り込み制御レジスタ(TRJIR)で、タイマRJ2の割り込みを許可しましたが、初期状態ではマイコン全体の割り込みが禁止になっています。
そのため、最後にマイコン全体の割り込みを許可します。全体割り込み許可は、マイコンのCPUレジスタという、C言語では操作できない場所にあるので、アセンブラで命令を記述します(下記プログラム)。asm関数は、C言語プログラム内でアセンブラ命令を記述する命令です。

    /* 全体割り込みの許可 */
    asm(" fset I ");    /* 全体の割り込み許可 */


タイマRJ2の設定は、init関数内で行います。プログラムを下記に示します。

    /* タイマRJ2の設定 */
    msttrj  = 0;            /* タイマRJ2を有効にする        */

    p46sel2 = 1;            /* P4_6をTRJIO端子にする        */
    p46sel1 = 0;
    p46sel0 = 1;

    tck2_trjmr   = 0;       /* カウントソース = f1          */
    tck1_trjmr   = 0;
    tck0_trjmr   = 0;
    tmod2_trjmr  = 0;       /* パルス幅測定モード           */
    tmod1_trjmr  = 1;
    tmod0_trjmr  = 1;
    tedgsel_trjioc = 1;     /* Hレベルを測定                */
    trj          = 0xffff;  /* TRJに最大値を入れる          */
    trjie_trjir  = 1;       /* TRJ割り込み許可              */
    ilvlb        = 0x02;    /* 割り込み優先レベル2          */
    tstart_trjcr = 1;       /* タイマスタート               */

    /* 全体割り込みの許可 */
    asm(" fset I ");        /* 全体の割り込み許可           */

「msttrj」は、タイマRJ2スタンバイビットで、タイマRJ2を有効にするか、無効にするかを選択するビットです。0で有効です。初期状態ではタイマRJ2は無効になっているので、タイマRJ2を使う前にこのビットを0にしてください。

割り込みプログラム(パルス幅の測定)

割り込みプログラムを下記に示します。このプログラムは、入力信号が"1"→"0"になった瞬間、またはアンダーフロー(TRJが0→65535になった瞬間)に実行されます。

#pragma interrupt intTRJ(vect=22)
void intTRJ( void )
{
    if( tundf_trjcr ) {         /* アンダフローあり?       */
        // 50ns×65536=3.2768ms以上ONなら、計測できない
        tundf_trjcr = 0;
    }

    if( tedgf_trjcr ) {         /* 立ち下がり検出           */
        tedgf_trjcr = 0;

        /* パルス幅セット */
        pulse_width = 0xffff - trj;

        /* カウンタクリア(いったん停止させてセット) */
        tstart_trjcr = 0;       /* TRJ停止                  */
        trj          = 0xffff;
        tstart_trjcr = 1;       /* TRJ再開                  */
    }
}

intTRJ関数が、タイマRJ2割り込みが発生したときに実行される関数です。この関数がタイマRJ2割り込みの実行先ということを設定するのが、「#pragma interrupt」命令です。この命令の書式を下記に示します。
#pragma interrupt 割り込み関数名(vect=割り込み番号)
void 割り込み関数名( void )
{
    割り込みプログラム
}

タイマRJ2の割り込み番号は22と決まっています。どの内蔵周辺機能が何番の割り込み番号かは、ルネサス エレクトロニクスの「R8C/M11Aグループ、R8C/M12Aグループ ユーザーズマニュアル ハードウェア編」の「可変ベクタテーブル」部分を参照してください。
割り込み関数名は、自由に付けて構いません。今回はタイマRJ2割り込みなので、割り込みの「interrupt」とタイマRJ2の「Timer RJ2」を略して、「intTRJ」としました。

タイマRJカウンタレジスタ(TRJ)の値、入力波形などの関係を、下図に示します。

タイマRJ2(パルス幅測定モード) 波形

今回、割り込みプログラムが実行されるきっかけは次の2つあります。

@タイマRJカウンタレジスタ(TRJ)がアンダーフローした(0→65535になった瞬間の)とき
A入力端子が"1"から"0"になった瞬間

@で割り込みが発生した場合、tundf_trjcrが1になります。tundf_trjcrをチェックして1なら、tundf_trjcrを0にして、何もせずに終了します。
Aで割り込みが発生した場合、tedgf_trjcrが1になります。tedgf_trjcrをチェックして1なら、tedgf_trjcrを0にして、パルス幅をpulse_width変数に入れます。
入力波形が"1"になるとTRJが0xffffからダウンカウントしていき、入力波形が"0"になると停止します。よって、0xffffから現在の値を引くと、ONの幅が分かります。プログラムは次のようになります。
  pulse_width = 0xffff - trj; //pulse_width変数にパルス幅が入る

今回の設定では、pulse_widthの値が1あたり、50nsなので、パルス幅は次の計算で求めることができます。
  パルス幅[s] = 50[ns] × pulse_width
最後に、タイマRJカウンタレジスタ(TRJ)を0xffffに設定して、次のパルス幅測定に備えます。ただし、設定はTRJのカウントが停止されている状態でなければいけません(図のTSTART_TRJCR部分がOFFの状態でなければいけません)。よって、tstart_trjcrを0にしてから、TRJに0xffffを代入、再度、tstart_trjcrを1にします。

これで、パルス幅が分かりました。受信機からは、送信機のジョイスティックの操作量に応じてON幅0.7〜2.3msのパルスが出力されますので、pulse_width変数でパルス幅を測定、パルス幅に応じてLEDを光らせたり(今回のプログラム)、モータを動かす(「モータドライブ基板Ver.4をつないでモータ制御」を参照してください)など、プログラム次第で様々な応用が可能です。

BACK