Startup without peripheral libraries series
The dsPIC is one of the easier MCUs in this series to get running. Much like the PIC32MK, the default startup scripts are hidden in the compiler directory and included by default. Generally, they do not need to be touched. Almost all of the register definitions are included the standard device header file xc.h. This provides the register values both as a full register variable and as a bit fields. The compiler contains some built in functions that are required to switch clocks. These functions are documented in the compiler reference.
This example uses the internal 8MHz fast oscillator and PLL to run the system clock at 180MHz. I then set up Timer 1 and interrupts.
The steps are as follows:
- Set up the proper configuration bits for the clock and features being used – MPLAB X contains a gui to help. The PLL cannot be changed while being actively used for the clock. So, I start the system up just using the FRC oscillator, then configure the PLL, then switch the clock to the PLL.
- Next, I configure Timer1 and enable interrupts
- The sysInit function is called before the main loop
#include <xc.h> #pragma config FNOSC = FRC #pragma config IESO = OFF #pragma config POSCMD = NONE #pragma config OSCIOFNC = ON #pragma config FCKSM = CSECMD #pragma config PLLKEN = ON #pragma config WINDIS = OFF #pragma config FWDTEN = ON_SW #pragma config ICS = PGD1 #pragma config JTAGEN = OFF #pragma config DMTDIS = OFF void sysInit (void) { //----------------------------------------------------- // Configure clock - 360 MHZ -> 90 MHz fclk //----------------------------------------------------- CLKDIVbits.FRCDIV = 0; CLKDIVbits.PLLPRE = 1; PLLFBDbits.PLLFBDIV = 190; PLLDIVbits.POST1DIV = 4; PLLDIVbits.POST2DIV = 1; // Start clock switch to PLL __builtin_write_OSCCONH(0x01); __builtin_write_OSCCONL(OSCCON | 0x01); // wait for clock switch while (OSCCONbits.OSWEN != 0); // Wait for PLL to lock while (OSCCONbits.LOCK != 1); //----------------------------------------------------- // Timer 1 - use FRC @ 8MHz -> 1ms tick //----------------------------------------------------- T1CONbits.TON = 0; T1CONbits.TECS = 3; // use FRC T1CONbits.TCS = 1; // use TECS clock selection T1CONbits.TCKPS = 1; // /8 TMR1 = 0; PR1 = 1000; IPC0bits.T1IP = 2; // priority 2 IFS0bits.T1IF = 0; // clear timer1 int flag IEC0bits.T1IE = 1; // enable timer1 int T1CONbits.TON = 1; // turn on timer1 INTCON2bits.GIE = 1; // global interrupt enable }