PIC32 Oscillator - Clock Switching
Clock Switching
With few limitations, applications are free to switch between any of the following clock sources at run-time:
- Primary Oscillator (POSC)
- Secondary Oscillator (SOSC)
- Fast RC Oscillator (FRC)
- Low Power RC Oscillator (LPRC)
To limit the possible side effects that could result from this flexibility, PIC32 devices have a safeguard lock built into the switch process.
Clock switching is disabled by default. You can enable it with the clock switching and monitor (FCKSM) setting. See the example code below.
#pragma config FCKSM = CSECME
// clock switching enabled and clock monitor disabled
#pragma config FCKSM = CSECMD
// clock switching disabled and clock monitor disabled (default)
#pragma config FCKSM = CSDCMD
The oscillator switching sequence is as follows:
- Determine the current clock source (optional).
- Perform the unlock sequence to allow a write to the Oscillator Configuration register (OSCCON).
- Configure the New Oscillator (NOSC) setting with the clock source you want to switch to.
- Initiate the oscillator switch by setting the Oscillator Switch Enable (OSWEN) bit.
- Perform the lock sequence to prevent an unintended clock switch (optional).
The following example code shows how to perform a clock switch using MPLAB® Harmony functions.
// Assume the current oscillator is the Primary Oscillator with the PLL and we want to
// change the PLL settings. We will need to switch to another non-PLL clock source
// (FRC in this case) to perform this switch.
// variable to hold the state of the current clock source
OSC_SYS_TYPE currOsc;
// assign FRC as the oscillator we want to switch to
OSC_SYS_TYPE newOsc=OSC_FRC;
// assign the current clock source to currOsc
currOsc = PLIB_OSC_CurrentSysClockGet(OSC_ID_0);
// if the current osc and new osc are different, perform the switch
if(currOsc != newOsc)
{
// unlocks the Oscillator Control register,
// configures the new oscillator setting to Primary Oscillator
// and initiates the oscillator switch
PLIB_OSC_SysClockSelect ( OSC_ID_0, newOsc );
// returns true when switch is complete
while (!PLIB_OSC_ClockSwitchingIsComplete(OSC_ID_0));
}
// change the PLL multiplier to 24
PLIB_OSC_SysPLLMultiplierSelect(OSC_ID_0, 24);
// change output divide to 256
PLIB_OSC_SysPLLOutputDivisorSet(OSC_ID_0, OSC_SYSPLL_OUT_DIV_256);
// Switch clock source back to the
// primary osc now using new PLL values
PLIB_OSC_SysClockSelect(OSC_ID_0, OSC_PRIMARY_WITH_PLL);
// returns true when switch is complete
while (!PLIB_OSC_ClockSwitchingIsComplete(OSC_ID_0));
Detailed Overview
For more detail on the Clock Switching feature, please review the oscillator family reference manual chapter for that device, for example:
- Section 6. Oscillators (PIC32MX795F512L)
- Section 42. Oscillators with Enhanced PLL (PIC32MZ2048EFG100)
The device datasheet should then be consulted to verify the specific features implemented in that device.