前回はWDTとLVPしか設定しませんでしたが、他の設定についても決めていきたいと思います。
MCC18のドキュメントの hlpPIC18ConfigSet.chm とPIC18F2550のデータシートを見比べながら検討します。
まずは動作クロックに関する設定からです。秋月のマイコンボードAE-18F2550の場合は20MHzの発振子がOSC1,OSC2ピン(9番ピンと10番ピン)につながっていて、これがプライマリオシレータとなります。
USBモジュールはUSBの要件として6MHz(Low-Speed)ないし48MHz(Full-Speed)のクロックで動作しなければならないそうなのですが、特にLow-Speedを選ぶ理由はないので、この20MHzを掛けたり割ったりして最終的に48MHzを作ります。
これはデータシートのFIGURE 2-1の上部に該当します。
一番右のFSENというのは48MHzか6MHzかを選ぶ設定で、1だと48Mhzになって上のほうから48MHzクロックを受け取ることになります。
そこを左にたどっていくとあるUSBDIVというのはプライマリオシレータから直接48MHzを受け取るか、PLLを通して受け取るかの選択です。このマイコンボードのオシレータは20MHzなので直接受け取れませんからPLLを通して受けます。1のほうを選択することになります。
その1を左にたどって「÷2」とあるのは文字通りです。この右側が48MHzとなっていて左側が96MHzとなります。
「96MHz PLL」は4MHzのクロックを受け取って96MHzのクロックを出力するモジュールです。したがってこの左側ではクロックが4MHzになっていなければなりません。
その左の「PLL Prescaler」は何らかの周波数のクロックを受け取り、それを1から12までの数(PLLDIV)で割った周波数のクロックを出力します。これの入力が20MHzで出力が4MHzになるようにするのですから、「÷5」を選択すればいいということになります。
以上からFSEN, USBDIV, PLLDIVの値が決まります。
#pragma config PLLDIV = 5 // Divide by 5 (20 MHz oscillator input)
#pragma config USBDIV = 2 // USB clock source comes from the 96 MHz PLL divided by 2
USBDIVは先の図で0,1となっているところがpragma上は1,2で指定するようです。ちょっと紛らわしいですね。
FSENはコンフィギュレーションビットではなくファイルレジスタの値で設定するようです。仮にFSENでLow-Speedを選ぶという場合でも発振子が20Mhzという時点で上記2つのコンフィギュレーションビットは自動的に決定されるといってもいいと思います。
なおちょっと先回りして言うと、FSENの値はMicrochip社のUSBフレームワーク上はUSB_SPEED_OPTIONという定数をUSB_FULL_SPEEDという値にすることで設定します。
さて、48MHZはUSBモジュールのクロックの要件でした。PIC18F2550ではマイコン本体の動作クロックはこれとは別に設定できます。こちらは正直なんでもいいような気がしますが、せっかくなので一番速く動く設定にしたいと思います。
データシートのTABLE 2-3から発振子が20MHzの場合の設定を見ます。
これをみると48MHzにする設定が最高のようです。
まずClock Modeに上下段の選択肢があります。上の段はプライマリオシレータ(20MHz)から直接クロックをもらうルート、下の段はPLL(96MHz)経由でクロックをもらうルートです。PLL経由のほうが動作周波数が高いのでこちらにします。これにするためにはClock Mode(FOSC)を下の段のHSPLL,ECPLL,ECPIOのどれかにします。
じゃあ3つのうちどれにしたらよいのかというと、これは外付けの発振子のタイプで決まります。以下のページが参考になりました。
http://www.picfun.com/pic20.html
この秋月のマイコンボードは水晶発振子が使われているのでHSPLL,ECPLL,ECPIOのうちHSPLLに設定します。
#pragma config FOSC = HSPLL_HS // HS oscillator, PLL enabled, HS used by USB
MCU Clock Division(CPUDIV)は「÷2(00)」にするのが最速です。
#pragma config CPUDIV = OSC1_PLL2 // 96 MHz PLL Src: /2
多分以上がUSBを扱う上での最小限必要な設定だと思います。他の設定も適当に決めておきます。
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor disabled
FCMENはFail-Safe Clock Monitorという、外部クロックがうまく動いていないときに内部クロックに切り替えて動作させるモードを使うかどうかの設定です。デフォルトでOFFです。使わないのでOFFのままにします。
IESOはTwo-Speed Start-upという、外部クロックが動き出すまでの間とりあえず内部クロックを使っておくことによりプログラムの動作開始までの時間を短縮するというモードの設定です。デフォルトでOFFです。使わないのでOFFのままにします。
#pragma config PWRT = OFF // PWRT enabled
PWRTはPower-up Timerの設定で、これは電源投入後、電圧が安定するまでは動き出さないようにするものです。デフォルトでONです。これは使ったほうがいい気がするのでONのままにします。
#pragma config BOR = ON // Brown-out Reset enabled in hardware only (SBOREN is disabled)
#pragma config BORV = 3 // Minimum setting
BORとBORVは電源電圧がある閾値より下になったらリセットをかけるという機能です。特に判断がつかないのでデフォルトのままとします。
#pragma config VREGEN = ON // USB voltage regulator enabled
VREGENはUSBがらみで必要な3.3Vを作るためのレギュレータを有効にする設定です。デフォルト値についてデータシートの記載に矛盾がある(p.167の17.2.2.8では "The regulator is enabled by default and can be disabled through the VREGEN Configuration bit." だが、p.289のREGISTER 25-3では "Value when device is unprogrammed" が 0 となっている)のですが、必要なはずなのでONにします。
#pragma config WDT = OFF // HW Disabled - SW Controlled
#pragma config WDTPS = 32768
ウォッチドッグタイマーは前回の記事の通りOFFにします。タイマーの値はWDTPSで設定されます。OFFなので使われませんが、とりあえず一番長い値にしておきます。
#pragma config MCLRE = ON // MCLR pin enabled; RE3 input pin disabled
MCLREはMCLR/RE3ピンをリセットボタンに使用するかどうかで、もしOFFにすればこのピンを普通のデジタル入力として使えるようになります。とりあえずONでいいと思います。ちなみに秋月のボードではMCLRピンはプルアップ抵抗がつながった状態にしてくれています。
#pragma config LPT1OSC = OFF // Timer1 configured for higher power operation
LPT1OSCはTimer1を低電力モードで動かすかどうかで、低電力モードだと電力消費が少ない代わりにノイズの影響を受けやすくなると書いてあります。デフォルトでOFFです。OFFでよいかと思います。
#pragma config PBADEN = ON // PORTB<4:0> pins are configured as analog input channels on Reset
PBADENはPORTBのピンが初期起動時にアナログ入力モードになるかどうかの設定です。特にいまの段階で判断することではないのでデフォルト通りONにします。
#pragma config CCP2MX = ON
これは多分CCP2のピンをRC1(12番ピン)かRB3(24番ピン)のどちらにアサインするかの設定を行うようです。デフォルトのまま(RC1)にします。
#pragma config STVREN = ON // Stack full/underflow will cause Reset
STVRENがONだとスタックオーバーフローやアンダーフローが起きた時にデバイスがリセットされます。デフォルトONです。OFFだとプログラムで例外処理できるのだと思いますが、そんな細かいことをするつもりはあまりないのでONでいいでしょう。
#pragma config LVP = OFF // Single-Supply ICSP disabled
LVPは前回も書いたとおりOFFにします。デフォルトはONです。
#pragma config XINST = OFF // Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
PIC18F2550の拡張命令が使えるようにするモードです。多分C18コンパイラにも拡張命令を使うかどうかの設定があるはずですが、今使っているStandard Evaluationでは60日後に拡張命令も使えなくなることが分かっていますので最初からOFFにしておきます。
#pragma config DEBUG = OFF // Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
DEBUGをONにするとMPLAB IDEでデバッグができるらしいのですが、ちょっと難しそうなのでOFFにしておきます。デフォルトもOFFです。
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF
#pragma config CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
#pragma config WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF
#pragma config EBTR3 = OFF
#pragma config EBTRB = OFF
メモリー保護のための設定ですが、全部OFFにしておきます。
ここまで設定するとPICkit2にコンフィギュレーションビットに関する警告を受けずに済むようになります。
あと動作クロックがデフォルトよりあがってLEDの点滅が速くなりました。