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

●PIC18F14K50用「動作する」USBプログラム

PIC18F2550でまともに動作していたプログラムがPIC18F14K50では全く動いてくれなかった、その原因は前回書きましたようにUSBに関係するシステムレジスタが、バンク切り換えを使わない簡便なアクセス方式であるAccess Bankではアクセスできない「領域外」に置かれている、というとんでもないところにありました。

まあしかし、私がそれをとんでもない、と言ってみたところで、これはもうMICROCHIP様のお考えになることでありますから、どーにもなることではありません。
素直に従うしかありません。

では、どのように直したらよいのか、ということなのですが、対策は2通り考えられます。
「動かなかった」プログラムは前回お見せしておりますが、そのうちの直さなければならないところだけ、もう一度取り出して下に示します。

;
usbreset
	movlw 16
	movwf UEP0
	movlw 15;ping-pong buffer set for EP0(out) only	
	movwf UCFG
;

という部分です。
下の movwf UCFGはこのままで構いません。
UCFGはアドレスがF61なので、Access Bankで普通にアクセスできます。
問題はmovwf UEP0です。
UEP0のアドレスはF53なので、Access Bankではアクセスできません。
では、どうすればよいか、といいますと、まず考えられる方法はBSRレジスタを使って、BANK15を指定しておいてから、UEP0に対するmovwf命令を使うようにすることです。

下のように書き直します。

;
usbreset
	movlb 0f
	movlw 16
	movwf UEP0,1
	movlw 15;ping-pong buffer set for EP0(out) only	
	movwf UCFG
;

movlb 0f で、BSRレジスタにバンク15(0fh=15)を指定します。
PIC18Fアセンブラでは、BSRで指定したバンクアドレスに従ってアクセスしたいときには、命令の最後の’a’パラメータに’1’を指定します。
この’1’を省略すると、Access Bankをアクセスします。
前回も少し書いたことなのですが、このパラメータの省略についてはDataSheetの説明がどうやら間違っているようです。
おかげで私の説明も二転三転してしまいました。
そのことについてはまたのちほど説明をいたします。

前回、Access Bankを使わないで、BSRによるバンク切り換え方式でレジスタをアクセスするようにすると、別のバンクのメモリをアクセスする場合には、またBSRにそのメモリバンクの番号を書き込まなくてはならなくて、なかなか面倒です、と書きました。
たとえば上の例では、movlb 0f によってBSRに0fがセットされますから、次にBSRに別のバンクbセットするまでの間は、ずっとバンク15がセレクトされることになります。
それじゃあ、ユーザー用のレジスタエリアの000〜に置いたワークレジスタをアクセスできないので、上のプログラム部分の下で、movlb 0 を書いておかなければいけないのではないだろうか。
いやいやそれでは、他のシステムレジスタがアクセスできなくなってしまうから、やっぱりBSR=0fのままにしておかなければいけないのだろうか。
など、いろいろ悩んでしまいます。

でも、実は、それほど悩む必要はないのです。
上で書きましたように、BSRで指定したメモリバンクをアクセスするためには、命令の末尾にパラメータの’1’をつけなければならないのですから、これを逆に考えますと、今までと同じように、Access Bankでのアクセスで構わないところには’1’をつけなければよいのです。
その場合にはBSRに何が指定されていても、それは無視されてしまって、Access Bankがアクセスされることになります。
たとえば上の例で、movwf UCFGには’1’がついていません。
UCFGはバンク15にあって、かつFFF〜F60の間にありますから、この場合には’1’をつけてもつけなくてもどちらでもアクセスできることになります。
しかしもしこのmovwf UCFGの前でBSRに別のバンクbェ入れられていると、’1’をつけた場合にはUCFGではなくて、別のアドレスがアクセスされてしまいます。
そういうことから考えてみますと、’1’パラメータはどうしてもつけなくてはならないとき以外はつけないようにしておいた方がいい、ということになります。

ところで、BSRを使う方法以外にも、UEP0に正しくアクセスできる方法があります。

また時間がなくなってしまいました。
この続きは、次回にすることにいたします。
2010.6.10upload

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