
投稿日 2014/10/15
microchip社のDSP内蔵PIC dsPIC33FJ64GP802のクロック設定をまとめてみました。
dsPIC33FJ64GP802は名前のとおりDSPを内蔵するPICで16bit 40MIPSのCPUです。
64はプログラム用フラッシュROMの容量が64Kbであることを示します。このシリーズでは128KbのdsPIC33FJ128GP802もあります。
以前dsPIC33FJ128GP802を使用してDSP CWフィルターを作ってみました。
ただしこのときは、AD、DAコンバータにWolfmanのWM8510をI2Sを使用してつなぎました。
GPはGeneral Purposeつまり汎用を意味します。
このシリーズの特徴は何と言ってもアドバンスド・アナログです。別の言い方ではアナログ・リッチとも言えるでしょうか。
10bit 1.1Msps、または12bit 500KspsのADコンバータ
16bit 100Ksps Audio DAC
を内蔵。しかもI2S、DMAサポート。
おまけにRTCCまで内蔵しています。

dsPIC33FJ64GP802のクロック・システム
microchip社データシートより抜粋
ここではdsPIC33FJ64GP802のクロック設定をまとめました。
(クロック設定関連のすべてを網羅している訳ではありません)
上図を見ると、クロック源としてPrimary Oscillator、FRC Oscillator、LPRC Oscillator、Secondary Oscillator、Auxiliary Oscillatorの5つがあることがわかります。 Primary OscillatorとSecondary Oscillatorは外付けの水晶振動子、または発振器です。FRCとLPRC Oscillatorは内蔵発振器です。Auxiliary Oscillatorは、CPUとは独立したDAC用のクロックです。
Primary Oscillatorは水晶振動子の周波数によってXT(3 - 10MHz),HS(10 - 40MHz)があり、発振器はEC( - 64MHz)があります。
XT, HS, ECのいずれかをPLLに通したものが、XTPLL, HSPLL, ECPLLです。
FRC Oscillatorを分周後PLLに通したものがFRCPLLです。
FRC Oscillator(7.37MHz)を分周器(FRCDIV)に通して、分周したものがFRCDIVNです。独立の1/16分周器を通したものがFRCDIVV16です。分周器を通さないものがFRCです。
LPRC Oscillator(32,768Hz)の出力には分周器はなく、そのままLPRCです。LPRCはWDT等にも使われます。
Secondary Oscillator(LP)(32,768Hzなど)も分周器はなく、そのままSOSCです。Timer1のクロックをSOSCからとることもできます。
これらのクロックはマルチプレクサに入力され、コンフィグレーションビットのFNOSCとOSCCONのNOSCビットで選ぶことができるようになっています。NOSCビットによる設定はプログラム実行中に行えます。また、現在の設定はCOSCビットを見ることで知ることができます。
マルチプレクサの出力はそのままFoscであり、周辺機能のクロック(Fp)となります。
Foscは1/2分周され、DOZE分周器を通過後Fcyとなります。Fcyがプログラム実行に使われるクロックです。Foscの最高は80MHzなのでFcyは40MHz(40MIPS)となります。なかなか高速です!

dsPIC33FJ64GP802のクロック・システム PLL部分
microchip社データシートより抜粋
データシートには以下のような例が載っています。
Primary Oscillator : 10MHz XT Xtal
PLLプリスケーラ: 1/2倍 N1
PLLマルチプレクサ: 32倍 M
PLLポストスケーラ: 1/2倍 N2
Fcyの計算
Fcy = Fosc / 2 = ((XT x M) / (N1 x N2)) / 2 = ((10000000 x 32) / (2 x 2)) / 2 = 40MHz
N1は1/2 から1/33が、N2は1/2, 1/3, 1/8から選べます。
PLLの入力は0.8Mから8MHzの範囲である必要があります。
Mは2から513倍が選べますが、PLLの出力(Fvco)が100から200MHzの範囲内に入る必要があります。
Auxiliary Oscillator(AOSC)はDACで使うCPU用のクロックとは独立したクロックです。ただし、クロック源はPrimary OscillatorのXT, HS, ECのいずれかです。DAC用のクロックはFoscも選ぶことができます。Auxiliary Oscillatorは、構成が異なりますがdsPIC33FJ16GS502のような電源用GSシリーズではPWMやADコンバータのタイミングをとるために使われています。
#pragma config疑似命令によるコンフィグレーションビットの設定
#pragma config FNOSC = FRC
#pragma config IESO = OFF
#pragma config FCKSM = CSECMD
#pragma config OSCIOFNC = ON
#pragma config POSCMD = NONE
#pragma config OSCIOFNC = OFF
FNOSCはリセット時の初期クロックとして設定されますが、FCKSMが切り替え有効になっていればOSCCONのNOSCビットでプログラム実行中に切り替えることができます。なにもしなければFNOSCによる指定のままです。現在のクロックはOSCCONのCOSCビットで知ることができます。(クロックの切り替えにはアンロックシーケンスが必要)
(以下 microchip社 xc16 33FJ64GP802.html 一部)
Oscillator Mode
FNOSC = FRCInternal Fast RC (FRC)
FNOSC = FRCPLLInternal Fast RC (FRC) w/ PLL
FNOSC = PRIPrimary Oscillator (XT, HS, EC)
FNOSC = PRIPLLPrimary Oscillator (XT, HS, EC) w/ PLL
FNOSC = SOSCSecondary Oscillator (SOSC)
FNOSC = LPRCLow Power RC Oscillator (LPRC)
FNOSC = FRCDIV16Internal Fast RC (FRC) divide by 16
FNOSC = LPRCDIVNInternal Fast RC (FRC) with divide by N
Internal External Switch Over Mode
IESO = OFFStart-up device with user-selected oscillator source
IESO = ONStart-up device with FRC, then automatically switch to user-selected oscillator source when ready
Primary Oscillator Source
POSCMD = ECEC Oscillator Mode
POSCMD = XTXT Oscillator Mode
POSCMD = HSHS Oscillator Mode
POSCMD = NONEPrimary Oscillator Disabled
OSC2 Pin Function
OSCIOFNC = ONOSC2 pin has digital I/O function
OSCIOFNC = OFFOSC2 pin has clock out function
Clock Switching and Monitor
FCKSM = CSECMEBoth Clock Switching and Fail-Safe Clock Monitor are enabled
FCKSM = CSECMDClock switching is enabled, Fail-Safe Clock Monitor is disabled
FCKSM = CSDCMDBoth Clock Switching and Fail-Safe Clock Monitor are disabled
SCR OSCCONによる設定項目(一部)
OSCCONbits.COSC 現在のオシレータを知る(Read Only)
OSCCONbits.NOSC 切り替えるオシレータを決める
OSCCONbits.LPOSCEN LPOSCの有効/無効
OSCCONbits.OSWEN NOSCで指定したクロックに切り替える
CLKDIVbits.DOZE DOZEの分周比を指定する(default = 8)
CLKDIVbits.DOZEN DOZEの有効/無効
CLKDIVbits.FRCDIV FRCDIVの分周比を指定する 1 - 256 (default = 1)
CLKDIVbits.PLLPOST PLLの出力側分周比を指定する N2 = 2,4,8(default = 4)
CLKDIVbits.PLLPRE PLLの入力側分周比を指定する N2 = 1 - 33(default = 2)
PLLFBDbits.PLLDIV PLLの逓倍比 2 - 513 (default = 50)
OSCTUNE FRCの補正
ACLKCONbits.SELACLK Auxiliary Oscillatorのクロックソース(Primary/Secondary or Fosc)から選ぶ
ACLKCONbits.AOSCMD 無効、XT、 HS、 ECから選ぶ
ACLKCONbits.APSTSCLR Auxiliary Oscillatorの分周比 1 - 256 (default = 256)
ACLKCONbits.ASRCSEL Primary or Secondaryから選ぶ

dsPIC33FJ64GP802のピン・ダイヤグラム
microchip社データシートより抜粋
下記プログラムを書き込み/実行するための最低限の配線
ICSP 1ピンをPICの1ピン MCLRへ 10KΩでプルアップ
ICSP 2ピンをVccへ
ICSP 3ピンをGNDへ
ICSP 4ピンをPICの4ピン PGED1へ
ICSP 5ピンをPICの5ピン PGEC1へ
PIC 8ピン Vss GNDへ
PIC 10ピン OSC2 オシロのプローブをつなぐ
PIC 13ピン Vdd 電源+3.3Vへ
PIC 14ピン LEDのアノードへ カソードから1KΩをGNDへ
PIC 20ピン Vcap 22uFをGNDへ
今回、簡単に済ませるためPrimary Oscillatorをつないでの実験は行っていません。

最低限の配線でLEDを点滅
ソースコード
クロック設定をいろいろ変えて確認するプログラム
OSC2(Pin10)にFcy(Fosc/2)が出力されるのでオシロで観測できる。
LEDの点滅速度が変わる
LEDを点滅させるための最低限の設定しかやっていません。
OSCCONのNOSCビットによるクロック設定は行っていません。
main.c
//#pragma config FNOSC = FRC //FRC 7.37MHz
#pragma config FNOSC = FRCPLL //FRC x PLL
//#pragma config FNOSC = PRI //Primary OSC (XT, HS, EC)
//#pragma config FNOSC = PRIPLL //Primary OSC x PLL
//#pragma config FNOSC = SOSC //Secondary OSC
//#pragma config FNOSC = LPRC //Low power RC OSC (32,768Hz)
//#pragma config FNOSC = FRCDIV16 //FRC x 1/16
//#pragma config FNOSC = LPRCDIVN //FRC x 1/FRCDIV
#pragma config IESO = OFF //Start-up device with user-selected oscillator source
//#pragma config IESO = ON //Start-up device with FRC, then automatically switch to user-selected oscillator source when ready
//#pragma config POSCMD = EC //Primary OSC EC ( - 64MHz)
//#pragma config POSCMD = XT //Primary OSC XT (3 - 10MHz)
//#pragma config POSCMD = HS //Primary OSC HS (10 - 40MHz)
#pragma config POSCMD = NONE //Primary OSC disable
//#pragma config OSCIOFNC = ON //OSC2 pin has Digital I/O
#pragma config OSCIOFNC = OFF //OSC2 pin has clock out function(Fosc/2)
//#pragma config FCKSM = CSECME //Clock switing and Fail-safe Clock Monitor are enable
//#pragma config FCKSM = CSECMD //Clock switching is enable, Fail safe Clock Monitor is disable
#pragma config FCKSM = CSDCMD //Clock switing and Fail-safe Clock Monitor are disable
long i;
int main(void) {
//CLKDIVbits.ROI = 1; //Interrupts clears the DOZEN bit and the processor clock/peripheral clock ratio is set to 1:1
CLKDIVbits.ROI = 0; //Interrupts have no effect on the DOZEN bit
//CLKDIVbits.DOZE = 7; //Fcy/256
//CLKDIVbits.DOZE = 6; //Fcy/64
//CLKDIVbits.DOZE = 5; //Fcy/32
//CLKDIVbits.DOZE = 4; //Fcy/16
//CLKDIVbits.DOZE = 3; //Fcy/8(default)
//CLKDIVbits.DOZE = 2; //Fcy/4
//CLKDIVbits.DOZE = 1; //Fcy/2
CLKDIVbits.DOZE = 0; //Fcy/1
CLKDIVbits.DOZEN = 0; //disable DOZE
//CLKDIVbits.DOZEN = 1; //enable DOZE
//CLKDIVbits.FRCDIV = 7; //FRC/256
//CLKDIVbits.FRCDIV = 6; //FRC/64
//CLKDIVbits.FRCDIV = 5; //FRC/32
//CLKDIVbits.FRCDIV = 4; //FRC/168
//CLKDIVbits.FRCDIV = 3; //FRC/8
//CLKDIVbits.FRCDIV = 2; //FRC/4
//CLKDIVbits.FRCDIV = 1; //FRC/2
CLKDIVbits.FRCDIV = 0; //FRC/1(default)
//CLKDIVbits.PLLPRE = n; //input/(n + 2) n = 0 - 31
//CLKDIVbits.PLLPRE = 31; //input/33
//CLKDIVbits.PLLPRE = 1; //input/3
CLKDIVbits.PLLPRE = 0; //input/2(default)
//CLKDIVbits.PLLPOST = 3; //output/8
CLKDIVbits.PLLPOST = 1; //output/4(default)
//CLKDIVbits.PLLPOST = 0; //output/2
//PLLFBDbits.PLLDIV = n; //x (n + 2) n = 0 - 511
//PLLFBDbits.PLLDIV = 511; //x 513
PLLFBDbits.PLLDIV = 48; //x 50(default)
//PLLFBDbits.PLLDIV = 1; //x 3
//PLLFBDbits.PLLDIV = 0; //x 2
AD1PCFGL = 0xFFFF; //All Digital
TRISBbits.TRISB5 = 0; //RB5(LED)
/*
* Fcy = ((OSC x M) / (N1 x N2)) / 2 = ((OSC x PLLDIV) / (PLLPRE x PLLPOST)) / 2
* e.g. OSC = FRC(7.37MHz) PLL50逓倍 PLLプリスケーラ 2分周 PLLポストスケーラ 4分周
* Fcy = ((FRC / FRCDIV x M) / (N1 x N2)) / 2 = ((FRC / FRCDIV x PLLDIV) / (PLLPRE x PLLPOST)) / 2
* FNOSC = FRCPLL
* FRCDIV = 1
* PLLDIV = 50
* PLLPRE = 2
* PLLPOST = 4
* Fcy = ((7.37 / 1 x 50) / (2 x 4)) / 2 = 23.03MHz
* FcyはさらにDOZEで分周できる
*/
while (1) {
LATBbits.LATB5 = 1; //LED ON
for (i = 0; i < 100000; i++) {
}
LATBbits.LATB5 = 0; //LED OFF
for (i = 0; i < 100000; i++) {
}
};
}
(JF1VRR)