Tag: XC16 compiler tutorial

dsPIC/PIC24 Configuration Bits and Oscillator Settings(using XC16 and MPLAB X )

Setting configuration bits in dsPIC/PIC24 can be done with the help of the utility given in MPLAB X which will make our life a lot easier. Hope this post will help on how to bring in the configuration bits window (configuration window). Setting configuration bits in PIC24 is much similar to PIC18 but for dsPIC we need to do some reading.

These documents might be useful for setting configuration bits

The last 2 items in the list above are pretty much the same, but still gives a good idea. As mentioned above, setting PIC24 configuration bits are much similar to PIC18 but not the same. I am using dsPIC33FJ128GP202. Getting into the config_docs folder (%XC16 install folder%\docs\config_docs) there will be html pages containing the configuration bit name and comments in their respective device page. Please read it for the device that you will be using.

In 8-bit PIC’s the operating frequency Fcy = Fosc/4. But in 16-bit PIC’s (dsPIC and PIC24) Fcy = Fosc/2.

 

Setting Configuration Bits

But there are more than just that. To set the Fosc it is depended on what you have in configuration bits, PLL and more (which I’ll let you know below) I will show only the changes I made in the configuration bits related to clock settings.

// FOSCSEL #pragma config FNOSC = PRIPLL #pragma config IESO = ON // FOSC #pragma config POSCMD = HS #pragma config OSCIOFNC = OFF #pragma config IOL1WAY = ON #pragma config FCKSM = CSDCMD

Definitions of those names can be found in the html page in config_docs folder. IESO bit is turned on and if you read the datasheet you’ll know why. I am suing 20MHz crystal oscillator (that’s what I was able to find around quick).

 

Oscillator Configuration

 

Back to settting up Fosc in dsPIC [NOT APPLICABLE TO PIC24]

image

And to select the M, N1 and N2 we have to follow this another set of rules

image

 

Right now I have 20MHz crystal. So lets see how I’m going to set it up to get 80MHz off of it.

N1 and N2 does division.

M does multiplication.

N1 = 4

20MHz/4 = 5MHz

M = 32

5MHz * 32 = 160MHz

N2 = 2

160MHz/2 = 80MHz

which will become our Fosc = 80MHz.

Now to write the code. Here is how the register settings will look like

image

image

image

 

So create a function called SetupClock() and this is how the settings will be set.

 

Note: 
1) N1 and M has an offset of 2

2) Please refer Datasheet

void SetupClock() { //Setting N1 to 4 (N1 = n+2) CLKDIVbits.PLLPRE0 = 0; CLKDIVbits.PLLPRE1 = 1; CLKDIVbits.PLLPRE2 = 0; CLKDIVbits.PLLPRE3 = 0; CLKDIVbits.PLLPRE4 = 0; //Setting M to 32 (M = m+2) PLLFBDbits.PLLDIV0 = 0; PLLFBDbits.PLLDIV1 = 1; PLLFBDbits.PLLDIV2 = 1; PLLFBDbits.PLLDIV3 = 1; PLLFBDbits.PLLDIV4 = 1; PLLFBDbits.PLLDIV5 = 0; PLLFBDbits.PLLDIV6 = 0; PLLFBDbits.PLLDIV7 = 0; PLLFBDbits.PLLDIV8 = 0; //Setting N2 to 2 CLKDIVbits.PLLPOST0 = 0; CLKDIVbits.PLLPOST1 = 0; }

 

Test Firmware

config.c

// DSPIC33FJ128GP202 Configuration Bit Settings #include <xc.h> // FBS #pragma config BWRP = WRPROTECT_OFF #pragma config BSS = NO_FLASH #pragma config RBS = NO_RAM // FSS #pragma config SWRP = WRPROTECT_OFF #pragma config SSS = NO_FLASH #pragma config RSS = NO_RAM // FGS #pragma config GWRP = OFF #pragma config GSS = OFF // FOSCSEL #pragma config FNOSC = PRIPLL #pragma config IESO = ON // FOSC #pragma config POSCMD = HS #pragma config OSCIOFNC = OFF #pragma config IOL1WAY = ON #pragma config FCKSM = CSDCMD // FWDT #pragma config WDTPOST = PS32768 #pragma config WDTPRE = PR128 #pragma config WINDIS = OFF #pragma config FWDTEN = OFF // FPOR #pragma config FPWRT = PWR128 #pragma config ALTI2C = OFF // FICD #pragma config ICS = PGD1 #pragma config JTAGEN = OFF

dsPICtest.c

/* * File: dsPICtest.c * Author: Singular Engineer * * Created on February 5, 2014, 9:18 PM */ #define FCY 40000000ULL //Fcy = (Fosc/2) Fosc = 80MHz #include <xc.h> #include "config.h" #include <libpic30.h> /* * */ int i = 0; void Delay1Second(void); void SetupClock(void); int main(int argc, char** argv) { SetupClock(); TRISBbits.TRISB0 = 0; while(1) { LATBbits.LATB0 = 1; Delay1Second(); LATBbits.LATB0 = 0; Delay1Second(); } return 0; } void Delay1Second() { for(i=0;i<100;i++) { __delay_ms(10); } } void SetupClock() { //Setting N1 to 4 (N1 = n+2) CLKDIVbits.PLLPRE0 = 0; CLKDIVbits.PLLPRE1 = 1; CLKDIVbits.PLLPRE2 = 0; CLKDIVbits.PLLPRE3 = 0; CLKDIVbits.PLLPRE4 = 0; //Setting M to 32 (M = m+2) PLLFBDbits.PLLDIV0 = 0; PLLFBDbits.PLLDIV1 = 1; PLLFBDbits.PLLDIV2 = 1; PLLFBDbits.PLLDIV3 = 1; PLLFBDbits.PLLDIV4 = 1; PLLFBDbits.PLLDIV5 = 0; PLLFBDbits.PLLDIV6 = 0; PLLFBDbits.PLLDIV7 = 0; PLLFBDbits.PLLDIV8 = 0; //Setting N2 to 2 CLKDIVbits.PLLPOST0 = 0; CLKDIVbits.PLLPOST1 = 0; }