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

UEP0に16を入れたつもりだったのですけれど、PIC18F14K50用としてこのプログラムをアセンブルしますと、UEP0=53hとして機械語に翻訳されてしまいます。
すると、ACCESS BANKのルールで、この部分はF53hではなくて、053hに16をmoveするという命令になってしまいます。

あ。もう少し、ですけれど、本日もまたタイムアウトになってしまいました。
ですので、この続きは次回に書くことにいたします。
CPUをつくろう!第520回(2010.6.9upload)を再編集

PICでUSBを![第91回]
2011.7.13upload

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