標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第414回]

●間接アドレッシング

前回は、PIC18F4550のメモリバンク0に置いたユーザー定義レジスタと、バンク15にあるシステムレジスタへのアクセスについては、PIC16Fでのプログラムと同じ感覚で行えば良い、ということを説明しました。
バンク0以外のメモリバンクに置いたレジスタに対しても、BSRレジスタにそのバンクを指定する値をセットすれば、バンク0に置いたレジスタと同じようにアクセスすることはできます。
ただバンク0以外については、そういうプログラムは実際には書くことが少ないのではないか、と思います。

前回説明しましたように、MPLABに附属のPICアセンブラを使えば、メモリバンク0のアドレス000〜05Fの範囲に割り付けたユーザー定義レジスタだけではなくて、060〜0FFに割り付けたユーザー定義レジスタに対しても、特別に意識することなく普通にプログラムを書いて、普通にアクセスすることができます。
000〜05F以外のGPR(general purpose RAM)に割り付けたレジスタをアクセスする命令を’a’パラメータを省略して書くと、アセンブラが’1’を付加する形で機械語に翻訳してくれるので、BSR=0ならば、060〜0FFに置いたレジスタもそのままアクセスできるからです(リセット後にはBSRの値が0になっています)。
前回は説明するのを忘れましたが、BSRというレジスタ名はBank Select Registerのイニシャルからきています。

000〜05Fの範囲だけで8ビットのレジスタ変数を96個も定義することができます。
これに加えて060〜0FFの範囲にも普通にアクセスできるユーザーレジスタ変数を定義することができるのですから、両方をあわせると、8ビットのユーザーレジスタ変数を256個も定義することができます。

普通のプログラムで変数を256個も使うなどということはないのではないか、と思います。
すると、さらにそれを超えて、そのほかのメモリバンクにもメモリバンク0と同じようなユーザーレジスタを定義して使う、などということは実際にはちょっと考えられないのではないでしょうか。

そうすると、バンク1〜バンク7は、実際にはどのような使われ方をするのでしょうか。
おそらく、主たる用途はメモリバッファとしての使われ方である、と考えられます。
今回はPIC18F4550のUSB機能を使うことがそもそもの目的なのですが、USBに限らず、いろいろな目的で、ある程度のまとまったデータを処理するようなプログラムをPICで書くような場合には、このバンク1〜バンク7のメモリバンクをデータバッファとして使うことになります。
たとえば232C通信のための、送受信バッファであるとか、ADコンバータの測定データの蓄積バッファというような用途がその使われ方の一例です。

そのようなプログラムでは、メモリバッファの先頭から順に、data1、data2、data3…というように名前をつけておいて、そこに順にデータを格納していく、などというプログラムは、書きません(500バイトのデータバッファに500個の名前をつけてひとつひとつ順番にアクセスする、などというプログラムはとても考えられません)。

そういうときのために、間接アドレッシングが利用されます。
PICではFSRレジスタとINDFレジスタのペアが使われます。
FSRはFile Select Register、INDFはIndirect Fileから名づけられています。
PICではメモリ上に置かれたレジスタを’f’(File)と形容しているようで、そこからこういう名前がつけられているようです。

FSRレジスタとINDFレジスタを使ったメモリの間接アドレッシングは、PIC18F4550だけではなくて、16F84や16F628、16F88でも使うことができます。
たとえばPIC16F88Datasheetでは次のように説明されています。

[出典]Microchip社PIC16F88Data Sheet

こんな難しいものはわからん。
と思われるかも知れませんが、それはちょっとMicrochip社の説明が悪いのです。
こんなものは難しくもなんともないのです。
8080やZ80でごく普通にやっていることと全く同じなのです。
せっかく8080の回路を作ってきたのですから、8080の命令で説明してみます。

8080では普通にメモリをアクセスするにはどうするでしょうか。
たとえばアセンブラで、LDA DATA1などと書くと、これが直接アドレッシングで、機械語では、3Axxxxになります。
メモリアドレスDATA1(xxxx)の値をAレジスタに入れる命令です。
その逆は、STA DATA1です。機械語は32xxxxです。
Aレジスタの値をメモリアドレスDATA1(xxxx)に入れる命令です。

メモリとレジスタの間のデータの転送にはもうひとつの方法がありました。
メモリをMという記号であらわした命令です。
MOV A,Mは機械語では7Eになります。
メモリの値をAレジスタに入れる命令です。
その逆はMOV M,Aです。機械語は77です。
Aレジスタの値をメモリに入れる命令です。
8080でこのように使われるMはHLレジスタで示されたメモリアドレスのことでした。
これが間接アドレッシングです。

HLレジスタにアクセスしたいメモリアドレスを入れておいて、メモリをアクセスしながらHLレジスタをインクリメントまたはデクリメントしながら繰り返すことで、データバッファを簡単にアクセスすることが可能になります。

PICのFSRとINDFを使ったアクセスも、8080のHLレジスタを使ったメモリアクセスと全く同じなのです。
8080のHLレジスタがPICのFSRレジスタに相当し、また8080アセンブラ表記のMがPICのINDFに相当しているのです。

PIC16Fでは、FSRとINDFは1組だけですが、PIC18F4550には、3組もあります。
FSR0H、FSR0LとINDF0
FSR1H、FSR1LとINDF1
FSR2H、FSR2L、INDF2
という3組です。

前にも説明しましたように、PICのレジスタは8ビットです。また命令のオペランド部も8ビットの範囲のメモリしかアクセスすることができません。
しかし、データメモリエリアは000〜7FFの範囲なので、8ビットではこの全メモリ範囲を直接アクセスすることはできません。
そこでダイレクトメモリアクセスでは、BSRレジスタを使ってバンク切り替えで、000〜7FFの範囲のメモリをアクセスするようにしています。
一方でFSRとINDFを使った間接アドレッシングでは、FSRをHレジスタとLレジスタの2つのレジスタにすることで(おお、8080のHLレジスタと全く同じです)、000〜7FFの全データメモリ範囲をアクセスできるようになっています。
すなわちFSR0H(FSR1H、FSR2Hも同じ)には、メモリアドレスの上位4ビット0〜7を与え、FSR0L(FSR1L、FSR2Lも同じ)に下位8ビット00〜FFを与えることによって、データメモリの全範囲をアクセスできるのです。
この場合には、BSRがどのバンクを指定していても、それにはとらわれることなくアクセスすることができます。

PIC18F4550のData Sheetで、FSRとINDFを説明している部分を下に示します。


[出典]Microchip社PIC18F4550Data Sheet

FSRnH、FSRnLにアドレス値を入れるには、普通にレジスタに値を入れるときと同じように、
movlw 3
movwf FSR0H
movlw 45
movwf FSR0L
のようにすることができます。

またFSRnH、FSRnLの値は、これも普通のレジスタのように、incf、decf、incfsz、decfszなどの命令でインクリメント、デクリメントすることができます。
上の例では、データメモリアドレス345が選択されますから、
movf INDF0,w
とすれば、345番地のデータがwレジスタに入ります。

逆に、
movwf INDF0
とすれば、wレジスタの値が345番地に入れられることになります。

このあと、
incf FSR0L
とすれば、その次のアドレス346番地が次に選択されることになりますし、
decf FSR0L
とすれば、344番地が選択されることになります。

そのようにすれば、BSRの指定とは別のメモリバンクのx00〜xFFをアクセスすることができますし、incfsz、decfszと組み合わせて、上位レジスタのFSRnHをインクリメント、デクリメントすることによって、バンクの境を越えてシームレスにメモリをアクセスすることも可能です。

このように、PIC18F4550には、8080のHLレジスタを使った間接メモリアクセスと全く同じ感覚で使えるFSR、INDFレジスタペアが3組も用意されていて、相互には全く独立して使うことができますから、この3組のペアレジスタによる間接メモリアクセスと、バンク0、バンク15をアクセスするベーシックな直接メモリアクセスを必要に応じて使うことによって、かなり高度なプログラムが組めることがおわかりいただけると思います。

それだけでもPIC18F4550は、PIC16Fとは比較できないくらい優れたパフォーマンスを有していることになるのですが、実は、このPIC18F4550のFSR、INDFペアによるメモリアクセスには、もっと便利な機能が用意されていたのです。

本日は時間がなくなってしまいました。この続きはまた次回に説明いたします。
2010.1.6upload

前へ
次へ
ホームページトップへ戻る