目次

動作テスト2(Forth)

 Arduino基板で使っているForthは、AmForthなので
 Arduinoのデジタルピン9、10からPWM波形を出力
 できます。

 デジタルピンの9、10は、タイマー1のOutput Compare Match
 を利用すると、簡単にPWM波形を出力可能。

 ArduinoのAPIでは、analogWriteを利用しています。

 analogWriteでは、DUTY比を0から255で設定。
 パラメータから、PWMモード利用と考えてよいで
 しょう。

 データシートに、次の一覧表があります。



 一覧表では、PWMモードにすると、カウンタの最大値を
 0xFFにできると書かれています。

 DUTY比は、0から100にした方が、考えやすいので
 Fast PWMモードにして、カウンタのリセットには0xFF
 を利用。

 Modeを5とすると、この仕様を満足できます。



 仕様を決めたなら、レジスタに設定する値を
 どう扱うのかを考えていきます。

 モード指定

  モードは、FAST PMWとしてカウンタのリセットに0x1FFを利用。
  そのため、WGM13からWGM10に2進数0101を設定。

  WGM13からWGM10をもつレジスタを探すと以下。



  TCCR1A、TCCR1Bにまたがって、レジスタ値を指定と
  なっています。

  TCCR1Aでは、Arduinoのデジタル出力が、コンペア
  マッチしたときに、論理値の'1'か'0'のどちらを
  出力するのかを指定しています。

  モータドライバは、NchMOSFETかNPNトランジスタを
  利用するとして、次の回路で採用。



  論理値の'1'でモータを回転させるとすれば、次の
  タイミングチャートと合致させればよいでしょう。



  タイマーカウンタの値とOCR1A、OCR1Bの値が一致
  したときに、論理値の'0'を出力すればよいとして
  TCCR1Aの上位4ビットを、1010に設定。

  Forthでは、次のように記述するとよいはず。

$A1 TCCR1A c!

  TCCR1Bについて、ビットパターンを考えます。

  ICNC1、ICES1は、Input Captureに関係する設定
  なので、00としておきます。

  下位3ビットは、カウンタに与えるクロックの
  プリスケーラなので、初期化時は000にして
  カウンタを動かさない様に指定。

  カウンタにクロックを与えるのは、タイマーを
  動かすときとし、初期化では、次の操作で対応。

$08 TCCR1B c!

 デジタルピンの入出力方向

  Arduinoでは、pinModeを利用して、デジタルピンの
  入出力方向を指定できました

  Output Compare Matchを利用するときには、デジタルピンを
  出力に設定して、使います。

  レジスタTCCR1Cにて、比較器の出力をデジタルピンに
  出せると記述がありました。



  ただし、これはPWMモード以外となっているので
  レジスタのDDRBを使って設定すれば充分。

$FF DDRB c!

 DUTY比とカウンタ値

  PWM波形を出力するとき、論理値の'1'と'0'の比率を
  設定するのか考えないと、制御がうまくいきません。

  カウンタの最大値を255として、TCNT1は0から255を
  繰り返すとします。

  この仕様で、OCR1A、OCR1Bへの値格納の
  操作を定義できます。

  PWM波形生成の初期化は、次のワードでよいでしょう。

: PWM_INIT
  $FF DDRB c!
  PORTB c@ $F9 and PORTB c!
  0 OCR1AL c!
  0 OCR1BL c!
  0 TCNT1L c!
  0 TCNT1H c!
  $A1 TCCR1A c!
  8 TCCR1B c!
;

  左右のモータを扱うときのDUTY比設定は
  次のように定義。

: PWM_LEFT
  8 lshift
  100 / 
  OCR1BL c!
;

: PWM_RIGHT
  8 lshift
  100 / 
  OCR1AL c!
;

 DUTY比は、0から100ですが、カウンタとの
 比較値は、0から255とするため、換算して
 おきます。

 タイマー起動

  タイマーは、クロックを与えないと動きません。

  TCCR1の下位3ビットは、カウンタに与えるクロックの
  プリスケーラになっています。カウンタに与える値を
  000でないようして、プリスケーラで1024分周にします。

  Arduinoは、16MHzで動作しているので、約16kHzで
  カウンタをインクリメントすることになります。

  起動用ワードは、次のように定義すればよいはず。

: PWM_START
  $A1 TCCR1A c!
  13 TCCR1B c!
;

 停止

  PWM波形出力を停止しなければならないときも
  あるので、そのためのワードを考えます。

  TCCR1の下位3ビットを000にすると、カウンタの
  インクリメントが止まります。

  比較値を0にすると、出力は必ず'0'になることを
  利用すれば、ダイナミックストップになります。

  ワードは、次のように定義。

: PWM_STOP
  0 0 PWM_DUTY
  8 TCCR1B c!
  0 TCCR1A c!
  PORTB c@ $F9 and PORTB c!
;

 DUTY比の同時更新

  左右のモータのDUTY比を、同時に設定できるように
  しておくと、使い勝手がよくなります。

  次のように、左右のDUTY比をスタックに入れて
  操作できるようにしました。

: PWM_DUTY PWM_RIGHT PWM_LEFT ;

  スタックトップには、右のDUTY比が置かれるので
  すでに定義してあるPWM_RIGHTを先に使っていき
  ます。

 定義したワードをまとめて見れば、以下。

: PWM_INIT
  $FF DDRB c!
  PORTB c@ $F9 and PORTB c!
  0 OCR1AL c!
  0 OCR1BL c!
  0 TCNT1L c!
  0 TCNT1H c!
  $A1 TCCR1A c!
  8 TCCR1B c!
;

: PWM_START
  $A1 TCCR1A c!
  13 TCCR1B c!
;

: PWM_STOP
  0 0 PWM_DUTY
  8 TCCR1B c!
  0 TCCR1A c!
  PORTB c@ $F9 and PORTB c!
;

: PWM_LEFT
  8 lshift
  100 / 
  OCR1BL c!
;

: PWM_RIGHT
  8 lshift
  100 / 
  OCR1AL c!
;

: PWM_DUTY PWM_RIGHT PWM_LEFT ;

 これらのワードを利用すると、PWM波形生成に
 割込みを考えなくてよくなります。

 Arduino基板には、コネクタがあるので
 コネクタを利用してモータドライバに
 接続して、動作を確認しました。

 次のように接続して、動作を確認。




目次

inserted by FC2 system