サインボード ソフト処理説明 |
タイトル ;******************************************************** ; ; The signboard control processing ; ; Author : Seiichi Inoue ;******************************************************** コメント(;)を使用してプログラムのタイトルを書きました。 LIST および INCLUDE疑似命令 list p=pic16f84a include p16f84a.inc
PIC16F84Aの標準ラベル定義をINCLUDEコマンドで組み込みます。 Microchip社で定義している定義ではTRISAおよびTRISBの定義がBank1アドレスになっているので、そのまま使用するとバンク切り替えの警告メッセージが出ます。私は定義ファイルを変更しました。 定義ファイルはMPLABをインストールしたときにインストールされます。ファイルのインストール先は通常以下の場所にあります。 c:\Program Files\Mplab\p16f84a.inc PCによってはドライブが異なりますので注意して下さい。 p16f84a.incの内容の変更部分は以下です。 ; P16F84A.INC Standard Header File, Version 2.00'(modify) TRISA EQU H'0085' -> H'0005' TRISB EQU H'0086' -> H'0006'
コンフィギュレーションワード
__config _hs_osc & _wdt_off & _pwrte_on & _cp_off
ただし、このコマンドのオペランドにラベルを使用する場合には事前にラベルの常数が定義されている必要があります。 PIC16F84Aの標準ラベルには一通りのラベルが定義されているので、INCLUDEの後にCONFIGを指定すれば問題はありません。 今回指定したラベルは標準ラベルでは以下のように定義されています。 _CP_OFF EQU H'3FFF' _PWRTE_ON EQU H'3FF7' _WDT_OFF EQU H'3FFB' _HS_OSC EQU H'3FFE'
__config h'3ff2'
ラベル定義 ;**************** Label Definition ******************** 処理で使用するラベル常数の定義を行います。PIC16F84Aの標準ラベルはINCLUDEで組み込まれるので、ここで定義する必要はありません。標準ラベルの名称はドキュメントに記載されている名称と異なる場合もありますので、注意が必要です。 ラベルの内容はメモリ・アドレスの定義と、データサイズなどのようにプログラムが動作する時の値を設定するものがあります。いずれも、EQU疑似命令を使用して定義します。今回のリストではアドレスのEQUとデータ設定のEQUとの分かりやすく分けました。 ;************************ ;* Time adjust * ;************************ ;This data decides a scroll speed. Basic rate is 26msec. tm_adj equ 0c ;Time adjust(26msec x 12) ;************************ ;* EEPROM data size * ;************************ ;If the data size is 30 bytes, then simply set d'30'. e_size equ d'32' ;EEPROM data size EEPROMデータの設定 ;*************** EEPROM Data Definition *************** org h'2100' de b'11111111' 今回のソフトでは表示するメッセージの内容をEEPROMに格納しています。 EEPROMのデータはメモリアドレス h'2100' として指定します。 アドレス h'2100' はEEPROMメモリでは h'00' になります。アドレスの指定にはORG疑似命令を使用します。 各ビットは'0'でLED点灯、'1'でLED消灯です。 プログラム開始 ;**************** Program Start *********************** 電源投入/リセット時はプログラムメモリアドレスは h'0000' からスタートします。また、割り込み処理のスタート番地は h'0004' です。 goto命令で各処理にジャンプするようにしています。 h'0000' は初期化処理、h'0004' はタイマー割込処理にジャンプします。 初期化処理 ;**************** Initial Process ********************* 電源投入後の初期化処理として以下の処理を行います。
LEDスクリーン表示処理 ;************** Screen Load Process ******************* 128個(8 x 16)のLEDにはメッセージを表示するので、スクリーンと称しています。 128個のLEDの点滅状態はRAMファイルメモリのに16バイトを確保して制御するようにしています。 PICでは同時には8個のLEDの点滅しか制御できないので、8個単位の点滅制御を高速で行い、人の目には128個のLEDを同時に制御しているように見せています。制御は一番右端の8個から始まり、1列ずつずらして制御して16回で1周期分です。 RAMファイルメモリの内容を変更すれば、LEDの点灯状況を変えることができます。 ポートBには8個のLEDの点滅状態を出力し、ポートAの4ビット(RA0-RA3)には列制御情報をバイナリで出力します。 列制御情報は外部のデコーダ(74HC154)により16本の制御情報に分けられ、16本の内の1つだけが選択されます。 高速でスキャンしていますので、ちらつきは無いのですが、1つのLEDの点灯時間は1/16になりますので、少し暗くなります。外部にラッチレジスタ回路を使用すれば点灯時間を長く出来るので、LEDを明るく点灯させることができます。しかし、16個のラッチレジスタが必要なので、今回の回路では省きました。
スクリーンデータの書き換え処理で最初にLEDを消すしてから次の列の処理を行っています。これはLEDを消さないで次の列に切り替えると次の列のLEDが前の列のデータで一瞬点灯してしまい、表示に「にじみ」が出てしまいます。デバッグでは気が付かなかったのですが、実際にサインボードを動作させて分かりました。 割り込み処理 ;************ Begin Interruption Process **************
次に割り込みの種類を判断します。今回はタイムアウト割り込みしか発生しないので、特に判定をする必要はないのですが、一応、タイムアウトビット(T0IF)のチェックを行っています。タイムアウトビットが立っていない割り込みが発生した場合には、異常割り込みとして初期化処理にジャンプさせています。初期化処理にジャンプしても異常が直るわけではありませんので、異常動作をしている場合には要因を追求する必要があります。 割り込み終了処理 ;************ END of Interruption Process **************
その際に待避したレジスタ類を元の値に設定します。レジスタを戻す順番はSTATUSレジスタを戻してからWレジスタを戻します。 STATUSレジスタを戻すときにWレジスタを使用するからです。Wレジスタを戻すのには工夫が必要です。単純にmovf命令を使用してWレジスタを設定するとSTATUSレジスタの内容が変わってしまいます。ですから、STATUSレジスタの内容が変わらない方法で戻します。具体的にはswapf命令を使います。swapf命令は上位4ビットと下位4ビットを入れ替える命令で、STATUSの変化はありません。また、処理結果を格納する場所を指定することができます。ですから、swapf命令を二回使用し、二回目の結果をWレジスタに格納すれば、STATUSレジスタの内容を変えることなくWレジスタを戻すことができます。 最後にretfie命令で元の処理に戻ります。この命令はスタックの内容により元のプログラムに戻ると同時にINTCONレジスタのGIEビットを'1'にして割り込み可能な状態にします。 タイムアウト割り込み処理 ;*********** Time-out interruption Process ************
タイムアウト割り込みが発生するとINTCONレジスタのT0IFビットが'1'になります。このビットはソフトウェアで消さないと次の割り込みが発生しません。また、カウント値も設定し直す必要があります。 TMR0はカウントアップタイマーで、値がFFhから00hになるとタイムアウトになります。ですから、256から希望するタイマー値を引いた値が設定値になります。255(FFh)を設定すると1カウントでタイムアウトします。 例えば、10MHzのクロックを使った場合、タイマーの1カウント時間は4サイクルですから、0.4μ秒です。プリスケーラを256に設定した場合、TMR0に入力されるパルスの間隔は256 x 0.4 = 102.4μ秒になります。 TMR0を約20ミリ秒でタイムアウトさせるのには20/0.1024 = 約195カウントです。195カウント後にタイムアウトさせるためには256-195 = 61(3Dh)カウントをTMR0に設定します。 今回の場合には最大時間を設定したいので、TMR0の設定値は 0 にしています。 スクリーンスクロール処理 ;************ Screen data shift Process ***************
処理内容は1列分左に移動し、一番右側の列に新しいメッセージの1列を表示することです。 まず、左の15列分のメッセージを1列移動します。この処理でも間接アドレスを使用しています。FSRレジスタにアドレスを設定するとINDFレジスタに該当するメモリの内容が格納されます。また、その状態でINDFレジスタの内容を変更すれば、RAMメモリの内容を変更することができます。 EEPROMデータ読み出し処理 ;************** New data write Process ****************
読み出したデータをLED表示の一番右側の列に設定します。 以上で、LEDの表示が左に1列分移動しました。 EEPROMに書かれたデータを最後尾まで読み出すと、また、先頭に戻って読み出しを行います。この動作を繰り返し行い、LEDにはEEPROMのデータが流れるように表示されます。 コーディングの終了 ;******************************************************** ; END of signboard control processing ;******************************************************** end
|