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
- Configuration Document located in your local drive when you install the compiler (%XC16 install folder%\docs\config_docs)
- http://ww1.microchip.com/downloads/en/DeviceDoc/70580C.pdf
- Device datasheet that will be used
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]
And to select the M, N1 and N2 we have to follow this another set of rules
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
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; }