連載
» 2007年08月22日 00時00分 公開

PWMを利用したサーボモータ制御プログラミングH8で学ぶマイコン開発入門(11)(3/3 ページ)

[宮崎 雅史 ソフィアシステムズ,MONOist]
前のページへ 1|2|3       

サーボモータを実際に制御するプログラム

 さて、上記の関数で構造体に記憶させた内容を実際に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;
        }
    }
}
リスト4 サーボモータのON/OFFを設定

 例えばリスト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);
    }
}
リスト5 サーボモータ制御のmain関数

 サーボモータを初期化する関数を実行してから(1)、サーボモータの周期を10ms、デューティ比を15%とすることで、パルス幅を1.5msとしています(2)。その後サーボモータをONにすることで、モータが中央に来るようにしていますが(3)、すぐ次のwhileループで左右どちらかに回転するような処理になっています(4)

 モータが左右どちらに振れるかはトグルスイッチの状態により決定されます。今回初めてスイッチに関する関数を使用していますが、この関数はトグルスイッチ0の状態を監視していて、スイッチがHighになっていたら1を、スイッチがLowになっていたら0を返します。スイッチ関数の仕組みについては次回で説明します。

※注:
ここでの設定周期とデューティ比は分かりやすくするための理論値なので、実際にはモータごとに多少の調整が必要になります。




 以上で、3回にわたって取り上げてきたPWMによるモータ制御は終了になります。第6回から主に出力系の装置ばかりを扱ってきましたが、今回をもって本連載で使用しているターゲットボードで制御できる出力系はすべて解説しました。次回は、トグルスイッチ、ロータリエンコーダなどの入力系について解説します。組み込み特有のC言語文法のおさらいも兼ねていますのでお楽しみに。いよいよ本連載も大詰めです。(次回に続く)

⇒ 連載バックナンバーはこちら

前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.