さて、上記の関数で構造体に記憶させた内容を実際にH8/3048F-ONEに反映させる処理は次の関数で行います(リスト4)。
引数chが0であればITUのチャネル0(サーボモータ0)の、1であればチャネル1(サーボモータ1)のレジスタを更新します。また、引数onがTRUEであれば、PWM波を出力するために必要な処理(GRA、GRBレジスタの更新、ITUのモードをPWMモードにする、ITUのカウント値を0クリアする、ITUのカウントスタート)を行います。
サーボモータの制御では、DCモータのような回転方向やブレーキの制御は必要ありませんので、以上で必要な処理は出そろったことになります。ServoSetCycle()関数の引数をいろいろと変えることで、モータを好きな位置に止めることができるようになります。
#define TRUE 1 #define FALSE 0 //---------------------------------------------------------------------- // ServoOn //---------------------------------------------------------------------- // [説明] // サーボモータのON/OFFを設定します // [入力] // ch :サーボモータを0,1で指定します // on :TRUE PWM ON // :FALSE PWM OFF // [出力] // なし // [戻り値] // なし //---------------------------------------------------------------------- void ServoOn(int ch, int on) { if(ch == 0) { ServoSet[0].on = on; if(on) { ITU0.GRA = ServoSet[0].trig; ITU0.GRB = ServoSet[0].cycle; ITU0.TCNT = 0; ITU.TMDR.BIT.PWM0 = 1; ITU.TSTR.BIT.STR0 = 1; } else { ITU.TSTR.BIT.STR0 = 0; ITU.TMDR.BIT.PWM0 = 0; } } else if(ch == 1) { ServoSet[1].on = on; if(on) { ITU1.GRA = ServoSet[1].trig; ITU1.GRB = ServoSet[1].cycle; ITU1.TCNT = 0; ITU.TMDR.BIT.PWM1 = 1; ITU.TSTR.BIT.STR1 = 1; } else { ITU.TSTR.BIT.STR1 = 0; ITU.TMDR.BIT.PWM1 = 0; } } }
例えばリスト5のように記述すると、ターゲットボードのトグルスイッチ0を切り替えるたびに、サーボモータが左右に回転するプログラムとなります。
void main(void) { int prev_sw= 0xf; // サーボモータ初期化 ServoInit(); ……(1) // 初期設定 // 周期=10ms、デューティ比=15% → パルス幅=1.5ms ServoSetCycle(0, 10000, 15); ……(2) ServoSetCycle(1, 10000, 15); // サーボモータ ON ServoOn(0, TRUE); ……(3) ServoOn(1, TRUE); while(1){ ……(4) if(IsSwOn(0)){ // 前回のスイッチ状態と比較。スイッチが切り替わったならデューティ比を変える if(prev_sw== 0){ // デューティ比=20%(プラス方向へ回転) ServoSetCycle(0, 10000, 20); ServoSetCycle(1, 10000, 20); } prev_sw= 1; } else{ // 前回のスイッチ状態と比較。スイッチが切り替わったならデューティ比を変える if(prev_sw== 1){ // デューティ比=10%(マイナス方向へ回転) ServoSetCycle(0, 10000, 10); ServoSetCycle(1, 10000, 10); } prev_sw= 0; } Wait(100); } }
サーボモータを初期化する関数を実行してから(1)、サーボモータの周期を10ms、デューティ比を15%とすることで、パルス幅を1.5msとしています(2)。その後サーボモータをONにすることで、モータが中央に来るようにしていますが(3)、すぐ次のwhileループで左右どちらかに回転するような処理になっています(4)。
モータが左右どちらに振れるかはトグルスイッチの状態により決定されます。今回初めてスイッチに関する関数を使用していますが、この関数はトグルスイッチ0の状態を監視していて、スイッチがHighになっていたら1を、スイッチがLowになっていたら0を返します。スイッチ関数の仕組みについては次回で説明します。
以上で、3回にわたって取り上げてきたPWMによるモータ制御は終了になります。第6回から主に出力系の装置ばかりを扱ってきましたが、今回をもって本連載で使用しているターゲットボードで制御できる出力系はすべて解説しました。次回は、トグルスイッチ、ロータリエンコーダなどの入力系について解説します。組み込み特有のC言語文法のおさらいも兼ねていますのでお楽しみに。いよいよ本連載も大詰めです。(次回に続く)
Copyright © ITmedia, Inc. All Rights Reserved.