Clock Switching for 16-bit MCUs and DSCs

Last modified by Microchip on 2023/11/10 11:07

dsPIC33/PIC24 families have four sources for supplying the system clock:

  • Primary Oscillator
  • Secondary Oscillator
  • Free Running RC Oscillator
  • Low Power RC Oscillator

Simplified 16-bit System Clock

Basic Clock Tree Diagram for 16-bit Families

With a few limitations, application programs are free to switch between any of the four clock sources at any time.

Clocking switching is controlled by a combination of the FCKSM1 bit in the configuration word FOSC and the Oscillator Control Special Function register (OSCCON). When the FCKSM1 configuration bit has been set to 0, the clock can be switched by writing to OSCCON.

To limit the possibility of unintentional clock switching, OSCCON must undergo a specific unlock sequence before it can be written. The MPLAB® XC16 C compiler provides two built-in functions to unlock and write to the upper and lower bytes of OSCCON:

  • The lower byte - OSCCONL, is written with the special function __builtin_write_OSCCONL.
  • The high byte - OSCCONH, is written with the special function __builtin_write_OSCCONH.

FOSC: Oscillator Configuration Register

FOSC Oscillator Configuration Register Bit Definitions

bit 7-6

FCKSM1 and FCKSM0: CPU Clock Switching Mode Bits

1x = Clock Switching disabled, Fail-Safe Monitor disabled.
01 = Clock Switching enabled, Fail-Safe Monitor disabled.
00 = Clock Switching enabled, Fail-Safe Monitor enabled.

If FCKSM1 is set to 0, Clock Switching will be enabled.

OSCCON: Oscillator Control Register - (High byte)

OSCCON Register High Byte Bit Definitions

OSCCON: Oscillator Control Register - (Low byte)

OSCCON Register Low Byte Bit Definitions


R = Readable Bit
u = Bit is unchanged
'1' = bit is set

W = Writable Bit
x = Bit is unknown
'0' = Bit is cleared

U = Unimplemented Bit, read as '0'
-n/n = Value at POR nad BOR/Value at all other resets
-n = Value at POR reset

bit 10-8

NOSC<2:0>: New Oscillator Selection bits

111 = Fast RC Oscillator with Divide-by-N (FRCDIVN)
110 = Fast RC Oscillator with Divide-by-16 (FRCDIV16)
101 = Low Power RC Oscillator (LPRC)
100 = Secondary Oscillator (SOSC)
011 = Primary Oscillator (XTPLL,HSPLL, ECPLL)
010 = Primary Oscillator (XT, HS, EC)
001 = Fast RC Oscillator with PLL ( FRCPLL)
000 = Fast RC Oscillator (FRC)

bit 0

OSWEN: Oscillator Switch Enable bit

1 = Request oscillator switch to selection specified by the NOSC<2:0> bits.
0 = Request oscillator switch to selection specified by the NOSC<2:0> bits.

When exiting reset, the clock source set by the FOSC configuration word is copied to the Current Oscillator Selection bits (COS<2:0>) in OSCCON. The current clock source can be read at any time by the application software.

Back to top

Procedure to Switch the Clock in a 16-bit MCU or dsPIC® DSC

At a minimum, performing a clock switch requires this basic sequence:

  1. If required, read the COSC bits (OSCCON<14:12>) to determine the current oscillator source.
  2. Perform the unlock sequence to allow a write to the OSCCON register high byte.
  3. Write the appropriate value to the NOSC control bits (OSCCON<10:8>) for the new oscillator source.
  4. Perform the unlock sequence to allow a write to the low byte of OSCCON.
  5. Set the OSWEN bit to initiate the oscillator switch.

Once OWSEN is set, the MCU will begin to switch the clock. The newly selected oscillator may take several instruction cycles to become stable. OSWEN will remain high until the new clock is established as the system clock.

Sample Code to change to Low Power RC Oscillator (LPRC)

#include <xc.h>
current_clock = OSCCONbits.COSC;   // if needed

__builtin_write_OSCCONH(5);   // 5 = LPRC clock selection
__builtin_write_OSCCONL(1);   // Sets OSWEN bit

Back to top

Learn More

Back to top