2016-05-18 11:49 | カテゴリ:PIC応用回路
先日、アップさせていただきましたPICによるLEDの点滅制御のプログラムですが、シンプルすぎて、一度起動したらそのまま走り続ける仕様でしたので、ちょっと機能を追加してみました。

追加仕様としては、

1)ポートCのRC0にSWを接続する事を前提として、そのSWがONかOFFかによって、特定のLEDの点滅動作を停止したり動作させたり出来るようにする。
2)PWM(PIC16F876Aなどには標準で装備されています)信号の制御も、周期とデューティー比を簡単にパラメータ設定できる。
3)PWMのデューティー比を自動で変化させて、LEDの輝度変化を可能とする。

を実現したく、検討してみました。

まず、1)ですが、ポートC0とポートC1にスイッチを取り付け、常時抵抗で+Vにプルアップしておき、スイッチをONとするときに、GNDに落とすように回路を組みます。
プログラムでは、そのスイッチの状態を読み込んで、ONなら、動作指定配列の、指定された出力の設定を、13(定期点滅)か15(動作しない)に書き換えます。

//---------------------------------------------
//スイッチの状態をチェックして配列データを変更する
//----------------------------------------------
// 下記のparameter[n][m]のnに制御したい配列のポート番号を指示する
// 下記の例では、sw0でポート番号3をsw1ではポート番号4を示しています
// swは、負論理で、ゼロならONとみなしています
// この機能を使用しない場合は、以下のプログラムをコメントアウトします
// 各行の先頭に//を挿入してください
//----------------------------------------------------------------

if (sw0 == 0)parameter[3][0] = 13; //sw0が0ならRA3の設定を13(定期点滅)に設定

else {
port_off(); //点灯中の場合に備え指定ビットを消灯
parameter[3][0] = 15; //そうでなければ、設定解除
}
if (sw1 == 0)
parameter[4][0] = 13; //sw1が0ならRA3の設定を13(定期点滅)に設定
else {
port_off(); //点灯中の場合に備え指定ビットを消灯
parameter[4][0] = 15; //そうでなければ、設定解除
}

上の例では、配列の番号3と4のLEDを制御するように記述しています。
制御したいポート番号のnを0から14の範囲で指定します。

プログラム追加部分はここです。

sw_set.jpg

続いて、2)です。
まず、PICのPWMの設定に関しては、以下の様になっています。
いずれも動作周波数20MHzを前提として

(PWMの周期の決定)

周期=(255+1)x 4 x 0.05マイクロ秒 x 10(のマイナス6乗)x 16
   PR2レジスタ値  <- PICの動作クロックの4倍の逆数->  (タイマー2のプリスケーラ)
  =0.8192ミリ秒から0.0032ミリ秒(1220Hxから312KHzの範囲)
となり、
LEDの点滅制御もしくは、模型用小型モーターの制御と言う前提で考えれば、プリスケーラは16で良さそうです。


(PWMのデューティー比の決定)

デューティー比=1023 x 0.05 x 10(のマイナス6乗) x 16
       =CCPR1Lレジスタ値(CCP1XとCCP1Yは使用しません) x 0.05 x 10(のマイナス6乗) x プリスケーラ
       =0から0.819ミリ秒

となり、この範囲で、周期とdヒューティー比を変更できますが、注意が必要です。
それは、デューティー比は、0-100の%で指定するのではなく、ONとなっている時間で指定するため、途中でデューティー比が100%を超えた数値になっても無視され、あるいは、レジスタがオーバーフローして、いきなり小さな値に戻ったりして、使い勝手が良くありません。
使用目的を、模型のLEDや小型モーターの制御と仮定して、PWMの周期は、遅めの1220Hzで固定し、デューティー比を0から100%の数値で指定する使用としました。

整理しますと、今回のPWMは、
周期は、約819マイクロ秒(1220Hz)で固定とし、デューティー比は、0-100%の値で制御する、と言う仕様に決めました。
(模型の小型モーターのPWM制御は、自分の経験上、周波数が低めの方が、起動時の最初の動き出しに力が入って、回転しやすい印象があります)


[x, y, z]の指定パラメータは、

自動モード
x=14:PWMの制御を指定
y=0 :PWMのデューティー比を0から100%の間で、自動的に増減させる。
z=n :デューティー比を増減させる速度を指定。1%あたりnx5msecで増減。例:2とすると、2x5msecx100=1000msec、つまり1秒で消灯から最大輝度へ、また次の1秒で、消灯へ。
     ただし、最大値は255。

PWM00.jpg

PWM02.jpg

手動モード
x=14:同上
y=1-255:周期を1から255までの間で指定可能。現在は、255固定(約0.819ミリ秒=約1220Hz)で使用する。デューティー比0-100%制御のため固定とする。
        変更禁止
z=n ;デューティー比を指定。0-100(%)として指定可能。プログラム内で、上記の周期に合わせてデューティー0-100%で制御。

PWM01.jpg

また、メインルーチンの比較判定部分に、PWM処理へ分岐する部分を追加します。

proces.jpg

肝心のPWM処理をする関数です

まず、PWMを使用できるように各種のパラメータを設定します。

PWM_setuup.jpg


そして、配列の設定データに従って、PWMの周期とデューティー比を設定する部分です。

pwm_proces.jpg

以上、プログラム全体をテキストファイルでここにアップしました。
ご自身の、MPLABXのCプログラムのメインプログラムを新規作成し、そこにコピペして、コンパイルしてください。

メインプログラムです
-----------------------------
PWM_Program.txt
-----------------------------

実際の動作状況です。

まずは、指定した周期とデューティー比でLEDを単純に点灯した場合。
ここでは、周期は255、つまり、約1200Hzくらいで、デューティー比は、3%くらいで赤色LEDを点灯させました。

LED1.jpg

次に自動でゆっくり輝度変化して点滅する自動モードです。
このLEDは、かなり古いもので、発光輝度が低いので、明暗が分かりやすいですが、最近の高輝度タイプのLEDだと、すぐに明るくなって、飽和してしまうかと想像します。
つまり、指定したデューティ%と明るさが比例しません。



以上、よろしければご参考にしてください。


【ジャンル】:趣味・実用 【テーマ】:模型・プラモデル
コメント(5)

管理者のみに表示する