行け!! マイクロマウス! ステッピングモーターで前進だ:マイクロマウスで始める組み込み開発入門(12)(2/3 ページ)
市販の組み立てキットを利用して、「マイクロマウス」の開発を進める北上くんとえみちゃん。サンプルのソースコードに頼らず、オリジナルプログラムでマイクロマウスを走らせようと奮闘中だ。今回は、いよいよモーター制御に取り掛かる!!
今回は、使用する関数が多くなるので、これから作成するモーター制御プログラムの概念図を用意しました(画像4)。
この図からも分かるように、モーター制御といっていますが、実際にマイコンが制御しているのは、モータードライバICです。モータードライバICに対し、MTUからパルスを出し、スピードや正転逆転の指示を送ることでモーターを駆動させています。
モータードライバには、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にする }
/************************************************/ /* 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; //タイマストップ (…… 中略 ……) }
続いて「Mouse2012.h」に、モーターを制御するのに必要なグローバル変数を“volatile”修飾子を付けて宣言します。volatile修飾子を付け忘れた状態でビルドすると、コンパイラがプログラムを最適化してしまい、その結果、思わぬエラーを引き起こすので注意してください(ソースコード4)。
//グローバル変数 volatile int G_TimerCount; //1msごとにカウントアップされる変数 volatile int G_StepCountR; //右モーター 1stepごとにカウントアップされる変数 volatile int G_StepCountL; //左モーター 1stepごとにカウントアップされる変数
モーターのMTU割り込みに必要な処理を「intrpt.h」と「intrpt.c」に追加します(ソースコード5)。
/************************************************/ /* 右モーターMTU割り込み処理 (int_mtr_r) */ /************************************************/ /* 右モーターが1ステップ進むごとの割り込み */ /************************************************/ void int_mtr_r(void) { //右モーターが1ステップ進むごとの割り込み MTU_R_INT_F = 0; //フラグクリア // G_StepCountR++; //ステップ数をカウント }
「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(); }
ドライバとコントローラの作成
プログラムの概念図があると、イメージがつかみやすいですね!
概要設計のときに、こうやって各モジュールの関係と役割を明確にしておくんだ。頭の中で考えているだけだと人に説明できないからね。特に、チームで開発するような場合は絶対に必要だよ。
なるほど〜。
じゃあ、ドライバとコントローラを作るよ。
はいっ!
Copyright © ITmedia, Inc. All Rights Reserved.