PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 |
2011.7.12 前へ 次へ 目次へ戻る ホームページトップへ戻る |
☆PIC18F14K50 PIC18F2550では大きすぎて、計画中のTK80互換マイコンボードND80ZVには組み込めそうにないことがわかりました。 USB機能内蔵のPICにはPIC18F4550、PIC18F2550のほかに20pinのPIC18F14K50があることはちょっと前から知っていました。しかしUSBに関する部分がPIC18F2550とはかなり異なっているようです。 案の定しっかり泥沼にはまってしまいました。 |
[第75回]
●USBのためのCPUクロック
前回はPIC18F14K50を使うことを前提にして、そうするとI/Oの数が不足してしまいますから、CPUとの間でのパラレル伝送を現行の8ビットから4ビットに変更するようにプログラムを変更して、とりあえずはまだPIC18F2550のままなのですが、その動作テストがうまくいきました、というところまで書きました。
昨年10月からおよそ半年をかけて、やっとPIC18F2550でUSB(HID)の送受信に成功するところまできたことでもありますし、スタートしたときはPIC18F4550だったのですがPIC18F4550からPIC18F2550へはほとんど変更らしい変更もなくすんなりできたのですけれど、ここからさらに、PIC18F2550からPIC18F14K50への変更を行うことにつきましては、いささか気が重かったのですねえ。
もともとPICをナニするということが本来の目的ではなかったわけですし、あんなこんなで予想だにしなかった泥沼につぐ泥沼に手足を取られていささかうんざりしてしまいましたから、もうこの辺でいいじゃないの、という気分になってきておりました。
そういう精神状態でありますから、なんとなく気が乗らなかったわけですけれど、半分はいやいやながらも、こうやって4ビットでのデータ伝送もできてしまいますと、せっかくここまできたのに、PIC18F14K50に全然タッチしないままで済ます、というのもちょいと惜しい、などという別の気の迷いも出て来てしまいます。
PIC18F2550に比べますと、PIC18F14K50は、第一印象としては、なんだかちょいとムリをしているような感じで、使うのにもなかなか骨が折れそう、といったところが気にはなりました。
で、まあ、とりあえず、ちょいとさわってみて、あまり納得がいかないようでしたら、やっぱりPIC18F2550を使うことにして、基板配線を工夫してなんとか28pinを乗せられるように考えることにいたしましょう。
すでに説明しましたようにPIC18F14K50はUSBメモリのアドレスと、そのメモリサイズがPIC18F2550とは全く異なっています。
しかしそれにつきましては、いうなれば機械的な変更作業でクリアできるはず、なのですから、当初からあまり問題視はしておりませんでした。
しかしながら、CPUクロック。
これはちょいと問題だなあ。
というわけで、まずは、そのあたりから、そろりそろりと首をつっこむことにいたしました。
まだいきなりUSBの本拠地には突入などいたしません。
とはいえ、もちろん、PIC18F14K50を使ってUSBをナニすることが目的ですから、そこのところをふまえた上で、まずはCPUクロックの説明から取りかかることにいたしまします。
USBを使わない、ということでしたなら、いまさらPICのクロックについてどうこう言うことはない、でありましょう。
それは18Fであっても、16Fであっても似たようなものなのです。
適当な値のクリスタルを外付けするだけで、簡単に動作してくれますし、クリスタルを外付けしなくても、内蔵の発振回路を使って自前でCPUクロックを供給してくれるものも多くなりました。
しかし、USBを使う、ということになりますと、今までのPICとはいきなり様子が異なってきてしまいます。
PIC18F2550については、[第58回]から[第63回]で簡単なプログラムについての説明をいたしました。
そこでは、USBを使わない、ごく普通のプログラムをPIC18F2550に書いての動作テストをしました。
[第58回]のテストでは外付けのクリスタルも不要な内部発振回路によるクロックを使いました。
内部発振回路とはいっても、なんと8MHzまでのクロックが選択でき、クロックの精度も通常の使用には差し支えない程度の精度はありますから、これはなかなかに便利です。
ということで、とりあえずの動作テストとしては、その内部発振回路によるクロックでよかったのですけれど、USBを使おうとしますと、残念ながらこのクロックでは動作させることができません。
PIC18F2550でUSBプログラムを実行させるためには、48MHzのクロックが必要になります(Full Speedモード)。
CPUそのものの動作としては48MHzものクロックは必要ないのですが、PIC18F2550に内蔵されているUSBロジック回路には、48MHzが必要なのです。
USB信号は12MHzです(Full Speedモード)から、その4倍の周波数ということになります。
PICはCPUクロックの4クロックが1マシンサイクルになっています。
PIC18F2550に内蔵されているUSBロジック回路もPICCPUと良く似たアーキテクチャで作られているのかも知れません。
それはともかくとして、12MHzならばなんとかなりますが、48MHzとなると、これは普通のTTLなどのはるかに及ばない高い周波数です。
このような高い周波数のクロックを外部から供給するとなると、もうのっけから敷居が高くなってしまいます。
幸いPIC18F2550のクロック回路にはPLL回路が内蔵されていて、低い周波数を供給しても、そこから48MHzを作り出してくれます。
そのあたりの設定はconfigワードで設定することになります。
●PIC18F2550のUSBのためのクロックの設定(DataSheetから)
PIC18F2550のData Sheetで、その説明を見てみることにいたしましょう。
[出典]Microchip社PIC18F2455/2550/4450/4550DataSheet
普通のPICと違って、USBを扱うためには、CPUクロックのほかに、USBのLow Speedモード(6MHz)とFull Speedモード(12MHz)の両方のクロックが必要になってきます。
PIC18F2455/2550/4450/4550は(いちいちこのように書くのは面倒ですから、以下はPIC18F2550とだけ書くことにしてしまいます)、USBのFull Speedモードに対応するために、48MHzのクロック回路を用意している、てなことが書いてあります。
PIC18F2550には12種の異なるクロックモードがあって、う?twelve?
でも1から10までしか書いてありません。2つ足りないじゃないの。
ここらあたりがMicrochipのDataSheetのチャランポランなところで、そもそもDataSheetに書いてある表現のままConfigに書いてもたいていはエラーになってしまうのですよねえ。
このOscillator Typeに関して言えば、Configにそのまま書いて通るのは”HS”だけです。
ちなみにインクルードファイルP18f2550.incを覗いてみますと。
; Oscillator Selection bits: ; FOSC = XT_XT XT oscillator, XT used by USB ; FOSC = XTPLL_XT XT oscillator, PLL enabled, XT used by USB ; FOSC = ECIO_EC External clock, port function on RA6, EC used by USB ; FOSC = EC_EC External clock, CLKOUT on RA6, EC used by USB ; FOSC = ECPLLIO_EC External clock, PLL enabled, port function on RA6, EC used by USB ; FOSC = ECPLL_EC External clock, PLL enabled, CLKOUT on RA6, EC used by USB ; FOSC = INTOSCIO_EC Internal oscillator, port function on RA6, EC used by USB ; FOSC = INTOSC_EC Internal oscillator, CLKOUT on RA6, EC used by USB ; FOSC = INTOSC_XT Internal oscillator, XT used by USB ; FOSC = INTOSC_HS Internal oscillator, HS used by USB ; FOSC = HS HS oscillator, HS used by USB ; FOSC = HSPLL_HS HS oscillator, PLL enabled, HS used by USB ; |
; ; PLL Prescaler Selection bits: ; PLLDIV = 1 No prescale (4 MHz oscillator input drives PLL directly) ; PLLDIV = 2 Divide by 2 (8 MHz oscillator input) ; PLLDIV = 3 Divide by 3 (12 MHz oscillator input) ; PLLDIV = 4 Divide by 4 (16 MHz oscillator input) ; PLLDIV = 5 Divide by 5 (20 MHz oscillator input) ; PLLDIV = 6 Divide by 6 (24 MHz oscillator input) ; PLLDIV = 10 Divide by 10 (40 MHz oscillator input) ; PLLDIV = 12 Divide by 12 (48 MHz oscillator input) ; ; CPU System Clock Postscaler: ; CPUDIV = OSC1_PLL2 [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2] ; CPUDIV = OSC2_PLL3 [OSC1/OSC2 Src: /2][96 MHz PLL Src: /3] ; CPUDIV = OSC3_PLL4 [OSC1/OSC2 Src: /3][96 MHz PLL Src: /4] ; CPUDIV = OSC4_PLL6 [OSC1/OSC2 Src: /4][96 MHz PLL Src: /6] ; ; USB Clock Selection bit (used in Full Speed USB mode only; UCFG:FSEN = 1): ; USBDIV = 1 USB clock source comes directly from the primary oscillator block with no postscale ; USBDIV = 2 USB clock source comes from the 96 MHz PLL divided by 2 ; |
;;;pic p18f2550 test program ;f2550test3 ;4/25 5/18 ; #include<p18f2550.inc> ; ;cpuclock=48MHz 4MHz crystal ; CONFIG PLLDIV=1,USBDIV=2,CPUDIV=OSC1_PLL2,FOSC = XTPLL_XT,WDT=OFF,LVP=OFF ; org 00 st0 movlw 0f movwf ADCON1;porta,b,e are digital movlw 0;porta-c are output movwf TRISA movwf TRISB movwf TRISC ; movlw 1 loop xorwf PORTA goto loop ; end |