dsPIC33FJ64GP802のクロック設定

投稿日 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_1.jpg

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_2.jpg

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_3.jpg

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をつないでの実験は行っていません。

dsPIC33fj64gp802_4.jpg

最低限の配線で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)