Sahara's WebLog

日記のような、備忘録のような、うらみつらみのような、自慢のような…。

PIC24FJ64GB002 __delay_ms();を使う

やっぱり手っ取り早いのは __delay_ms(); だ。
PIC24シリーズというかXC16というか、8BITのものとは若干使い方が違ったので放置状態だったが、使い方が分ったので書く。

肝心なのは以下の3行のおまじない。

システムのクロック(FOSC)を指定し、それを2で割ったものがInstruction Cycle Clock (FCY)になる。

The processor clock source is divided by two to produce the internal instruction cycle clock, FCY. In this document, the instruction cycle clock is also denoted by FOSC/2.

ま、難しいことはよく分からないが、これを書いておけば、__delayが使えるってわけ。
例えばこんな感じ。

6ピンにつないだLEDが0.5秒間隔で点滅する。
ちなみに、PICF24では訳の分らない Configuration Bits が山ほどある。
もちろん8BITのPICのConfiguration Bitsもすべてを把握したわけではないが、数がねえ16BITでは全く違って、頭が痛くなる。

というわけで、今回、あれこれこねくり回した挙句どうやら意図した動作にこぎつけたドタバタの記録。
__delay_ms(500);と設定しているのに、実測すると88.06475msとかいう値になる。
pic24fj64gb002_delay_t1_01
あれこれ見直しても直らないので、面倒になってConfiguration Bitsの設定を全て削除してみたら、499.5685msと意図した値になる。
pic24fj64gb002_delay_t1_02
あれこれいじり倒した挙句におかしな設定をしてしまったという毎度のパターンだ。
原因を絞っていくと、
#pragma config FNOSC = FRCPLL // Initial Oscillator Select (Fast RC Oscillator with Postscaler and PLL module (FRCPLL))
となっているとダメで、
#pragma config FNOSC = FRCDIV // Initial Oscillator Select (Fast RC Oscillator with Postscaler (FRCDIV))
ならうまく動く。
もちろん、他の設定との兼ね合いでどうにかなる場合もあるのでこれが直接の原因だとは一概には言えない。
そうは言っても他との兼ね合いまで考慮するとわけ分らなくなるので、とりあえずこのFNOSCとは何ぞやということに絞る。
良く分らないので調べると、PIC24 Family Reference Manual の Section 6. Oscillator によれば以下の通り。
pic24fj64gb002_delay_t1_03
Power-on Reset時に使うClock sourceを決定するんだって。
ついでに同じところの下の表を見るとこうなっていて、
pic24fj64gb002_delay_t1_05
今回の目標である「内蔵のクロックを使って8MHzをPLLでもう少し速くして使いたい。」という場合には、赤枠の設定でいいことが分る。
88.06475msという予期しない値になったときの設定がこれなので、あながちでたらめをやってたわけでもないようだ。
下は、PIC24FJ64GB002 のデータシートから。
pic24fj64gb002_delay_t1_04
pic24fj64gb002_delay_t1_06
ちなみにIDE(v2.35)ではPOSCMDではなくPOSCMODとなっている。
pic24fj64gb002_delay_t1_07
そうなると、結局のところ、Oscillatorの設定に関しては問題は無いが PLL module を含めると変になるということなので、今度はPLLを調べないといけない。
仕方なくPLLがらみを PIC24 Family Reference Manual Section 6. Oscillator で読んでいく。
すると一番大事な勘違いに気付く。
このファミリーには大きく2種類のPLLの仕組みのいずれかが搭載されていて、それは「Basic 4x PLL Block」と「96 MHz PLL Block」である。
PIC24FJ64GB002はUSB機能の付いているPICなので「96 MHz PLL Block」が載っている。
実は、データシートをナナメにしか読まない私は、「96 MHz PLL Block」はUSB機能を使わないなら無関係だと勘違いして、これ関連の設定を全く無視していたのだった。
実際は、たとえUSBは使わなくても、PLLを使うなら必須の設定項目があったのだ。
下のブロック図を見るとそれがよくわかる。
内蔵のOscillatorを使って最速の32MHzで動かすときの設定の流れを赤い矢印で示してある。
pic24fj64gb002_delay_t1_08
そしてたぶん一番肝心なのがこの一文。
pic24fj64gb002_delay_t1_09
PLLには4MHzを入れなきゃいけないので、クロックが8MHzなら一度4MHzにする必要がある。
#pragma config PLLDIV = DIV2 // USB 96 MHz PLL Prescaler Select (Oscillator input divided by 2 (8 MHz input))
これを設定すれば、当初の設定の
#pragma config FNOSC = FRCPLL // Initial Oscillator Select (Fast RC Oscillator with Postscaler and PLL module (FRCPLL))
のままでちゃんと意図した動作をしてくれる。
ただし、#define FOSC (8000000UL) は #define FOSC (32000000UL) と書き直す。
pic24fj64gb002_delay_t1_10
以上で、とりあえず、
内蔵クロック、PLLで最速駆動、delayを使う
が実現できた。
最近お気に入りの光らせ方。

pic24fj64gb002_delay_t1_11

このエントリーをはてなブックマークに追加

Posted under: PIC24FJ64GB002


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.