目次PIC回路集LEDフラッシャー


LEDフラッシャー ソフト処理説明



タイトル
;********************************************************
;
;            The LED flash control processing
;
;                                 Author : Seiichi Inoue
;********************************************************
    コメント(;)を使用してプログラムのタイトルを書きました。


LISTコマンド
        list    p=pic16f84a
    PICの種類を指定します。


INCLUDEコマンド
        include   p16f84a.inc
    PIC16F84Aの標準ラベル定義をINCLUDEコマンドで組み込みます。
    定義ファイルはMPLABをインストールしたときにインストールされます。ファイルのインストール先は通常以下の場所にあります。
    c:\Program Files\Mplab\p16f84a.inc
    PCによってはドライブが異なりますので注意して下さい。


__CONFIGコマンド
        __config _hs_osc & _wdt_off & _pwrte_on & _cp_off


ERRORLEVELコマンド
        errorlevel      -302    ;Suppress bank warning
    Microchip社で定義している定義ではTRISAおよびTRISBの定義がBank1アドレスになっているので、そのまま使用するとバンク切り替えの警告メッセージが出ます。この疑似命令で警告メッセージを出さないようにしています。


ラベル定義
;****************  Label Definition  ********************
    プログラムで使用するラベルの定義をします。リテラル値をラベルとして定義します。ラベルの定義はデータを参照するステップより前に書かれていれば問題はありません。見やすさのためにまとめて書くようにしています。プログラム自体に付けているラベルは定義する必要はありません。



LED点灯パターンデータ定義
;*************  Pattern Data Definition  ****************
;                 '1':OFF   '0':ON
    LED点灯制御のデータは8ビットなので、リテラルデータを使います。そのために、各データパターンにラベルを付け、EQUで設定値を定義するようにしました。今回のようなLED点滅制御だけであれば、このような方法で良いと思います。


プログラム開始
;****************  Program Start  ***********************
    PICの電源投入するとプログラムメモリの0番地から命令が実行されます。また、割り込み処理がある場合には4番地から処理が開始されます。
    今回の回路では割り込み機能は使用していないので、4番地からプログラムが走り始めることはありません。ですが、いずれ割り込みを使うことがあるかもしれないので、4番地から走り始めても問題がないようにしました。
    ですから、実質的なプログラムは5番地からです。


初期化処理
;****************  Initial Process  *********************
    まず、ポートの入出力の設定を行っています。PIC16F84Aは電源投入直後は全て入力モードになります。ですから、本当は出力ポートの設定のみを行えば良いのですが、今回は入力ポートの設定も意識的に行っています。
    ポートの設定の後、LEDの消灯処理を行っています。これも特に行わなくても良いのかも知れません。


キースキャン
;****************  Key Scan Process  ********************
    RA0からRA4に接続したスイッチの状態を取り込みます。スイッチが押されるとLレベル(0)になり、スイッチを離すとHレベル(1)になります。スイッチが押されていると認識すると押されたスイッチの種類により、該当するLED点滅パターン処理サブルーチンを実行します。
    各々のスイッチを順番にチェックするので、全てのスイッチを押すと、順番に各パターンのLED点滅制御が実行されます。
    スイッチが押されていない場合には、このキースキャン処理が繰り返し実行されます。


LED点滅制御サブルーチン
;***********  Pattern 0 Output Subroutine ***************
    5つのパターン毎にサブルーチンを作りました。処理としては単純に点滅データを設定し、PORTBに出力し、タイマーサブルーチンを実行することの繰り返しです。PORTB出力とタイマーサブルーチンは更にサブルーチン化してプログラムメモリの使用量を減らすことが出来ます。ただし、その場合、命令の実行ステップ数はCall/Return分増えてしまいます。
    今回の場合、プログラムメモリに余裕はあるので、分かりやすさの点でサブルーチン化はしませんでした。
    サブルーチン化する場合、スタックの数に注意する必要があります。
    今回の場合、スタックは以下のように使われます。(タイマーとして1秒タイマーを使用した場合)
    スタック段数起動条件戻り番地
    キースキャンからLED点滅処理を起動キースキャン
    LED点滅処理から1秒タイマーを起動LED点滅処理
    1秒タイマーから500ミリ秒タイマーを起動1秒タイマー
    500ミリ秒タイマーから100ミリ秒タイマーを起動500ミリ秒タイマー
    100ミリ秒タイマーから1ミリ秒タイマーを起動100ミリ秒タイマー

    スタックは最大8段までですから、まだ、余裕はあります。


タイマーサブルーチン
;********************************************************
;          Timer  Subroutine for 10MHz clock
;********************************************************
    信号を一定時間継続させたり、スキャンする時間間隔を決めたりするときには、命令を実行するタイミングを遅らせる必要があります。ある命令を実行して次の命令をするまでの時間を作る方法としていくつかの方法があります。通常は処理をループさせて、時間を稼ぐ方法と、ハードのタイマー機能を使う方法があります。今回は処理をループさせる方法で時間を稼いでいます。
    2つの方法を比べると以下のような得失があります。
    メリットデメリット
    ソフトでのループ・処理が簡単 ・時間カウント中は他の処理はできない
    ・使用するプログラムメモリが多い
    ・タイマー値を決めるのが大変(実行サイクルを計算)
    ・誤差が大きい
    ハードタイマー ・時間カウント中でも他のソフト処理が可能
    ・比較的時間が正確
    ・割り込み処理を使うので処理が面倒

    本来はハードタイマーを使った方が良いと思いますが、今回の処理ではソフトウェアを理解すると言う名目で全てソフトで行いました。
    タイマー処理としては、まず、1ミリ秒のタイマーを作ります。今回のクロックには10MHzを使っているので、周期は0.1マイクロ秒です。命令の実行サイクルはその4倍なので、1命令実行サイクルの時間は0.4マイクロ秒になります。ですから、1ミリ秒の時間に実行させるサイクル数は2,500サイクルになります。今回の処理では2,501サイクルになりました。少しの誤差がありますが、実質的には問題はありません。
    100ミリ秒のタイマーは1ミリ秒のサブルーチンを100回繰り返します。500ミリ秒は100ミリ秒のサブルーチンを5回、1秒は500ミリ秒を2回繰り返すというようにしています。


コンフィギュレーションワード
    今回のソフトウェアでのコンフィギュレーションワードは '3FF2' にしています。設定内容は以下のようになります。
    項目設定内容フィールド名称ビット
    コードプロテクションOFFCP1111111111
    パワーアップタイマーONPWRTE(inv)0
    ウォッチドッグタイマーOFFWDTE0
    クロック発振器指定HSFOSC1およびFOSC010