回転速度を変えるにはPWMのデューティ比を変化させます。(リスト3)
リスト3
27行目: ディップスイッチの下位2ビットの値に250を掛けてウエイト時間を調節しデューティ比を決める(表3)
SW1 | SW2 | |
デューティ比 0% | L | L |
デューティ比 25% | L | H |
デューティ比 50% | H | L |
デューティ比 100% | H | H |
表3
PWMのデューティ比を変えることで車輪の回転速度が変化することが実感できたと思います。
ここまでは単純にポートを操作してPWMを出力していました。しかしながら、この方法では車輪の回転速度をコントロールしながら別の作業をすることはできません。29行目,31行目のfor文ループの間CPUはただひたすらループカウンタのiを足し算します。あまり有効的な使い方とはいえません。ここからはマイコンに内蔵のタイマモジュールを使ってPWMを出力したいと思います。
タイマにはカウンタがあり、ある決められた周期でカウントアップしていきます。カウンタは8ビット,16ビット等あり8ビットなら255までカウントアップし、0に戻るとき(オーバフロー)にイベントを発生させたり、またある値を設定しておいてカウンタがその値と同じになったとき(コンペアマッチ)にイベントを発生させたりすることができます。(図4)
図4
PUPPYに対応するH8/Tinyマイコンの内蔵モジュールにタイマZがあります。タイマZは16ビットのカウンタをもつ多機能タイマです。PWMモードがあり、簡単にPWMを出力することができます。先ほどはPWMを出力するのにP63を汎用出力ポートとして利用しました。P63には汎用入出力の他にFTIOD0というタイマ入出力の機能も持っています。
タイマZには、ジェネラルレジスタA(GRA)〜ジェネラルレジスタD(GRD)の4本のレジスタがあり、それらにあらかじめ値を設定しておきます。タイマカウンタ(TCNT)がカウントアップしてジェネラルレジスタに設定した値と同じ値になったとき(コンペアマッチ)にあらゆるイベントを発生することができます。例えば
初期出力HI
GRAに100 GRDに25を設定
GRAのコンペアマッチでタイマカウンタクリア、FTIOD0端子をHIに
GRDのコンペアマッチでFTIOD0端子をLOに
このときの動作は図6のようになります。
図5
@初期出力HI
AGRDのコンペアマッチでFTIOD0端子をLOW
BGRAのコンペアマッチでFTIOD0端子をHI
CGRAのコンペアマッチでカウンタクリア
この例の場合ではGRAをPWMの周期設定に、GRDをPWMのデューティ比設定に使用しています。内部クロックを20MHz、カウントソースをφとするとFTIOD0端子から周波数200kHz、デューティ比25パーセントのPWMが出力されることになります。
これらを踏まえてハードウェアマニュアルを見ながらタイマZのレジスタを設定してみましょう
1)GRAのコンペアマッチでタイマカウンタをクリアする設定にするにはTCR(タイマコントロールレジスタ)のbit7〜bit5のCCLRを001に設定します。
2)FTIOD端子をPWMモードで使用するためにビット3のPWMD0に1をセットします
3)初期出力HIは、TOCR(タイマアウトプットコントロールレジスタ(TOCR)を設定します。bit3でFTIOD0端子の初期出力が設定できます。初期出力をHI にするには1をセットします。
4)GRAのコンペアマッチでFTIOD0端子をHI ,GRDのコンペアマッチでLOWにするにはPOCR(PWMモードアウトプットレベルコントロールレジスタ)を設定します。今回の組み合わせでは初期値どおりなので設定の必要はありません。
5)GRAに100を、GRDに25を設定します。
6)TOER(タイマアウトプットマスタイネーブルレジスタ)でFTIOD0端子からのPWM出力を許可します。
7)TSTR(タイマスタートレジスタ)でチャネル0のタイマカウンタをスタートします。
上の手順でFTIOD0端子からPWM出力が出るはずです。先ほどの演習課題で作成したプログラムを改良してタイマZでPWMを出力するプログラムを作成してみましょう