センサーで壁の有無を判断し、迷路内を自律走行!!:マイクロマウスで始める組み込み開発入門(14)(2/3 ページ)
市販の組み立てキットで「マイクロマウス」の開発を進めている北上くんとえみちゃん。これまで開発してきたプログラムをベースに、センサーで迷路内の壁の有無を判断しながら、マイクロマウスを自律走行させる。果たしてうまく走ることができるのか!?
連載第10回で、センサー値を取得するプログラムを作成しました。今回は、それをベースに走行中に壁の有無を判断するプログラムを作成します。
走行中に常に壁をチェックするので、割り込み処理を使います。これまで「CMT0」で1msの割り込み処理をしてきました。この1ms間に4つのセンサー値を取得します。「LEDをONにし、センサー値をA/D変換して、LEDをOFFにする」を行うのに90μsかかります。4つのセンサー値を次々に取得すると、トータルで360μs間は他の処理が何もできなくなってしまいます。4つのセンサーで値を1度に取得すると、その間は他の処理が何もできなくなってしまいます。そこで、新たな割り込み処理「CMT1」を作成し、4つのセンサー値を0.25msごとに順次取得します。
それでは、センサー用の割り込み処理プログラムを作成しましょう。
まず、CMT1を使う準備です。連載第8回でCMT0を扱ったときと同様に、「intprg.c」の中のCMT1を追記し、使用できるようにします(ソースコード2)。これで「CMT1」のコンペアマッチ割り込みが発生した際に、「int_cmt1」関数が実行されます。
// 188 CMT1 CMI1
//void INT_CMT1_CMI1(void){/* sleep(); */}
//CMT1割り込み(センサー)
extern void int_cmt1(void);
void INT_CMT1_CMI1(void){
int_cmt1();
}
続いて、「init.c」内の「init_cmd」関数に、CMT1の初期化処理記述を追加します(ソースコード3)。
void init_cmt(void)
{
(……中略……)
//CMT1はセンサーチェック用タイマー
CMT1.CMCSR.BIT.CMIE = 1; //割り込みを許可
CMT1.CMCSR.BIT.CKS = 0; //カウントクロックPφ/8=3MHz
CMT1.CMCSR.BIT.CMF = 0; //フラグクリア
CMT1.CMCOR = (3000/4)-1; //0.25msごとに割り込み
//
INTC.IPRJ.BIT._CMT1 = 0x0e; //割り込み優先度を次点に設定
(……中略……)
//
CMT.CMSTR.BIT.STR1 = 1; //CMT1カウント開始
//
}
これでCMT1を使う準備ができました。次に画像1のフローチャートを参照して、「intrpt.c」にCMT1割り込み処理のint_cmt1関数を作成します(ソースコード4)。ここで使用するG_SensorRや他のグローバル変数は、「Mouse2012.h」で宣言したものを、「intrpt.h」で外部参照します。このとき、volatileを付けて宣言することに注意してください。「intrpt.h」には、タイマー1割り込みフラグ「CMT1_INT_F」の宣言も必要です。
/************************************************/
/* CMT1割り込み処理 (int_cmt1) */
/************************************************/
/* センサーチェック用タイマー割り込み(0.25ms)*/
/* 0:右壁チェック */
/* 1:左壁チェック */
/* 2:前右壁チェック */
/* 3:前左壁チェック */
/************************************************/
void int_cmt1(void)
{
//センサー用タイマー割り込み(0.25ms)
static int state = 0; //読み込むセンサーのローテーション管理用変数
//
CMT1_INT_F = 0; //フラグクリア
//
switch(state)
{
case 0: //右壁チェック
G_SensorR = ctrl_adc_r(); //右センサー値取得
break;
case 1: //左壁チェック
G_SensorL = ctrl_adc_l(); //左センサー値取得
break;
case 2: //前右壁チェック
G_SensorFR = ctrl_adc_fr(); //前右センサー値取得
break;
case 3: //前左壁チェック
G_SensorFL = ctrl_adc_fl(); //前左センサー値取得
break;
}
//
state++; //4回ごとに繰り返す
if(state >= 4)
{
state = 0;
}
}
右手法で迷路を攻略
よし! これでセンサー用の割り込み処理はOKだ。
「CMT0」と「CMT1」。2つの割り込み処理を使うのがポイントなんですね。
そうなんだよ。4つのセンサー値を読み込む間も、マイクロマウスは走り続けているし、その間に他の処理を止めるわけにはいかないからね。
1度に4つの値を読まずに分割することで、待ち時間を分散しているんですね。
うん。そういうことだよ。
360μsって、ほんの一瞬って思っちゃうけど……。
そうだよね。でも、マイコンの処理スピードは速いからね〜。
“マイコンの世界”の時間感覚を意識してプログラミングするのが大事なんですね!
うん。それじゃあ、迷路走行のプログラムを作ろうか!
はーい。
Copyright © ITmedia, Inc. All Rights Reserved.
