行け!! マイクロマウス! ステッピングモーターで前進だマイクロマウスで始める組み込み開発入門(12)(2/3 ページ)

» 2013年04月04日 09時30分 公開
[三月兎,MONOist]

 今回は、使用する関数が多くなるので、これから作成するモーター制御プログラムの概念図を用意しました(画像4)。

 この図からも分かるように、モーター制御といっていますが、実際にマイコンが制御しているのは、モータードライバICです。モータードライバICに対し、MTUからパルスを出し、スピードや正転逆転の指示を送ることでモーターを駆動させています。


モーター制御プログラムの概念図 画像4 モーター制御プログラムの概念図【※画像クリックで拡大表示】

 モータードライバには、3つの関数を作ります。モーター励磁関数「drv_mtr_pw」では、モーターの励磁のON/OFFを行います。モーターを動かす前にON、停止させた後にOFFの指令を出します。

 モータードライバ(左右)関数「drv_mtr」は2つの引数を持ち、左右のモーターの「停止」「前進」「後進」を指定します。また、MTUカウントの開始/停止も行っています。

 左右のモーターのMTU周期を設定する関数「drv_mtu」は、MTUから出すパルスの周期を設定し、モーターのスピードを調整します。これら3つの関数は、コントローラ層にある関数から呼び出されます。

 移動距離を制御するために、割り込み処理を使っています。MTUがパルスを出すたびに割り込みが発生し、割り込み処理の中で左右のモーターのステップ数をカウントしています。そのためのグローバル変数が用意されており、コントローラ層のモーター処理wait関数「ctrl_mtr_wait」がこのグローバル変数を読んで、指定されたステップ数に至るまで待ちます。その間、MTUはパルスを出し続け、マイクロマウスは指定された距離を走るのです。


 モーター制御プログラムのイメージがつかめたら、いつものようにプログラムを作成していきましょう。今回はソースコードが長くなるので、ヘッダーに記述するコードは掲載していません。本稿の最後に紹介するダウンロードファイルで確認してください。

 まず、「init.c」にモーター関連のI/Oポートの初期化(ソースコード2)と、MTUの諸設定を追加します(ソースコード3)。

/************************************************/
/*    I/Oポート初期化            (init_io)    */
/************************************************/
/*    ポートを初期化する                        */
/************************************************/
void init_io(void)
{
 
    (…… 中略 ……)
 
    //モーター励磁
    PFC.PBIORL.BIT.B5        = 1;    //PB5を出力に設定
    //モータードライバ
    PFC.PEIORL.BIT.B8        = 1;    //PE8を出力に設定(右Clock)
    PFC.PEIORL.BIT.B9        = 1;    //PE9を出力に設定(右CWCCW)
    PFC.PEIORL.BIT.B10       = 1;    //PE10を出力に設定(左CWCCW)
    PFC.PEIORL.BIT.B12       = 1;    //PE12を出力に設定(左Clock)
    //モーターMTU
    PFC.PECRL3.BIT.PE8MD     = 1;    //MTU端子に設定
    PFC.PECRL4.BIT.PE12MD    = 1;    //MTU端子に設定
    //モーター励磁OFF
    PB.DR.BIT.B5             = 1;    //モーター励磁をOFFにする
}
ソースコード2 「init.c」内のI/O初期化関数「init_io」にモーター関連の設定を追加

/************************************************/
/*    MTU初期化                 (init_mtu)    */
/************************************************/
/*    MTUを初期設定する                         */
/*    MTU22:ブザー用                           */
/*    MTU23:右モーター用                       */
/*    MTU24:左モーター用                       */
/************************************************/
void init_mtu(void)
{
 
    (…… 中略 ……)
 
    //右モーター用MTU設定
    MTU23.TCR.BIT.TPSC = 1;            //MTU23の動作クロックは24/4=6MHz
    MTU23.TCR.BIT.CCLR = 1;            //TGRAコンペアマッチでカウンタクリア
    MTU23.TIOR.BIT.IOB = 2;            //初期出力0コンペアマッチ1出力
    MTU23.TIOR.BIT.IOA = 1;            //初期出力0コンペアマッチ0出力
    MTU23.TGRA = 22000;                //周期(MIN_SPEED(100)の周期)
    MTU23.TGRC = 22000;                //周期のバッファ
    MTU23.TGRB = 50;                   //パルス幅
    MTU23.TMDR.BIT.MD = 2;             //PWMモード1に設定
    MTU23.TMDR.BIT.BFA = 1;            //TGRCをTGRAのバッファレジスタとして使用
    MTU23.TIER.BIT.TGIEB = 1;          //TGRAコンペアマッチでの割り込み許可
    INTC.IPRE.BIT._MTU23G = 0xd;       //割り込み優先度を設定
    //左モーター用MTU設定
    MTU24.TCR.BIT.TPSC = 1;            //MTU24の動作クロックは24/4=6MHz
    MTU24.TCR.BIT.CCLR = 1;            //TGRAコンペアマッチでカウンタクリア
    MTU24.TIOR.BIT.IOB = 2;            //初期出力0コンペアマッチ1出力
    MTU24.TIOR.BIT.IOA = 1;            //初期出力0コンペアマッチ0出力
    MTU24.TGRA = 22000;                //周期(MIN_SPEED(100)の周期)
    MTU24.TGRC = 22000;                //周期のバッファ
    MTU24.TGRB = 50;                   //パルス幅
    MTU24.TMDR.BIT.MD = 2;             //PWMモード1に設定
    MTU24.TMDR.BIT.BFA = 1;            //TGRCをTGRAのバッファレジスタとして使用
    MTU24.TIER.BIT.TGIEB = 1;          //TGRAコンペアマッチでの割り込み許可
    INTC.IPRF.BIT._MTU24G = 0xc;       //割り込み優先度を設定
    //
    MTU2.TOER.BYTE=0xff;               //MTU出力端子を出力許可する
    //
    MTU2.TSTR.BIT.CST4 = 0;            //タイマストップ
    MTU2.TSTR.BIT.CST3 = 0;            //タイマストップ
 
     (…… 中略 ……)
 
}
ソースコード3 連載第9回で作成した「init.c」内のMTU初期化関数「init_mtu」に、モーター関連の設定を追加

 続いて「Mouse2012.h」に、モーターを制御するのに必要なグローバル変数を“volatile”修飾子を付けて宣言します。volatile修飾子を付け忘れた状態でビルドすると、コンパイラがプログラムを最適化してしまい、その結果、思わぬエラーを引き起こすので注意してください(ソースコード4)。

//グローバル変数
volatile int    G_TimerCount;       //1msごとにカウントアップされる変数
volatile int    G_StepCountR;       //右モーター 1stepごとにカウントアップされる変数
volatile int    G_StepCountL;       //左モーター 1stepごとにカウントアップされる変数
ソースコード4 「Mouse2012.h」に、左右のモーターを制御するグローバル変数を定義

 モーターのMTU割り込みに必要な処理を「intrpt.h」と「intrpt.c」に追加します(ソースコード5)。

/************************************************/
/*    右モーターMTU割り込み処理  (int_mtr_r)  */
/************************************************/
/*    右モーターが1ステップ進むごとの割り込み   */
/************************************************/
void int_mtr_r(void)
{
    //右モーターが1ステップ進むごとの割り込み
    MTU_R_INT_F = 0;       //フラグクリア
    //
    G_StepCountR++;        //ステップ数をカウント
}
ソースコード5 「intrpt.c」内に右モーターのMTU割り込み処理関数「int_mtr_r」を記述。左モーター用の「int_mtr_l」も同様に作成

 「intprg.c」に「intrpt.c」で作った関数を登録し、MTUの割り込み処理が呼び出されるようにします(ソースコード6)。

// 113 MTU2_3 TGIB3
//右モーターのMTU割り込み
//void INT_MTU2_3_TGIB3(void){/* sleep(); */}  <= コメントアウト
extern void int_mtr_r(void);
void INT_MTU2_3_TGIB3(void){
    int_mtr_r();
}
 
 (…… 中略 ……)
 
// 121 MTU2_4 TGIB4
//void INT_MTU2_4_TGIB4(void){/* sleep(); */}  <= コメントアウト
//左モーターのMTU割り込み
extern void int_mtr_l(void);
void INT_MTU2_4_TGIB4(void){
    int_mtr_l();
}
ソースコード6 「intprg.c」の自動生成ソースコードをコメントアウトし、これから作るタイマー割り込み関数をそれぞれ宣言

ドライバとコントローラの作成

えみ

プログラムの概念図があると、イメージがつかみやすいですね!


北上

概要設計のときに、こうやって各モジュールの関係と役割を明確にしておくんだ。頭の中で考えているだけだと人に説明できないからね。特に、チームで開発するような場合は絶対に必要だよ。


えみ

なるほど〜。


北上

じゃあ、ドライバとコントローラを作るよ。


えみ

はいっ!



Copyright © ITmedia, Inc. All Rights Reserved.