PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 |
2011.7.13 前へ 次へ 目次へ戻る ホームページトップへ戻る |
☆PIC18F14K50 PIC18F2550では大きすぎて、計画中のTK80互換マイコンボードND80ZVには組み込めそうにないことがわかりました。 USB機能内蔵のPICにはPIC18F4550、PIC18F2550のほかに20pinのPIC18F14K50があることはちょっと前から知っていました。しかしUSBに関する部分がPIC18F2550とはかなり異なっているようです。 案の定しっかり泥沼にはまってしまいました。 |
[第91回]
●PIC18F14K50メモリマップ
PIC18Fのほとんどの機械語の命令は8ビットのメモリアドレスしかアクセスできません。
8ビットのメモリアドレスは00〜FFの256バイトです。
しかしPIC18F14K50には約1KBのデータメモリがあります。
PIC18F14K50のメモリマップです。
[出典]MICROCHIP社PIC18F14K50DataSheet
前回も説明しましたように、8ビットのアドレスしかアクセスできない機械語命令で256バイトを超える範囲のメモリをアクセスするためのひとつの方法としてバンク切り換えがあります。
先頭から256バイトごとに分割して、それをBank0、Bank1、…、Bank15とします。
必要な範囲のメモリをアクセスする前にバンクレジスタ(BSR)に、そのバンクbセットしておいてから、そのメモリアドレスをアクセスする命令を実行します。
しかしこの方法はプログラムによっては頻繁にBSRにバンクb書き込まなくてはならないことになって、なかなかに面倒です。
そこで、ユーザーが汎用のワークエリアとして最も良く使用するバンク0(アドレス000〜0FF)の前半の96バイト(000〜05F)と、システムレジスタ群があるバンク15の160バイト(F60〜FFF)をくっつけた形でアクセスできるモードが用意されています。
その仮想的なバンクをAccess Bankといいます(上図参照)。
Access Bankを指定して、普通の機械語の命令で00〜FFのメモリ範囲をアクセスすると、00〜5Fのアドレスを指定したときは、000〜05Fの範囲のメモリがアクセスされ、60〜FFのメモリ範囲をアクセスすると、F60〜FFFの範囲のメモリがアクセスされます。
PIC18Fの命令はアセンブラ表記で’a’パラメータに0を指定したときに、Access Bankが選択されます。
前回はちょいとうっかりして、’a’パラメータを省略すると(デフォルトでは)、Access Bankが選択される、と書きましたが、正しくはデフォルトではBSRが選択される、でした(DataSheetを読みますとそのようにしか解釈できないものですから、一旦はこう書いたのでしたが…。下記の[注記]をお読みください)
[2010.6.14注記]
なにしろいろいろあれもこれもと、足りない頭と足りない時間でフルに活動しておりますものですから、一旦はそのように書いたのですけれど、どうにもおかしい。
そーいうことではないはずなのだが…。
なんだか過去の経験を無理やり否定されてしまったような気持ち悪さを感じながら、まま、DataSheetにはそのように書いてあるのだから、ということで、抵抗する頭を無理やり納得させたのでありましたが…。
やっぱり納得できません。
そりゃあ、おかしいよお。
どうにも納得できませんでしたので、作業が一息つきましたときに、あらためて確認をしてみました。
その結果、やっぱり、ということで納得いたしました。
納得しました結果からしますと、今回、ここで書きました’a’パラメータにつきましての記述は、やっぱりおかしい書き方になってしまっておりました。
’a’パラメータのdefaultにつきましては、[第94回]にまとめましたので、ご参照願います。
(注記ここまで)
’a’パラメータを省略するとBSRをベースにしたバンク切り替えが指定されるのですが、FSRとして登録されているレジスタ名(PORTAとかTRISAなど)を使った場合には、’a’パラメータを省略しても、アセンブラがAccess Bankを指定するように翻訳してくれます。
ここらあたりのことにつきましては、[第20回]、[第21回]で説明をしています。
前回、PIC18F14K50でこのアクセス方法を使ったために、ドツボにはまってしまいました、と書きました。
むむむ。
全然、気が付かなかったのですよお。
上のメモリマップをよく見ますと、SFR(Special Function Registers)が破線で2つに分かれているのですよねえ。
アドレスF53〜F5FとF60〜FFFの2つに。
そしてF53〜F5Fの方には(1)がついていて、図の下部を見ますと。
Note1: SFRs occupying F53h to F5Fh address space are not in the virtual bank
って書いてあります。
なるほど。
ここに気が付かなかった私が悪い。
しかし、しかし。
こおいうことは、できれば、やめていただきたい。
せっかくACCESS BANKなどというアクセス方法を用意しておいて、それでアクセスできないところにシステムレジスタを拡張してしまうってのは、ねえ。
●PIC18F14K50のFSR(Special Function Registers)
[出典]MICROCHIP社PIC18F14K50DataSheet
おお。
気が付いてみれば、なんとしっかりはみ出しているではありませんかあ。
しっ、しかも、USB関連のレジスタの大半がしっかりはみ出していますう。
これじゃ、いくらやってもUSBにアクセスできないはずだわ。
はい。これが[第84回]でお見せしたPIC18F14K50の「動いてくれなかった」プログラムです。
;;;pic p18f14k50 USB test program ;10/6/2 ; #include<p18f14k50.inc> ;cpuclock=48MHz exclock=12MHz ; CONFIG FOSC = ECH,CPUDIV = NOCLKDIV,USBDIV = OFF,PCLKEN = ON,PLLEN = ON,WDTEN=OFF,LVP=OFF ; w=0 f=1 c=0 z=2 ; cntr0=0c cntr2=0d cntr1=20 ; org 00 clrf ANSEL clrf ANSELH clrf TRISC clrf TRISB clrf TRISA ; usbreset movlw 16 movwf UEP0 ←ここが問題!! movlw 15;ping-pong buffer set for EP0(out) only movwf UCFG ; call setbd0 ; movlw 0ff movwf PORTC movlw 48 movwf UCON;clear bit4,for SIE enbl loop_ucon btfss UCON,4;if SETUP detect goto loop_ucon ; loop call t1ms decfsz cntr1 goto loop movlw 1 xorwf PORTC goto loop ; ;ep0 out data0(even) setbd0 lfsr 1,203 movlw 05;address high movwf POSTDEC1 movlw 00;address low movwf POSTDEC1 movlw 08;bytes movwf POSTDEC1 movlw 80;STAS(even) movwf POSTDEC1 return ; ;1msec timer t1ms movlw 0a;=10 movwf cntr2 t1ms2 call tm100micros decfsz cntr2 goto t1ms2 return ; tm100micros movlw 0f0;=240 movwf cntr0 tm100micros2 nop nop decfsz cntr0 goto tm100micros2 return ; end |