H8CPUのビット出力の使用法

Copyright(C) 10May2002
Copyright(C) 18Apr2002
Copyright(C)  7Mar2002
coskx

はじめに

この文書はH8CPUでモータなどを駆動するにはどうしたらよいかを解説しています。対象はH8CPUを使ったCPUボードのAKI-H8になっていますが,その他のCPU等でもその電流仕様を理解すれば使えるようになっているはずです。

【1】ビット出力

H8CPUで特定のポートの特定のビットに0または1を書き込むと,そのままCPUのある端子の電圧が変化する。
例えばポート1の第0ビットに0または1を書き込むと,CPUの36番ピンの電圧が変化する。
AKI-H8では,CPUの36番ピンに結線されているコネクタ3の15番ピンの電圧が変化する。
このときの様子を表にすると表1.1のようになる。

表1.1 「ポートのビット」と「CPUのピン」および「コネクタのピン」の関係

ポート番号とビット番号の表記 Cプログラムでの表記 CPUの36番ピン コネクタ3の15番ピン
ポート1の第0ビットに0を出力 P1.DR.BIT.B0=0; 約0ボルト 約0ボルト
ポート1の第0ビットに1を出力 P1.DR.BIT.B0=1; 約5ボルト 約5ボルト

注意:CPUの36番ピンは測定が難しいので測定しないこと
注意:測定にはオシロスコープあるいはディジタルテスタ等を用いること
補足:P1.DRはP1のデータレジスタであり8ビット構成である。.BIT.B0はその第0ビットを表す。

【2】ビット出力の方法

先の例のようなビット出力を行なうには,そのビットを出力用に初期化してからおこなう。
P1.DDRはデータディレクションレジスタ(方向レジスタ)と呼ばれ8ビット構成である。
P1の各ビットごとに方向を定めることが出来,出力にしたい場合は1を入力にしたい場合は0をプログラムの最初に設定する。

P1.DDR=1;   /*P1の第0ビットのみ出力に設定,他の7ビットは入力*/

のように書き,その後で

P1.DR.BIT.B0=0;

あるいは

P1.DR.BIT.B0=1;

と書いて出力できる。

ポート1の第0ビットに0と1を交互に高速出力するサンプルプログラム(このプログラムを実行しても点滅がはやすぎて目では点滅が確認できない)

#include "3048f.h"

main()
{
    P1.DDR=1; /*P1の第0ビットのみ出力に設定,他の7ビットは入力*/
    while (1) {
        P1.DR.BIT.B0=0; /*P1の第0ビットに0を出力*/
        P1.DR.BIT.B0=1; /*P1の第0ビットに1を出力*/
    }
}

ポート1の第0ビットに0と1を約1秒ごとに交互出力するサンプルプログラム(このプログラムなら点滅が確認できます)

#include "3048f.h"

void msecwait(int msec)
/*msec間なにもしない時間稼ぎ関数*/
{
    int i,j;
    for (i=0;i<msec;i++) {
        for (j=0;j<1588;j++);    /*1588は実測によって求めた値*/
    }
}

main()
{
    P1.DDR=1; /*P1の第0ビットのみ出力に設定,他の7ビットは入力*/
    while (1) {
        P1.DR.BIT.B0=0; /*P1の第0ビットに0を出力*/
        msecwait(1000); /*1000msecの間なにもしない*/
        P1.DR.BIT.B0=1; /*P1の第0ビットに1を出力*/
        msecwait(1000); /*1000msecの間なにもしない*/
    }
}

【3】ビット出力で直接モータを駆動できるか?

図3.1の左図のように1.5Vの乾電池にモータをつないで模型用の小型DCモータを回すことができる。CPUはビット出力で1の出力を行なうと,接続された外部端子には5V程度が出力される。5Vも出力してくれるのだから,右図のようにビット出力外部端子にモータをつないでも回りそうである。しかしこの5Vを用いてモータを駆動することは残念ながら出来ない。(このような実験は,やってはいけない
模型用の小型DCモータ(数W,3V)を無負荷(モータの軸になにもつけない状態)で回すために必要な電流は数100mA程度である。ただし起動時には一瞬だがその数倍程度流れる。モータを回すには,このくらいの電流(モータによってはそれ以上の電流)が必要ということになる。

MOTORDIRECTDRIVE.GIF - 3,827BYTES
図3.1 乾電池でモータ駆動しているところとH8CPUのポート1第0ビットで駆動?(実際には,やってはいけない

図3.1の右図のようにした時,どうして回らないかというと,H8などのCPUは電流駆動能力がないからである。H8CPUのユーザーマニュアルでDC特性を調べてみると次のように書いてある。

ビット出力で1を出力している端子は最大で2mAまで電流を流し出すことが出来る。さらに全ビット出力合計で40mAとなっている。
また,ビット出力で0を出力している端子は最大で2mAまで電流を吸い込むことが出来る。この場合は全ビット出力合計で120mAとなっている。(ビット出力で0を出力して電流を吸い込むように設計した場合は,ポート1,2,5,Bの各端子は最大で10mAまで電流を吸い込むことが出来る。この使い方の場合はこれらのポートの全ビット出力合計で80mAとなっており,これらのポートを含む全ビット出力合計で120mAとなっている。)

モータがまわらないのは,CPUには電流駆動能力がないためであった。以下少ない電流で駆動できるLEDから話を始め,次第に大電流を駆動する方法を明らかにしよう。そして最後にモータの駆動についてその方法を紹介する。

【4】ビット出力で発光ダイオード(LED)駆動(その1) [2mA以下]

発光ダイオード(LED)は図4.1のような形状で方向性がある素子である。順方向(アノードからカソードに電流が流れる方向)に規定の電流を流すと発光する。

P_LED.JPG - 5,650BYTES
図4.1 発光ダイオード(左側定格10mA仕様,右側定格20mA仕様)
足が長いほうがアノード,短いほうがカソード

通常の発光ダイオード(LED)の性質は,
(1)2mAから10mAの電流で点灯させることが出来る。(10mA以上の電流を流さないようにする
(2)自分自身で1.8V程度の電圧降下がある。(図4.2でVd=1.8[V]となる。)
である。
もしVcc=5[V]を用いるとすると,図4.2のように抵抗R[Ω]を入れて,電流制限を行なわなければならない。10mA電流を流すように設計するには,
(a)Vcc=Vd+Vr
(b)Vr=i×R
(c)Vcc=5[V]
(d)Vd=1.8[V]
(e)i=0.01[A] (抵抗中を流れる電流とダイオード中を流れる電流の値は等しい。)
よりR=320[Ω]を電流制限用抵抗とすればよいことになる。

DIODE1.GIF - 1,691BYTES
図4.2 電流制限用抵抗を用いたLED駆動
発光ダイオードLEDは上がアノード,下がカソードである。
左の図と右の図は同じ概念を描いている。
電池とその接続をすべて書くのは面倒なため右の図のように描かれることが多い。

ここで図4.3のようにH8のポート1ビット0でLEDを点灯させることを考えよう。H8のポート1ビット0の電流出力能力は2mA,出力電圧はV=5[V]を考えよう。そうすると
(a)V=Vd+Vr
(b)Vr=i×R
(c)V=5[V]
(d)Vd=1.8[V]
(e)i=0.002[A]
となるので,R=1600[Ω]=1.6[kΩ]の保護抵抗が必要となる。
実際AKI-H8のマザーボード上ではLEDが1.5kΩの保護抵抗付きでポート5の第0ビット,第1ビットに接続されている。

DIODE2.GIF - 2,313BYTES
図4.3 H8のポート1ビット0でLEDを点灯

【5】ビット出力でLED駆動(2) [10mA以下]

LEDを2mAで駆動した時,暗く感ずる。定格電流10mAで明るくLEDを駆動したい場合について考えよう。ポート1,2,5,Bの各端子は0出力の時,10mAまで吸い込むことが可能であることを利用する。次の図5.1のような結線とし,保護抵抗を320Ωにすれば,10mAの電流が流れる。ただし,ポート1の第0ビットに0を出力すると36番ピンは0Vになって電流を10mA吸い込むのでLEDが点灯し,第0ビットに1を出力すると36番ピンは5Vになって電流を吸い込まなくなるのでのでLEDは消灯する。すなわち負論理制御になる。

DIODE3.GIF - 2,243BYTES
図5.1 負論理制御で10mAでのLED駆動

【6】ビット出力でLED駆動(3) [100mA以下]

LEDの中には高輝度のものがあり,50mA(定格)で駆動するものがある。もはやH8CPU単独では駆動電流が足りない。そこでトランジスタ2SC1815(図6.1)を用いて電流増幅する。ここではトランジスタはベース電流が図6.2のように流れると,コレクタ電流を流すことは出来るようになるスイッチと考えてよい。実際にはコレクタ電流はベース電流の100〜700倍になる。ただし,コレクタ電流は最大で100mAまでしか流すことが出来ない。(2SC1815の定格)

P_TRANSIDTOR.JPG - 4,674BYTES
図6.1 トランジスタ2SC1815 足は左からエミッタ,コレクタ,ベース

TRANSISTOR.GIF - 1,846BYTES
図6.2 トランジスタの電流増幅

トランジスタでの駆動の前に図6.3のような本物のスイッチを使う回路を考えてみよう。
(a)Vcc=Vd+Vr
(b)Vr=i×R
(c)Vcc=5[V]
(d)Vd=1.8[V]
(e)i=0.05[A]
より保護抵抗R=64[Ω]を用いればよいことになる。

SWMODEL1.GIF - 1,896BYTES
図6.3 スイッチによるLEDのON-OFF回路

図6.3のスイッチをトランジスタに置き換え,50mAで駆動LEDの制御回路は図6.4のようになる。ただし
(a)Vcc=Vce+Vd+Vr
(b)Vr=i×R
(c)Vcc=5[V]
(d)Vce=0.9[V]
(e)Vd=1.8[V]
(f)Vbe=0.8[V]
(g)i=0.05[A]
(h)ib=0.002[A]  (H8CPU1端子当たり最大電流2mAなので)
(i)5-Vbe=ib×Rb (ポート1第0ビットは5Vを出力)
より,2つの保護抵抗はRb=2100[Ω]=2.1[kΩ],R=230[Ω]とすればよい。

DIODE4.GIF - 2,830BYTES
図6.4 トランジスタ電流増幅を利用した高輝度LED駆動

なお,トランジスタをスイッチと考えてよいと述べたが,図6.5のようにスイッチならどこにつけてもよいが,トランジスタは図6.6のような位置につけるとVbeが確保できなくなり必要な電流ibが確保できず,動作しなくなる。図6.4のようにエミッタは必ずグランドの位置に置くようにしなければならない。

SWMODEL1A.GIF - 1,274BYTES SWMODEL1B.GIF - 1,269BYTES
図6.5 スイッチならどこにおいても同じように回路は動作する

SWMODELWRONG.GIF - 3,511BYTES
図6.6 トランジスタの悪い配置例(このような回路を作ってはいけない

【7】ビット出力でLED駆動(4) [100mA以上 数A以下]

超高輝度LEDには250mA(定格)を流すものや,赤外線LEDのように100mA(定格)を流すものがある。トランジスタ2SC1815ではトランジスタの定格電流100mAが限界を与えるようになる。このような時はダーリントン結合のトランジスタやパワーMOSFETを用いる。
パワーMOSFET(2SK2886)は図7.1の形状で,図7.2のように,ゲート-ソース間電圧が5Vになるとドレイン電流が数A流れるスイッチと考えられる。トランジスタと違い,ゲートに電流が流れ込まない。

P_2SK2886.JPG - 5,483BYTES
図7.1 パワーMOSFET 2SK2886

FET.GIF - 1,762BYTES
図7.2 パワーMOSFET

次の図7.3,図7.4は400mA駆動の赤外線LED(32個モジュール)を駆動する回路である。図7.3は本物のスイッチを用いた例,図7.4はパワーMOSFETを用いた例である。この2つの例では8個を直列にして12Vで駆動するとLED1個あたり1.5Vが加わるので保護抵抗は不要になる。パワーMOSFETはゲートに電流は流れ込まないのでそのままつないでよい。ただし,図7.4では事故からの保護のために数10kオームの抵抗を36番ピンとFETのゲートの間にはさんでも良い。

SWMODEL2.GIF - 2,222BYTES
図7.3 400mA駆動赤外線発光モジュールをスイッチで駆動したところ

DIODE5.GIF - 2,796BYTES
図7.4 400mA駆動赤外線発光モジュールをパワーMOSFETで駆動したところ

【8】ビット出力でモータを駆動する(1)

モータは数100mAから数Aの電流を必要とするのでパワーMOSFETを用いれば駆動できそうである。もしスイッチでモータを制御すると図8.1のようになる。スイッチをパワーMOSFETで置き換えて図8.2のような回路にすればよいと思われるが,モータは電気的な雑音が多く発生するため,CPUが誤動作を起こす可能性があるためこのような回路は実用的ではない。

MOTORSW0.GIF - 2,441BYTES
図8.1 DCモータをスイッチで制御

MOTOR1.GIF - 3,121BYTES
図8.2 モータ駆動回路(モータのノイズでCPUが誤動作を起こすのでこの回路は作ってはいけない

そこで図8.3のように光アイソレータを用いて電気的に絶縁するとよい。光アイソレータとは発光ダイオードと光トランジスタで構成される,信号伝達・電気絶縁素子である。ここで光アイソレータ中の発光ダイオードの点灯のための保護抵抗は【5】で計算した値である。
こうすることにより,CPUを含む論理回路とモータ駆動系は電気的には離れた状態にすることが出来る。
しかしこのままではモータは一方向にしか回らない

MOTOR2.GIF - 4,039BYTES
図8.3 モータ駆動回路(論理回路とモータ駆動系を絶縁)

補足 図8.3の回路の説明

話を簡単なスイッチに戻そう。抵抗とスイッチのみで出来た回路である。
図8.4の左側はスイッチがOFFになっている。この時,電流は流れないので(オームの法則)スイッチの上部はどこも電位は等しく+12Vである。
図8.4の右側はスイッチがONになっている。抵抗を電流が流れるので抵抗中で電圧低下が起こり,抵抗の下部はどこも電位は等しく0Vである。

MOTORSW1.GIF - 2,094BYTES
図8.4 スイッチの状態と出力

スイッチのON-OFFを利用してパワーMOSFETのON-OFFを行なって,モータを回してみよう。
図8.5の左側はスイッチがOFFなのでパワーMOSFETのゲートには+12Vがかかり,FETはONになるため,モータは回る。
図8.5の右側はスイッチがONなのでパワーMOSFETのゲートは0Vになってしまうため,FETはOFFとなり,モータは回らない。
(スイッチのON-OFFの動作とモータのON-OFFの動作が逆であることに注意)

MOTORSW2.GIF - 4,906BYTES
図8.5 スイッチによるパワーMODFETを利用したモータ駆動

次に光アイソレータを用いてみよう。光アイソレータは「発光ダイオード」と「光トランジスタ」で出来ている。
「発光ダイオード」は電流を流すと発光する。
「光トランジスタ」は光があたるとONになり,光がなくなるとOFFになるトランジスタである。
図8.6の左側は発光ダイオードが発光していないので光トランジスタがOFFとなる。よってパワーMOSFETのゲートには+12Vがかかり,FETはONになるため,モータは回る。
図8.6の右側は発光ダイオードが発光しているので光トランジスタがONとなる。よってパワーMOSFETのゲートは0Vになってしまうため,FETはOFFとなり,モータは回らない。

PHOTOISO1.GIF - 2,193BYTES
図8.6 光アイソレータにおけるLEDの発光と出力の関係

この性質を用いると図8.7のようにDCモータのON-OFFが可能となる。これを完成すると図8.3となる。

PHOTOISO2.GIF - 3,002BYTES
図8.7 光アイソレータを用いたモータ駆動方法

【9】ビット出力でモータを駆動する(2)

モータを正転・逆転できるように制御しよう。始めにスイッチでモデルを考えると図9.1のようになる。図9.1左ではスイッチAとD同時にONになっている。また図9.1右ではスイッチBとCが同時にONになっている。このような回路を作るとDCモータを正逆転させることが出来る。

HSW.GIF - 5,462BYTES
図9.1 スイッチによるDCモータ正逆転回路

スイッチによる正逆転回路をCPUとパワーMOSFETを使って作り直してみる。ポート1の第0ビットと第1ビットを使うことにし,表9.1のように動作を割り当てよう。

表9.1 動作割り当て

P1.DR.BIT.B0(36番ピン)

P1.DR.BIT.B1(37番ピン)

DCモータ

0

0

まわらない

0

1

正転

1

0

逆転

1

1

定義されない

図9.2のように4つのパワーMOSFETを利用するとこの関係が作れそうだ。このような回路はモータを4つのFETの真中に描いた時の形からH型ドライバ回路と呼ばれる。次の4つの状態を考えてみよう。

ポート1第0ビットに0を出した時

36番ピンが0V,その先のLEDがON,その右の光トランジスタがON,FET_CとFET_Bのゲートが0Vとなり,FET_CとFET_BはOFF

ポート1第1ビットに0を出した時

37番ピンが0V,その先のLEDがON,その右の光トランジスタがON,FET_AとFET_Dのゲートが0Vとなり,FET_AとFET_DはOFF

ポート1第0ビットに1を出した時

36番ピンが5V,その先のLEDがOFF,その右の光トランジスタがOFF,FET_CとFET_Bのゲートが5Vとなり,FET_CとFET_BはON

ポート1第1ビットに1を出した時

37番ピンが5V,その先のLEDがOFF,その右の光トランジスタがOFF,FET_AとFET_Dのゲートが5Vとなり,FET_AとFET_DはON

HDRIVER1.GIF - 5,139BYTES
図9.2 H型ドライバを用いたDCモータ正逆転回路の例(実用回路ではないためこのまま作らないこと

FET_AとFET_Dが同時にONになると図9.3の左のようにDCモータに電流が流れる。
またFET_CとFET_Bが同時にONになると図9.3の右のようにDCモータに電流が流れる。
このようにしてモータの正逆転が実現できる。

HDRIVER2.GIF - 5,546BYTES
図9.3 DCモータ正逆転の様子

H型回路の動作はこれで理解できた。
これでうまくいったように思えるが,実際の動作では表9.2のような問題点がある。プログラムを作る段階で両方同時に0を出さないように気をつけていればすみそうだが,問題は簡単ではない。5Vの電源(CPUも使っている)がOFFで12Vの電源がONの時を考えると。LED,光トランジスタすべてがOFFになり,4つのFETがONになってしまう問題がクリアできない。

表9.2 実際の動作の問題点。

P1.DR.BIT.B0(36番ピン)

P1.DR.BIT.B1(37番ピン)

DCモータ

0

0

まわらない

0

1

正転

1

0

逆転

1

1

4つのFETが同時にONになり回路が燃える

この問題をクリアするには,回路構成を改良すればよい。すなわち,次の2つを改良する。
(1)光トランジスタとFETのゲート間にトランジスタでNOT回路を挿入する。
(2)現在の光アイソレータのLEDと36番37番ピン間の配線をはずす。「36番ピンと37番ピンのNAND出力」をPとすると,「36番ピンとPとのNAND出力」と「37番ピンとPとのNAND出力」を光アイソレータのLEDにそれぞれつなぐ。
(ここは読み飛ばしてもよい)

図9.4に実用回路例を示す。FET4個使用時で7Aまで,FET最大16個使用時で28Aまで電流駆動が可能である。

HDRIVERPRACTICAL.GIF - 8,552BYTES
図9.4 H型ドライバを用いたDCモータ正逆転回路の実用例((本校)機械工学科松林先生による)

【10】ビット出力でモータを駆動する(3) ドライバICを導入した実用回路

東芝のモータドライバIC「TA8429H」(図10.1)は図8.3あるいは図9.4のようなH型ドライバ回路を1つのICにモジュール化(図10.2)したもので使いやすい。12ピン構成でピンの番号とその役割は表10.1のとおりである。また入力ピンへの動作割り当ては表10.2のとおりである。図10.3にCPUとの結線を示す。
このモジュールは,以下の特性をもっている。
(1)出力電流は平均3.0A,瞬時最大4.5A
(2)発熱に対し電流遮断安全機構
(3)過電流に対して電流遮断安全機構
(4)電源電圧範囲 Vcc:7〜27V(素子内の論理回路部への電源) Vs:0〜27V(モータ用の電源)

なおメーカから推奨された方法ではないが,電流を取りたい場合には図10.4のような並列動作が可能である。

P_TA8429.JPG - 5,944BYTESTA8429H.GIF - 1,924BYTES
図10.1 モータドライバIC「TA8429H」の外観
正面から見て左側が1番ピンである

TA8429H1.GIF - 11,023BYTES
図10.2 東芝のモータドライバIC「TA8429H」

表10.1 ピン番号一覧

PIN番号

役割

結線

1

IN1

CPUの36番ピン(ポート1第0ビット)

2

IN2

CPUの36番ピン(ポート1第1ビット)

3

使用していない

 

4

OUT1

DCモータへ

5

使用していない

 

6

GND

共通グランド

7

使用していない

 

8

OUT2

DCモータへ

9

使用していない

 

10

Vs

モータ駆動用の電源へ(12V)

11

Vcc

内部論理回路用電源(12VでOK,5Vではだめ)

12

standby

使用しないので電源へ(12V)


表10.2 モータドライバIC「TA8429H」での動作定義

P1.DR.BIT.B0(36番ピン) - IN1

P1.DR.BIT.B1(37番ピン) - IN2

DCモータ

0

0

まわらない

0

1

正転

1

0

逆転

1

1

ショートブレーキ

TA8429H2.GIF - 4,769BYTES
図10.3 モータドライバIC「TA8429H」でのモータ駆動

TA8429H3.GIF
図10.4 3個並列2chモータドライバユニット

【11】モータのPWM駆動

スイッチをON-OFFする動作を繰り返すことを考えよう。
始めはゆっくりと1秒間に1回ON-OFFする動作を繰り返す。するとモータも1秒間に1回動いたり止まったりする。次に1秒間に5回スイッチをON-OFFする動作を繰り返すことを考えよう。するとモータも1秒間に5回動いたり止まったりする。1秒間に5回だと不連続なのはわかるが,一見ゆっくり回っているようにも見える。しかも1回のON-OFFは0.2秒間だが,0.05秒がONで0.15秒がOFFという動作を行なうとゆっくり回り,0.15秒がONで0.05秒がOFFという動作を行なうとそれよりははやく回るだろうと考えられる。
もし1秒間に100回スイッチをON-OFFする動作を繰り返すことが出来たら,見た目には回転が不連続なのはわからない。しかし人間業ではこの作業はできない。

CPUならは,図10.3のようにすれば,高速なON-OFFの繰り返し動作が出来る。しかもプログラミングにより,1/100秒の一周期の範囲でONの時間とOFFの時間の比を変化させることが出来る。
このように,高速なON-OFF動作の繰り返しを行ない,一周期の範囲でONの時間とOFFの時間の比を変化させるモータ制御方式はPWM制御(Pulse Width Modulation:パルス幅変調)と呼ばれている。ONの時間とOFFの時間の比はデューティ比(ONの時間[s]/一周期の時間[s])と呼ばれる。

モータのPWM駆動サンプルプログラム(1)
正転のみ

図10.3のようにモータドライバの入力(2ビット)はCPU「H8/3048」のポート1第0ビット,第1ビットに接続されているものとする
操作
 ポート1の第0ビットと第1ビットに1を出力して出力に設定する
 ポート1の第1ビットに0をPWM出力する
 ポート1の第0ビットに0と1をPWM出力する

#include "3048f.h"

void msecwait(int msec)
/*msec間なにもしない時間稼ぎ関数*/
{
    int i,j;
    for (i=0;i<msec;i++) {
        for (j=0;j<1588;j++);    /*1588は実測によって求めた値*/
    }
}

main()
{
    int i;

    P1.DDR=3; /*P1の第0ビット第1ビットのみ出力に設定,他の6ビットは入力に設定*/
    P1.DR.BIT.B1=0; /*P1の第1ビットに0を出力*/
    while (1) {
        for (i=0;i<1000;i++) { /*ループ区間A*/
            P1.DR.BIT.B0=0; /*P1の第0ビットに0を出力*/
            msecwait(1);    /*1msecの間待つ*/
            P1.DR.BIT.B0=1; /*P1の第0ビットに1を出力*/
            msecwait(9);    /*9msecの間待つ*/
        }
        for (i=0;i<1000;i++) { /*ループ区間B*/
            P1.DR.BIT.B0=0; /*P1の第0ビットに0を出力*/
            msecwait(5);    /*5msecの間待つ*/
            P1.DR.BIT.B0=1; /*P1の第0ビットに1を出力*/
            msecwait(5);    /*5msecの間待つ*/
        }

    }
}

説明
ループ区間Aでは1msecのOFFの後,9msecのONが出力され,この作業が1000回行なわれるので,デューティ比9/10の駆動が10秒間行なわれる。
ループ区間Bでは5msecのOFFの後,5msecのONが出力され,この作業が1000回行なわれるので,デューティ比5/10の駆動が10秒間行なわれる。
2つのループ区間が無限ループで繰り返されるので結局,デューティ比9/10の駆動とデューティ比5/10の駆動が10秒ずつ交互に行なわれる。
ここでのPWM周波数は100Hzである。

モータのPWM駆動サンプルプログラム(2)
正逆転

図10.3のようにモータドライバの入力(2ビット)はCPU「H8/3048」のポート1第0ビット,第1ビットに接続されているものとする
操作
 ポート1の第0ビットと第1ビットに1を出力して出力に設定する
 ポート1の第1ビットに0をPWM出力する
 ポート1の第0ビットに0と1をPWM出力する

#include "3048f.h"

void msecwait(int msec)
/*msec間なにもしない時間稼ぎ関数*/
{
    int i,j;
    for (i=0;i<msec;i++) {
        for (j=0;j<1588;j++);    /*1588は実測によって求めた値*/
    }
}

main()
{
    int i;

    P1.DDR=3; /*P1の第0ビット第1ビットのみ出力に設定,他の6ビットは入力に設定*/
    while (1) {
        for (i=0;i<1000;i++) { /*ループ区間A*/
            P1.DR.BIT.B0=1; /*P1の第0ビットに1を出力*/
            P1.DR.BIT.B1=0; /*P1の第1ビットに0を出力*/
            msecwait(9);    /*9msecの間待つ*/
            P1.DR.BIT.B0=0; /*P1の第0ビットに0を出力*/
            P1.DR.BIT.B1=0; /*P1の第1ビットに0を出力*/
            msecwait(1);    /*1msecの間待つ*/
        }
        msecwait(1000);    /*1000msecの間待つ*/
        for (i=0;i<1000;i++) { /*ループ区間B*/
            P1.DR.BIT.B0=0; /*P1の第0ビットに0を出力*/
            P1.DR.BIT.B1=1; /*P1の第1ビットに1を出力*/
            msecwait(9);    /*9msecの間待つ*/
            P1.DR.BIT.B0=0; /*P1の第0ビットに0を出力*/
            P1.DR.BIT.B1=0; /*P1の第1ビットに0を出力*/
            msecwait(1);    /*1msecの間待つ*/
        }

        msecwait(1000);    /*1000msecの間待つ*/
    }
}


説明
ループ区間Aではデューティ比9/10の正転駆動が10秒間行なわれる。
ループ区間Bではデューティ比9/10の逆転駆動が10秒間行なわれる。
2つのループ区間の合間には,1秒間の休止がある。これはモータに急な反転操作を与えるとドライバに負荷がかかるためである。
ここでのPWM周波数は100Hzである。


おわりに
このページは学生が独習でマイコンでモータ等を駆動する方法を学べるように作成しました。
より豊かで正確な内容を目指しております。
Y.Yamane氏のご指摘に感謝いたします。