PIC16Fシリーズの入門用として有名な16F84Aには、83byteのファイルレジスタが用意されています。
ファイルレジスタというのは、パソコンで言うところのRAMと、メモリマップされたI/Oレジスタに相当するものです。
名前は、ファイル”レジスタ”ですが、IntelのCPUで使用されている演算用レジスタ(EAX,EBX等の名前で呼ばれています)とは意味が違うので注意してください。(これに相当する,汎用レジスタはWレジスタというもので別途用意されています)
ファイルレジスタのメモリマップ
利用可能な144byteにはそれぞれ固有の(ユニークな)番地が割り振られています。具体的な番地はデータシートで明記されており、以下の通りとなっています。
上記表のうち、グレーになっている番地のレジスタは使用できません。
この為、実際に以下の番地にアクセスできるという事が分かります。
0x00~0x06 0x08~0x4f 0x80~0x86 0x88~0xCF |
レジスタの各番地は8bit幅で、0x00~0xFFの256通りの値をセットできます。
SFR(Special Function Register)
その内、一部の番地のレジスタには特殊な意味があり、SFRと呼ばれています。SFRというのはSpecial Function Registerの略です。
SFRをアクセスする事で、CPUの動作設定を変更させたり、マイコンから出ているI/Oピンの状態を読み書きする事が可能です。
以下にSFRの一覧を示します。
Addr 名称 内容 ---- ---------- -------------------------------------- 0x00 INDF 間接参照レジスタ 0x01 TMR0 タイマ 0x02 PCL プログラムカウンタ(下位8bit) 0x03 STATUS ステータスレジスタ 0x04 FSR バンク切り替え用レジスタ 0x05 PORTA ポートAの値 0x06 PORTB ポートBの値 0x08 EEDATA EEPROMの値 0x09 EEADR EEPROMのRead/Writeアドレス 0x0A PCLATH プログラムカウンタ(上位5bit) 0x0B INTCON 割り込みフラグ 0x81 OPTION_REG オプションレジスタ(プリスケーラetc) 0x85 TRISA ポートA入出力モード 0x86 TRISB ポートB入出力モード 0x88 EECON1 EEPROM操作用 0x89 EECON2 EEPROM操作用 |
SFR以外の0x0C~0x4F(計67byte)はプログラマが自由に使用可能な汎用領域で、内部的にはSRAMとして実装されています。
0x8C~0xCF番地も同様にアクセス出来ますが、この領域はBank0にマップされています。これは、例えば0x8C番地の値を書き換えると0x0Cも書き換わるという意味ですが、バンクの概念については次節の”バンク切り替え処理”を参照してください。
ファイルレジスタのバンク切り替え処理
先ほどの表を見ると、ファイルレジスタは大きく0x00~0x7Fと0x80~0xFFの2つに分けられており、表の上を見るとそれぞれBank0,Bank1という名前が付いていることが分かります。PICでは、プログラムの実行中、プログラムからはBank0かBank1のどちらかしか読み書きする事が出来ないような制限が有ります(この制限はプログラムの機械語上、レジスタ指定のビットが7bitしかない事から来ています)。
どっちのバンクにアクセスしたいかは、後述するSTATUSレジスタのRP0,RP1ビットを操作することで切り替え可能です。
上記のレジスタの内、PCL,STATUS,FSR,PCLATH,INTCONレジスタはよく使用されるので,以下のアドレスからもアクセス可能です。
0x82 PCL 0x83 STATUS 0x84 FSR 0x8A PCLATH 0x8B INTCO |
要は、バンク切り替えをしなくても常に参照できるという事です。
ビット毎に意味があるレジスタの内容一覧
SFRの内、STATUS/OPTION/INTCONレジスタは、ビット毎に意味を持たせています。各レジスタが、ビット毎にどんな意味を持たせているかは以下の通りです。
STATUSレジスタ (0x03, 0x83)
STATUSレジスタは、CPUによる命令の実行結果や、CPUの動作状態を通知します。
ビット 名称 意味 7 未実装(読むと常に"0") 5,6 #RP0 バンク指定(負論理) #RP1 01 = Bank 1 (80h - FFh) 00 = Bank 0 (00h - 7Fh) ※読み込み専用です。 4 #TO タイムアウトビット(負論理) 1 = 起動時か、CLRWDT/SLEEP命令実行時 0 = ウォッチドッグタイマによるタイムアウトが発生 ※読み込み専用です。 3 PD パワーダウンビット 1 = 起動後か、CLRWDT命令実行時 0 = SLEEP命令実行時 2 Z ゼロフラグ 1 = 直前の数値演算・論理演算の結果が0だった 0 = 直前の数値演算・論理演算の結果が0以外だった 1 DC キャリー発生フラグ (ADDWF, ADDLW,SUBLW,SUBWF命令) 1 = bit3からのキャリーが発生した 0 = bit3からのキャリーが発生しなかった 0 C キャリー発生フラグ 1 = 最上位ビットでキャリーが発生した 0 = 最上位ビットでキャリーが発生しなかった |
OPTIONレジスタ (0x81)
OPTIONレジスタはCPUの動作を指定します
ビット 名称 意味 7 #RBPU PORTBの内部プルアップ指定(負論理) 1 = PORTBの内部プルアップを無効にする 0 = PORTBの内部プルアップを有効にする 6 INTEDG 割り込みのエッジ指定 1 = RB0/INTピンの立上りエッジで割り込み発生 0 = RB0/INTピンの立下りエッジで割り込み発生 5 T0CS TMR0タイマのクロック指定 1 = RA4/T0CKIピンからタイマクロック供給 0 = CPUシステムクロック(CLKOUT)からタイマクロック供給 4 T0SE TMR0 Source Edge Select bit 1 = RA4/T0CKIピンの立下りでタイマ加算 0 = RA4/T0CKIピンの立上りでタイマ加算 3 PSA タイマ/ウォッチドッグのプリスケーラ割当て指定 1 = Prescalerをウォッチドッグ(WDT)に割当てる 0 = Prescalerをタイマモジュール(TMR0)に割当てる 2-0 PS2 プリスケーラ値の指定 PS1 値 TMR0使用時 WDT使用時 PS0 000 1:2 1:1 001 1:4 1:2 010 1:8 1:4 011 1:16 1:8 100 1:32 1:16 101 1:64 1:32 110 1:128 1:64 111 1:256 1:128 |
INTCONレジスタ (0x0B, 0x8B)
INTCONレジスタは割り込みに関する処理を制御します
ビット 名称 意味 7 GIE: Global Interrupt Enableフラグ 1 = 割込み制御を有効にします 0 = 全ての割込みを無効にします 6 EEIE EEPROM書き込み完了の割込み通知 1 = EEPROM書き込み完了時に割込みを発生させます 0 = EEPROM書き込み完了時に割込みを発生させません 5 T0IE TMR0オーバーフロー割込み通知 1 = TMR0オーバーフロー時に割込みを発生させます 0 = TMR0オーバーフロー時に割込みを発生させません 4 INTE RB0/INTピンによる外部割込み通知 1 = RB0/INTピンによる外部割込みを発生させます 0 = RB0/INTピンによる外部割込みを発生させません 3 RBIE PORTBの状態変化による割込み通知(RB7~RB4) 1 = PORTBの状態変化による割込みを発生させます 0 = PORTBの状態変化による割込みを発生させません 2 T0IF TMR0オーバーフロー割込みフラグ 1 = TMR0割込みが発生した 0 = TMR0割込みが発生しない 1 INTF RB0/INTピンによる外部割込みフラグ 1 = RB0/INTピンによる外部割込みが発生した 0 = RB0/INTピンによる外部割込みが発生しない 0 RBIF PORTBの状態変化による割込みフラグ 1 = PORTBの状態変化による割込みが発生した 0 = PORTBの状態変化による割込みが発生しない |
T0IF, INTF, RBIFフラグは、プログラマが割り込み処理内で0にクリアする必要があります。
RBIFはRB7~RB4の内、どのピンの状態が変わったかまでは通知してくれません。
割り込みハンドラ内で自分で判断する必要が有ります。
関連記事
コメントを残す