目次

モーターを回す

 書籍の付録には、DCモータがひとつ入っていました。



 DCモータを回すためのドライブ回路が紹介されています。



 ドライブ回路は、パワートランジスタのコレクタにモータの
 片側を接続し、もう一方は電源に接続。

 DCモータ内部のブラシで発生するノイズ低減にキャパシタを
 入れ、逆起電力でパワートランジスタが破損することを防ぐ
 ためのフライホィールダイオードが入っています。

 ドライブ回路は、電源からモータに電力を与えることですが
 マイコンの出力ピンから流せる電流は1mA程度で、モータが
 必要とする電流(最大500mAくらい)には、ほど遠いために
 電流増幅の目的で、トランジスタを使っています。

 電源電圧を5Vとすると、500mA流すと2500mWくらいになり
 ますが、回ってしまえば10mA程度になるので1Aくらいの
 電流を流せるパワートランジスタを利用します。

 ボタンを押したときだけ、モータが回転するという
 システムを実現する回路は、以下。



 LEDは、スイッチを押していることとモータを回転して
 いることのモニタに使っています。

 ポートBの各ビットは、次のように利用。

 I/Oの設定は、次のコードでよいでしょう。

  TRISB = 0x01 ; /* 0b00000001 */

 スイッチを押したときに、RB0に'0'が印加されるので
 LEDが点灯、モータが回転となるには、'1'を出力する
 となります。

  PORTB.F1 = ~PORTB.F0 ;
  PORTB.F2 = ~PORTB.F0 ;

 モータを回転させるための制御コードは、以下。

#define OFF 0
#define ON  OFF+1

/* prototype */
void usr_init(void);

void main(void)
{
  /* initialize PORT */
  usr_init();
  /* endless loop */
  while (ON) {
    PORTB.F1 = ~PORTB.F0 ;
    PORTB.F2 = ~PORTB.F0 ;
  }
}

void usr_init(void)
{
  /* turn off LED */
  PORTB.F1 = OFF ;
  /* stop motor */
  PORTB.F2 = OFF ;
  /* direction */
  TRISB = 0x01 ;
}

 これで回すだけはできるようになりました。

 モータの回転制御には、PWM(Pulse Width Modulation)を
 利用します。

 PWMは、モータに与える電力を電流が流れている時間幅で
 制御します。



 PWMによるモータの回転スピードを制御するシステムは以下。


 ポートBの各ビットは、次のように利用。


 PWMに利用する波形生成のための関数を定義して利用します。

typedef unsigned char UBYTE ;

void PWM(UBYTE x)
{
  /* turn on LED and rotate motor */
  PORTB.F2 = ON ;
  PORTB.F3 = ON ;
  /* delay */
  Vdelay_ms(x);
  /* turn off LED and stop motor */
  PORTB.F2 = OFF ;
  PORTB.F3 = OFF ;
  /* delay */
  Vdelay_ms(10-x);
}

 10msの間で、電流を流している時間を止めている時間を
 用意し、PWMの波形を構成します。

 片方のボタンを押していると高速、もう一方の
 ボタンを押していると低速回転となるように
 システムを構成するときのコードは、以下。

#define OFF 0
#define ON  OFF+1

#define SWON  0
#define SWOFF SWON+1

#define HS 9
#define LS 1

typedef unsigned char UBYTE ;

/* prototype */
void usr_init(void);
void PWM(UBYTE x);

void main(void)
{
  /* initialize PORT */
  usr_init();
  /* endless loop */
  while (ON) {
    /* switch 0 */
    while ( PORTB.F0 == SWON ) {
      PWM(HS);
    }
    /* switch 1 */
    while ( PORTB.F1 == SWON ) {
      PWM(LS);
    }
  }
}

void usr_init(void)
{
  /* turn off LED */
  PORTB.F2 = OFF ;
  /* stop motor */
  PORTB.F3 = OFF ;
  /* direction */
  TRISB = 0x03 ;
}

void PWM(UBYTE x)
{
  /* turn on LED and rotate motor */
  PORTB.F2 = ON ;
  PORTB.F3 = ON ;
  /* delay */
  Vdelay_ms(x);
  /* turn off LED and stop motor */
  PORTB.F2 = OFF ;
  PORTB.F3 = OFF ;
  /* delay */
  Vdelay_ms(10-x);
}

 高速と低速の回転ではなく、回転と停止にしたい場合
 #defineによる値定義を、次のように変更します。

#define HS 8
#define LS 0

 プログラム本体ではなく、先頭におかれている数値の
 定義を変更するだけで対応できます。

 回転スピード制御が可能になったので、回転方向を
 変更できるようにします。それにはHブリッジを利用。



 Hブリッジ回路を入れたシステムは、以下。



 Hブリッジ回路を使うには、電流が流れる方向を決めれば
 よいので、左回転、右回転の関数を定義して対応します。
 左回転、右回転の関数は、以下。


void motor_left(void)
{
  PORTB.F2 = ON  ;
  PORTB.F3 = OFF ;
}

void motor_right(void)
{
  PORTB.F2 = OFF ;
  PORTB.F3 = ON  ;
}

void motor_stop(void)
{
  PORTB.F2 = OFF ;
  PORTB.F3 = OFF ;
}

 片方のボタンを押していると右回転、もう一方の
 ボタンを押していると左回転となるようにコード
 を記述すると、以下。

#define OFF 0
#define ON  OFF+1

#define SWON  0
#define SWOFF SWON+1

/* prototype */
void usr_init(void);
void motor_left(void);
void motor_right(void);
void motor_stop(void);

void main(void)
{
  /* initialize PORT */
  usr_init();
  /* endless loop */
  while (ON) {
    motor_stop();
    /* switch 0 (left rotate) */
    while ( PORTB.F0 == SWON ) {
      motor_left();
    }
    /* switch 1 (right rotate) */
    while ( PORTB.F1 == SWON ) {
      motor_right();
    }
  }
}

void usr_init(void)
{
  /* turn off LED */
  PORTB.F2 = OFF ;
  /* stop motor */
  PORTB.F3 = OFF ;
  /* direction */
  TRISB = 0x03 ;
}

void motor_left(void)
{
  PORTB.F2 = ON  ;
  PORTB.F3 = OFF ;
}

void motor_right(void)
{
  PORTB.F2 = OFF ;
  PORTB.F3 = ON  ;
}

void motor_stop(void)
{
  PORTB.F2 = OFF ;
  PORTB.F3 = OFF ;
}

 通常は右回転していて、片方のボタンを押すと停止、
 もう一方のボタンを押すると左回転にするにはmain
 の中の記述を変えます。

  /* endless loop */
  while (ON) {
    /* right rotate */
    motor_right();
    /* switch 0 (stop) */
    while ( PORTB.F0 == SWON ) {
      motor_stop();
    }
    /* switch 1 (left rotate) */
    while ( PORTB.F1 == SWON ) {
      motor_left();
    }
  }

 ライントレースロボットを動かすような場合、モータの回転
 スピードを変えつつ、回転方向も逆にすることが要求されて
 きます。

 モータを2個以上使う場合、タイマー割込みを利用し
 main関数は、処理の交通整理と指示だけにします。

 複数のモータを同時に動かすコードは、次ページで説明します。


目次

inserted by FC2 system