環境設定
リストの行番号008-011で各種の環境設定をしています。
008 | list | 使用するPICの名称を定義しています。 |
009 | include | 各種の標準ラベルが定義されているファイル(p16f84a.inc)の組み込みを指示しています。 |
010 | __config | コンフィギュレーションワードの指定をしています。 |
| _hs_osc | | 発振器の種類 | :HS |
_wdt_off | ウォッチドッグタイマー | :使用しない |
_pwrte_on | パワーアップタイマー | :使用する |
_cp_off | コードプロテクタ | :使用しない |
|
上記の指定によるコンフィギュレーションワードの値はH'3FF2'です。 |
|
|
|
011 | errorlevel |
バンク切り替え警告メッセージ[302]の表示が出ないようにしています。
PIC16F84AのRAMファイルレジスタはバンクという方式を使用しています。例えばTMR0もOPTION_REGも01番地にあり、TMRはバンク0、OPTION_REGはバンク1です。INCLUDEで読み込む定義ファイルではOPTION_REGのアドレスをH'0081'と定義していて、バンク情報も書かれています。しかし、実際の処理ではSTATUSレジスタのRP0ビットによりバンクを指定する必要があります。MPLABではバンク切り替えを間違えないようにバンク1のレジスタの処理があると警告メッセージ"Message[302]"が表示されます。
Register in operand not in bank 0. Ensure that bank bits are correct.
「オペランドで指定されたレジスタはバンク0ではありません。バンク指定ビットが正しいか確認しなさい。」という内容です。バンク指定を正常に行っていてもこのメッセージは表示されます。このメッセージを出さないようにするためには定義ファイルの指定を変えてしまう方法があります。すなわち、OPTION_REGのアドレスをH'0001'と変えることにより、メッセージは表示されなくなります。または、今回使用しているようにERRORLEVEL命令を使って302のメッセージの表示を止める方法があります。 |
ラベル定義
;**************** Label Definition ********************
RAMレジスタファイルに領域を確保する部分にはCBLOCKおよびENDCを使用しています。これらのコマンドに挟まれたラベルはCBLOCKで指定しているアドレスから順番に領域が自動設定されます。今回の場合、以下のように指定したのと同じです。
tx_status equ h'000c'
tx_substatus equ h'000d'
pattern equ h'000e'
ptn1およびptn2は制御コードデータを指定するラベルです。ここで指定する値を変えれば、送信する制御コードを変えることができます。その場合には受信機側も変える必要があります。
ra4はポートAの4番ポートの位置を指定するラベルです。ra4を使わなくても使用する命令の部分で4を直に指定することもできます。
プログラム開始
;**************** Program Start ***********************
プログラムメモリアドレス0番地は電源投入時またはリセットが発生した場合のプログラム実行開始アドレスです。また、4番地はタイマー割り込みなどの割り込み処理が発生した場合の開始アドレスです。これらのアドレスはPIC16Fシリーズではハードウェアで決まっていて変えることはできません。
初期化処理
;**************** Initial Process *********************
ポート初期化
まず、ポートの初期化を行います。RA0およびRA1を入力モード、RA4を含むその他のRAポートは出力モードに設定しています。
タイマー設定
今回の回路では送信するデータを10ミリ秒間隔で制御しています。10ミリ秒の時間はタイマー0を使用して作ります。タイマー0に内部クロックおよびプリスケーラを使用するためにOPTION_REGのTOCSおよびPSAを"0"にします。プリスケーラ値は"101"で1:64にしています。PICの発振器には4MHzを使用しているのでクロックは1μ秒になり、プリスケーラと組み合わせてTMR0のカウントアップクロックは64μ秒です。TMR0はカウントアップタイマーでカウント値(TMR0)が255(H'FF')から0になるとタイマー割り込みが発生します。ですから、10ミリ秒のタイマーを設定するためには256-(10000/64)=100になり、タイマー設定処理でTMR0に100を設定すれば良いことになります。プルスケーラ値は必ずしも1:64でなくてもかまいません。1:128にすれば128μ秒毎にタイマー0がカウントアップされます。ですから、TMR0の設定値は256-(10000/128)=178になります。1:256にすれば256-(10000/256)=217です。プリスケーラ値が小さい方がTMR0でタイマー値を細かく設定できます。でも、1:32の場合は10000/32=312.5で、256以上の値になるので使えません。
レジスタ値の初期化
PICの電源を入れた場合には各種のレジスタは初期化されていますが、念のためにレジスタの初期化をしています。
送信パターンの確認
RA0またはRA1の状態をチェックして送信パターンを確認します。SW1が押されるとRA0がHレベルになり、SW2が押されるとRA1がHレベルになります。押されたスイッチの状態により、送信パターンをPATTERNレジスタに設定します。SW1とSW2が同時に押された場合にはSW1が押されたと判断します。
タイマー割り込み待ち
以上の処理を行った後はタイマーの割り込みを待つだけです。GOTO命令で$(自アドレス)を指定し、同じ場所の処理を繰り返して割り込みを待ちます。
タイマー割り込み処理
;********* Begin Timer Interruption Process ***********
今回の処理では割り込みはタイマータイムアウトしかありません。ですから、割り込みは全てタイマー割り込みと見なしています。他の割り込み(RBポート変化割り込みなど)と併用する場合には、割り込み要因の判定処理が必要です。
最初にタイマー割り込みフラッグを消します。これを消さないと割り込み終了命令(RETFIE)を実行した直後に規定時間が経っていないのに再びタイマー割り込みが発生してしまいます。
プリアンブル信号送出処理
;************ Preamble data send Process **************
送信ステータス(TX_STATUS)が"0"の場合はプリアンブル信号の送出処理を行います。ONとOFFを交互に3回送信し、送信終了時にはONを2回連続させ、最後にOFFとしてプリアンブル信号の送出を終わり、送信ステータスを"1"にします。
制御コード信号送出処理
;************ Control data send Process ***************
送信ステータスが"1"の場合、制御コードの送出処理が行われます。制御コードの各ビットの前にはON信号、後ろにはOFF信号を送ります。送出ビットの送出状態はサブステータス(TX_SUBSTATUS)で管理しています。処理を工夫すればもっと少ない処理ステップで実現できると思いますが、今回の処理では各信号毎の処理を順番に作っています。プログラムメモリの使用量は増えますが、実行時間は少なくなります。判断処理などがあまり無いからです。今回の場合にはプログラムの規模は小さいので、メモリ量を気にする必要もありません。また、この方のが処理は分かり易く、バグ(ソフトウェアの誤り)を作り込む可能性も少ないです。制御コードの送出が終了すると送信ステータスを"2"にします。
終了コード信号送出処理
;************** End data send Process *****************
送信ステータスが"2"の場合、終了コードの送出処理が行われます。終了コードはON状態を3回続け、最後にOFF状態にします。
終了コードを送信し終わった後、送信ステータスを"0"にすることにより、再びプリアンブルの送信が行われます。
タイマー割り込み終了処理
;*********** Substatus Increment Process **************
;******** End of Timer Interruption Process ***********
10ミリ秒毎にタイマー割り込みが行われ、送信ステータスおよび送信サブステータスの内容により処理が行われます。
タイマー割り込み処理の終了時にはタイマー値(TMR0)に10ミリ秒を設定し、次回のタイマー割り込み条件を設定します。ステータスの状態によってはサブステータスの加算を行う場合があります。割り込み処理はRETFIE命令を使って終了します。この命令によりINTCONレジスタのGIEビットが"1"になり割り込みが可能になります。
|