PIC 24FJ256GB110のクロック設定

投稿日 2014/03/26

PIC 24FJ256GB110ファミリのクロック設定をまとめてみました。

 

24FJ256GB110ファミリのクロック・ダイアグラムを以下に示します。

 

主な構成要素は、
 プライマリ・オシレータ
 セカンダリ・オシレータ
 USB PLL
 FRCオシレータ
 FRCオシレータ ポストスケーラ
 LPRCローパワーRCオシレータ
 クロック・マルチプレクサ
 リファレンス・クロック・ジェネレータ
 DOZEポストスケーラ
 クロック・コントロール・ロジック(含FSCM)

24FJ256GB110_1.jpg

PIC 24FJ256GB110ファミリのクロックダイアグラム (Microchip社データシートより)

 

24FJ256GB110のクロック周波数(Fosc)の最高は32MHzです。インストラクションは2クロックで実行されるのでFosc/2 つまり最高16MIPSです。

 

最も簡単にはプライマリ・オシレータに32MHzの水晶発振子をつないで、そのままFoscとすればよいのですが、せっかく内部にPLLやポストスケーラ(分周器)を内蔵しているので、8MHz位の発振子をつないで使うのが一般的です。

 

また、USBを使用する場合に必要となるUSBクロック(48MHz)を生成できるようになっています。

 

各構成要素の概要
 

 

○プライマリ・オシレータ(OSCO)
 外付けの発振子(XT, HS)、または発振器(EC)です。

 

○セカンダリ・オシレータ(SOSCO)
 外付けの発振子で、主にリアルタイム・クロック(RTCC)用クロック源として32.768Hzの発振子をつなぎます。

 

○USB PLL OSCOまたはFRCの4MHzまたは8MHzからPLLで96MHzに逓倍し、1/2してUSB用の48MHzを作ります。また1/3して32MHzをつくり、分周器で1/1, 1/2, 1/4, 1/8し、32MHz, 16MHz, 8MHz, 4MHZ(XTPLL, HSPLL, ECPLL, FRCPLL)を作ります。

 

○FRC 内蔵のRC発振器で8MHzです。

 

○FRCポストスケーラ FRC(8MHz)を分周し(MHzから31.25KHzを作ります。分周比は1:1から1:256までの8種類で、8MHz, 4MHz, 2MHz, 1MHz, 500KHz, 250KHz, 125KHz, 31.25KHzからプログラム実行時に選択(CLKDIVのRCDIVビット)できます。

 

○LPRC 内蔵の低速ローパワーRCオシレータ 31KHzです。

 

○マルチプレクサ OSCO直結(XT, HS, EC)、PLL出力(XTPLL, HSPLL, ECPLL, FRCPLL)、FRC直結(FRC)、LPFRC、SOSCO直結(SOSC)の5種から選べます。マルチプレクサの出力はそのまま周辺(Peripheral)のクロックとなります。CPUのクロックはDOZEポストスケーラを通過します。

 

○DOZEポストスケーラ CPUクロック用の分周器です。1:1から1:128分周の8種類からプログラム実行時に選択(CLKDIVのDOZEビット)できます。

 

○リファレンス・クロック・ジェネレータ プライマリ・オシレータまたはマルチプレクサの出力の分周値を外部(REFOピン)に取り出すことができます。1:1から1:32,768までの16種の分周を選択(REFOCON)できます。

 

クロック設定関連のコンフィグレーション・ビットとレジスタ・ビットフィールド
 

 

クロック設定は、いくつかのコンフィグレーション・ビットとレジスタのビット・フィールドの設定で行います。

 

コンフィグレーション・ビットはコンパイル時に決定するため実行時に変更できませんが、レジスタのビットフィールドは、プログラム実行時に変更可能です。このため、必要によってクロックを遅くしたり早くしたりすることができます。

 

■関連するコンフィグレーション・ビット

 

_CONFIG2の以下のビットがクロック設定に関係します。

 

プライマリ・オシレータの選択
 接続する水晶発振子が3から10MHzならXT、10から32MHzならHS。発振器ならECを選ぶ
 プライマリ・オシレータを使用しない場合はOFFとする

 

 POSCMOD_EC 外付け発振器
 POSCMOD_XT 外付け発振子
 POSCMOD_HS 外付け発振子
 POSCMOD_OFF プライマリ・オシレータ無し

 

プライマリ・オシレータ出力機能の選択
 OSCOピンの使用方法を選ぶ

 

 OSCIOFNC_ON OSCOピンをGPIO RC15として使用

OSCIOFNC_OFF OSCOピンをCLKOとしてFosc/2クロックを出力
 

クロック・スイッチングとモニタ
 フェールセーフ・クロック・モニタを有効にするとカレント・クロックに異常があるとOSCCONの
 NOSCで設定したクロックに切り替わる
 クロック・スイッチングを有効にすると、OSCCONのOSWENでプログラム実行中にOSCCONのNOSCで設定
 したクロックに切り替えることができる

 

 FCKSM_CSECME クロック・スイッチングとフェースセーフ・クロックモニタ共に有効
 FCKSM_CSECMD クロック・スイッチング有効、フェールセーフ・クロック・モニタ無効
 FCKSM_CSDCMD クロック・スイッチングとフェースセーフ・クロックモニタ共に無効

 

オシレータの選択(マルチプレクサの設定)
 ここでクロック源を選ぶ。この設定はOSCCONレジスタのCOSC(カレント・オシレータ)に反映される

 

 FNOSC_FRC FRCオシレータ選択
 FNOSC_FRCPLL FRC + USB PLL(FRCPLL)を選択
 FNOSC_PRI プライマリ・オシレータXT、HS、ECを選択(XT, HS, ECの決定はPOSCMODによる)
 FNOSC_PRIPLL OSCO + USB PLL(XTPLL、HSPLL、ECPLL)を選択(XT, HS, ECの決定はPOSCMODによる)
 FNOSC_SOSC セカンダリ・オシレータを選択
 FNOSC_LPRC LPFRCオシレータを選択
 FNOSC_FRCDIV FRCDIVを選択(CLKDIVのRCDIVで分周可能)

 

96MHz PLL
 USB PLLを使わない場合はOFFにしておいたほうが消費電力的に有利
 USBを使用する場合、XTPLL, HSPLL, ECPLL, FRCPLLのいずれかを使用する場合はON

 

 PLL_96MHZ_ON 96MHz PLL有効
 PLL_96MHz_OFF 96MHz PLL無効

 

USB 96MHz PLLプリスケーラ分周比の指定
 USB PLLには4MHzで入力する必要があるため、この分周比を調整して入力クロックから4MHzを
 得るようにする。

 

 PLLDIV_NODIV 分周無し(入力4MHz)
 PLLDIV_DIV2 2分周(入力8MHz)
 PLLDIV_DIV3 3分周(入力12MHz)
 PLLDIV_DIV4 4分周(入力16MHz)
 PLLDIV_DIV5 5分周(入力20MHz)
 PLLDIV_DIV6 6分周(入力24MHz)
 PLLDIV_DIV10 10分周(入力40MHz)
 PLLDIV_DIV12 12分周(入力48MHz) 

 

内外部スイッチオーバーモード
 クロック切り替え時に切り替え先が水晶発振子の場合、発振が安定するまでの遅延が発生するので
 その間FRCを使用し、その後水晶発振子に切り替える2段階スピード・スタートが行えます。

 

 IESO_OFF 2段階スピード・スタートアップ無効
 IESO_ON 2段階スピード・スタートアップ有効

 

■レジスタ

 

OSCCON オシレータ・コントロール・レジスタ

 

COSC カレント・オシレータ(読み出しのみ) CONFIG2のFNOSCで指定した値に初期化される
 現在使用されているクロック源を知ることができる

 

 7 = FRCDIV
 5 = LPRC
 4 = SOSC
 3 = OSCO + PLL(XTPLL, HSPLL, ECPLL)
 2 = OSCO(XT, HS, EC)
 1 = FRCPLL
 0 = FRC

 

NOSC 新(予備)オシレータ指定 初期値はCONFIG2のFNOSCで指定した値
 クロック・スイッチングで切り替える先のクロック源を指定する

 

 7 = FRCDIV
 5 = LPRC
 4 = SOSC
 3 = OSCO + PLL(XTPLL, HSPLL, ECPLL)
 2 = OSCO(XT, HS, EC)
 1 = FRCPLL
 0 = FRC

 

CLKLOCK(読み出しのみ) クロック、PLL変更の状況

FSCM(フェールセーフ・クロック・モニタ有効時 

 1 = クロックとPLLの変更は禁止されている

 

IOLOCK

 

LOCK PLLのロック検出(読み出しのみ)
 PLLが安定しロック状態になったか調べることができる

 

 1 = PLLはロックされた
 0 = PLLはまだロックされていない

 

CF クロック・フェイル発生状況(読み出しのみ)
 クロック。フェイルが発生したか調べることができる

 

 1 = クロック・フェイルによりFSCMが発生した
 0 = クロック・フェイルは発生していない

 

POSCEN スリープ時のプライマリ・オシレータ
 スリープ時のクロックの動作を指定する。

 

 1 = スリープ時でも動作する
 0 = スリープ時は動作しない

 

SOSCEN セカンダリ・オシレータ

 

 1 = 有効
 0 = 無効

 

OSWEN
 クロック・スイッチングを行う。クロック・スイッチングが終了すると0クリアされる

 

 1 = NOSCで指定したクロックへの切り替える
 0 = オシレータの切り替えは完了した

 

CLKDIV クロック・デバイダー・レジスタ

 

ROI Recover on Interrupt bit
 割り込み処理をクロック分周しない高速で実行するか、分周するかを指定する

 

 1 = 割り込み時はDOZEポストスケーラの分周比を1:1に変える
 0 = 割り込み時でもDOZEポストスケーラの分周比を変えない

 

DOZE DOZEポストスケーラの分周比
 DOZEで周辺機器よりもCPUクロックを低速にすることができる。
 DOZE分周後のクロックはCLKOに出力される。

 

 111 = 1:128
 110 = 1:64
 101 = 1:32
 100 = 1:16
 011 = 1:8
 010 = 1:4
 001 = 1:2
 000 = 1:1

 

DOZEN DOZEポストスケーラ
 DOZEポストスケーラの有効・無効指定

 

 1 = 有効
 0 = 無効

 

RCDIV FRCポストスケーラの分周比
 FRCの源発振8MHzを8通りに分周できる

 

 111 = 31.25 kHz (divide by 256)
 110 = 125 kHz (divide by 64)
 101 = 250 kHz (divide by 32)
 100 = 500 kHz (divide by 16)
 011 = 1 MHz (divide by 8)
 010 = 2 MHz (divide by 4)
 001 = 4 MHz (divide by 2)
 000 = 8 MHz (divide by 1)

 

CPDIV USB System Clock Select bits (postscaler select from 32 MHz clock branch)
 USB PLLの96MHzを3分周した32MHzを更に分周することができる。

 

 11 = 4 MHz (divide by 8)
 10 = 8 MHz (divide by 4)
 01 = 16 MHz (divide by 2)
 00 = 32 MHz (divide by 1)


 

設定例
 

 

○プライマリ・オシレータに外付け8MHz水晶発振子を接続し、そのままFoscを8MHzとする

 

_CONFIG2(POSCMOD_HS & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_PR & PLL_96MHz_OFF & PLLDIV_NODIV & IESO_OFF)
OSCCONbits.NOSC = 0 //FRC
OSCCONbits.POSCEN = 1 

 

○FRCオシレータ(8MHz)をそのまま8MHzで使う
○プライマリ・オシレータに外付け8MHz水晶発振子を接続。USB PLLでUSBクロック(48MHz)とFosc 32MHzを生成する。
○FRCオシレータ(8MHz)を1/2分周し、USB PLLでUSBクロック(48MHz)とFosc 32MHzを生成する。
○プライマリ・オシレータに外付け8MHz水晶発振子を接続し、そのままFoscを8MHzとする。プログラム実行中、FRCPLL(1MHz)に切り替える。

 

#include <p24fj256gb110.h>

 

_CONFIG1(WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & ICS_PGx2 & COE_OFF & BKBUG_OFF & GWRP_OFF & GCP_OFF & JTAGEN_OFF)

 

//CONFIG2
//Primary Oscillator Select:
// POSCMOD_EC EC oscillator mode selected
// POSCMOD_XT XT oscillator mode selected
// POSCMOD_HS HS oscillator mode selected
// POSCMOD_NONE Primary oscillator disabled

 

//Internal USB 3.3V Regulator Disable bit:
// DISUVREG_ON Regulator is enabled
// DISUVREG_OFF Regulator is disabled

 

//IOLOCK One-Way Set Enable bit:
// IOL1WAY_OFF Unlimited Writes To RP Registers
// IOL1WAY_ON Write RP Registers Once

 

//Primary Oscillator Output Function:
// OSCIOFNC_ON OSCO functions as port I/O (RC15)
// OSCIOFNC_OFF OSCO functions as CLKO (FOSC/2)

 

//Clock Switching and Monitor:
// FCKSM_CSECME Both Clock switching and Fail-safe Clock Monitor are enabled
// FCKSM_CSECMD Clock switching is enabled, Fail-safe Clock Monitor is disabled
// FCKSM_CSDCMD Both Clock Switching and Fail-safe Clock Monitor are disabled

 

//Oscillator Select:
// FNOSC_FRC Fast RC Oscillator (FRC)
// FNOSC_FRCPLL Fast RC oscillator with Postscaler and PLL module (FRCPLL)
// FNOSC_PRI Primary oscillator (XT, HS, EC)
// FNOSC_PRIPLL Primary oscillator (XT, HS, EC) with PLL module (XTPLL,HSPLL, ECPLL)
// FNOSC_SOSC Secondary oscillator (SOSC)
// FNOSC_LPRC Low-Power RC oscillator (LPRC)
// FNOSC_FRCDIV Fast RC oscillator with Postscaler (FRCDIV)

 

//96MHz PLL Disable:
// PLL_96MHZ_ON Enabled

 

//USB 96 MHz PLL Prescaler Select bits:
// PLLDIV_NODIV Oscillator input used directly (4MHz input)
// PLLDIV_DIV2 Oscillator input divided by 2 (8MHz input)
// PLLDIV_DIV3 Oscillator input divided by 3 (12MHz input)
// PLLDIV_DIV4 Oscillator input divided by 4 (16MHz input)
// PLLDIV_DIV5 Oscillator input divided by 5 (20MHz input)
// PLLDIV_DIV6 Oscillator input divided by 6 (24MHz input)
// PLLDIV_DIV10 Oscillator input divided by 10 (40MHz input)
// PLLDIV_DIV12 Oscillator input divided by 12 (48MHz input)

 

//Internal External Switch Over Mode:
// IESO_OFF IESO mode (Two-speed start-up)disabled
// IESO_ON IESO mode (Two-speed start-up) enabled


 

//プライマリ・オシレータに8MHz水晶発振子(HS)を接続、そのままFoscを8MHzとする
//_CONFIG2(POSCMOD_HS & DISUVREG_OFF & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_PRI & IESO_OFF)

 

//プライマリ・オシレータに8MHz水晶発振子(HS)を接続しUSB PLLを通して32MHzを得、CPDIV =1で2分周してFoscを16MHzとする
//_CONFIG2(POSCMOD_HS & DISUVREG_OFF & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_PRIPLL & PLL_96MHZ_ON & PLLDIV_DIV2 & IESO_OFF)

 

//FRC(8MHz)をRCDIV = 1で2分周し4MHzをUSB PLLに入れCPDIV = 0分周無しでFosc = 32MHzとする
//_CONFIG2(POSCMOD_NONE & DISUVREG_OFF & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_FRCPLL & PLL_96MHZ_ON & PLLDIV_NODIV & IESO_OFF)



 

//FRC + RCDIV=0 + USB PLL + CPDIV =0 Fosc = 32MHz RODIV=3 HS => REFO 1MHz
_CONFIG2(POSCMOD_HS & DISUVREG_OFF & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_FRCPLL & PLL_96MHZ_ON & PLLDIV_NODIV & IESO_OFF)
//FRC + RCDIV0 - 7 Fosc = 31.25KHz - 8MHz
//_CONFIG2(POSCMOD_NONE & DISUVREG_OFF & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_FRCDIV & IESO_OFF)
//LPRC 31KHz
//_CONFIG2(POSCMOD_NONE & DISUVREG_OFF & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_LPRC & IESO_OFF)
//SOSC 32768Hz
//_CONFIG2(POSCMOD_NONE & DISUVREG_OFF & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_SOSC & IESO_OFF)

 

int main(void) {

OSCCONbits.NOSC = 0; //New Oscillator Select 0 = FRC
OSCCONbits.POSCEN = 1; //Primary Oscillator Sleep Enable 0 = Disable during sleep mode
OSCCONbits.SOSCEN = 1; //32KHz Secondary Oscillator(SOSC) Enable 1 = enable

CLKDIVbits.ROI = 0; //Interrupt have no effection the DOZEN bit
CLKDIVbits.DOZE = 0; // CPU Peripheral Clock Select 0 = 1:1
CLKDIVbits.DOZEN = 0; // Disable DOZE

//CLKDIVbits.RCDIV = 0; //FRC Prescaler Select 0 = 8MHz
CLKDIVbits.RCDIV = 1; //FRC Prescaler Select 0 = 4MHz
//CLKDIVbits.RCDIV = 2; //FRC Prescaler Select 0 = 2MHz
//CLKDIVbits.RCDIV = 3; //FRC Prescaler Select 0 = 1MHz
//CLKDIVbits.RCDIV = 4; //FRC Prescaler Select 0 = 500KHz
//CLKDIVbits.RCDIV = 5; //FRC Prescaler Select 0 = 250KHz
//CLKDIVbits.RCDIV = 6; //FRC Prescaler Select 0 = 125KHz
//CLKDIVbits.RCDIV = 7; //FRC Prescaler Select 0 = 31.25KHz

CLKDIVbits.CPDIV = 0; //USB System Clcok Select 0 = 32MHz

  CLKDIVbits.CPDIV = 0; //USB System Clcok Select 1 = 32MHz
  CLKDIVbits.CPDIV = 0; //USB System Clcok Select 2 = 32MHz
  CLKDIVbits.CPDIV = 0; //USB System Clcok Select 3 = 32MHz

 

_T1MD = 0;
_REFOMD = 0;

AD1PCFGL = 0x1111111111111111;

/// GPIOポート入出力モード設定
TRISA = 0b0000000000000000;
TRISB = 0b0000000000000000;
TRISC = 0b0000000000000000;
TRISD = 0b0000000000000000;
TRISE = 0b0000000000000000;
TRISF = 0b0000000000000000;
TRISG = 0b0000000000000000;

 

  _REFOMD = 0: //リファレンスクロックモジュール = オン
 

//REFOCONbits.ROSEL = 0; //リファレンス・クロックのクロック源 = プライマリ・オシレータ

  REFOCONbits.ROSEL = 1; //リファレンス・クロックのクロック源 = マルチプレクサの出力

 

  //REFOCONbits.RODIV = 15; //リファレンスクロックの分周比 = 1:32768

//REFOCONbits.RODIV = 14; //リファレンスクロックの分周比 = 1:32768

  //REFOCONbits.RODIV = 13; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 12; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 11; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 10; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 9; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 8; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 7; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 6; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 5; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 4; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 3; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 2; //リファレンスクロックの分周比 = 1:32768
  //REFOCONbits.RODIV = 1; //リファレンスクロックの分周比 = 1:32768
  REFOCONbits.RODIV = 0; //リファレンスクロックの分周比 = 1:1

 

REFOCONbits.ROON = 1; //リファレンス・クロック = 有効

while (1);

}



 

(JF1VRR)