■課題04■

■練習問題■

秒数をカウントするだけの関数を作成せよ.そして,mainの中でそれを呼び出してセンサーラボ起動直後に3秒間何もしないまま待たせてからモータ回転を始めるようにmainを変更せよ.

ヒント

msecnタイマn回分の時間(待ち時間)
1210
2420
3630
4840
51050
.........
n2*nn*10
int wait(int millisec10)
{
 for(;;){
  if(タイマフラグ(ir_ta0ic)が立った)
   {
      タイマフラグを戻す
      カウントを増やす
   if(カウントとmillisec10の関係式を使って,指定された時間が立ったかどうか判定)
        break; //時間が立っていたらfor文を脱出
   }
  }
  return 0; //for文を脱出してここまできたら,そのまま終了
}

■必修課題■

前回のmainに残っているfor文の部分を新しい関数として独立させ,次に説明するように書き換えよ.新しい関数は,次の関数プロトタイプに従うものとする.これは,返値がint型で,int型の引数を2持つ関数であることを示している.

  int driveMotor(int target_R, int target_L);

この関数は,引数に指定されたふたつの値を,それぞれ右と左のモータの目的速度として参照することにさせる.そして5ミリ秒に一回ずつ現在のモータの回転速度を変更して,その目的速度に合致するまで増やしたり減らしたりさせるものとする.また,現在のモータの回転速度を記憶するために次の2つの大域変数を用意しておくこと.大域変数にする理由は,他の関数(例えばmain関数)からも参照することがあるためである.

  int dutydata_R; //右モータの現在の回転速度(を記憶しておくための変数)
  int dutydata_L; //左モータの現在の回転速度(を記憶しておくための変数)

もっと具体的に説明すれば,右モータの回転速度を現在のdutydata_Rを5ミリ秒に1回ずつ+1だけ増やして(あるいは減らして)target_Rになるまで繰り返し,そして左モータの回転速度は,同様にdutydata_Lをtarget_Lになるまで徐々に変化させる.

int driveMotor(int target_R, int target_L)
{
 /* 最初に引数が適切な値かどうかチェックすること. */
 if(右の目標速度(target_R)が最高速度よりも小さい)        //(注意: 小さい方が速いので)
      右目標速度を最高速度に書き換え
 else if(右の目標速度(target_R)が最低速度よりも大きい)   
      右目標速度を最低速度に書き換え
 ※左も同様に処理

 for(;;){
  if(タイマフラグが立った(※wait()と同様))
   {
      タイマフラグを戻す(※wait()と同様)

   if(現在の右モータ速度(dutydata_R)と右の目標速度(target_R)を比較)
      dutydata_Rを+1するか-1するか;
      else
      dutydata_Rを+1するか-1するか;
   if(現在の左モータ速度(dutydata_L)と左の目標速度(target_L)を比較)
      dutydata_Lを+1するか-1するか;
      else
      dutydata_Lを+1するか-1するか;

   ※この行でモータ速度とサイクルタイムから計算した値でモータ速度のレジスタを設定変更すること.
         (モータの速度を設定するためのレジスタは何か,課題2を思い出せ)

      if(両方のモータ速度が目標と一致した)
        break; //for文を脱出
    }
  }
  return 0;
}

ヒント

■必修課題の動作確認方法■

作成したwait()とdriveMotor()を使用する次のテスト用関数を作成し,mainから呼び出して動作確認を行う.

/* 関数プロトタイプのリスト */
void stop(void);
void go(void);

/* メインプログラム */
void main(void)
{
  initTimer();
  initMotor();
  tabsr = 0x0d;  //タイマA0と左右のモータの3つをスタート
 
  for(;;){//無限に繰り返し
    stop();     //ストップ
    go();       //加速
    wait(100);  //そのまま指定時間走りつづける
  }
}

/* 関数stopの本体 */
void stop(void){
  driveMotor(LOWERLIMIT,LOWERLIMIT); 右,左モータとも最低速(停止)にする
}

/* 関数goの本体 */
void go(void){
  driveMotor(UPPERLIMIT,UPPERLIMIT); 右,左モータとも最高速にする
}

※この他に,課題のwait()とdriveMotor()の本体など,その他の必要な部分を自分で追加すること

このプログラムが動作すれば,「かえる飛び」のように停止と最高速の状態を無限に繰り返すような動作をする.

■応用課題■

driveMotorで右と左の目標速度を異ならせ,一定の半径で回転するような関数を作成し,一定速度で回転しつづけるようにしてみよ.

■締め切り■