16-Bit Oscillator System
The 16-bit PIC® MCU and dsPIC® oscillator system is highly configurable. The many different clock options allow you to maximize device performance while controlling power consumption on other parts of the device. This section provides an overview of the various oscillator modes as well as C-code examples used to configure these modes.
Advanced operating modes such as Two-Speed Startup, Fail-Safe Clock Monitoring (FSCM), and Clock Switching are also covered.
More detailed information may be found in one of the family-specific Oscillator family reference manuals:
Please refer to your MCU datasheet for the specific oscillator system implemented on that device.
Overview
The 16-bit PIC® MCU and dsPIC® digital signal controllers (DSCs) oscillator system has multiple internal clocks that are derived from internal or external clock sources. Some of these clock sources have Phase-Locked Loops (PLLs), programmable output divider, and/or an input divider, to scale the input frequency to suit the application.
The CPU clock source can be changed on-the-fly by software. Registers controlling these clocks are locked by hardware to protect against erroneous clock switching. They must be unlocked by a series of writes before the software can perform a clock switch.
A Fail-Safe Clock Monitor (FSCM) mechanism detects clock failure and permits safe application recovery or shutdown by using one of the on-chip fast RC oscillators.
The default (hardware power-up) CPU clock source and initial configuration are determined by configuration bit settings. Additional configuration may be set at run-time.
Also, one or more MCU pins are available for outputting the instruction clock and/or a scaled primary oscillator clock signal.
CPU Clocking Scheme
The system clock source (FOSC) may be selected from one of 5 sources:
- Primary Oscillator (POSC) on the OSC1 and OSC2 pins
- Internal Phase-Locked Loop (PLL)
- Internal Fast RC Oscillator (FRC)
- Internal Low-Power RC Oscillator (LPRC)
- Secondary Oscillator (SOSC) on the SOSCI and SOSCO pins
This clock is then divided by 2 to produce the internal peripheral clock (FP) and core CPU instruction cycle clock, FCY as shown:
FCY may optionally be further divided down using DOZE mode settings, which enables power savings while continuing to run the peripherals at FOSC / 2.
Primary Oscillator (POSC)
External Clock and Oscillator Modes
The Primary Oscillator (POSC) uses the OSC1 and OSC2 pins. POSC can be configured for an external clock input (EC mode), or an external crystal or resonator (XT or HS modes).
The clock frequencies associated with these modes are device dependent. Please see the specific device data sheet for details.
Code Example:
The following MPLAB® XC16 compiler code example enables the Primary Oscillator as the default system clock and selects HS oscillator mode (supporting an external crystal) for a PIC24FJ128GA010 MCU:
#include <xc.h>
#pragma config FNOSC PRI // Enable primary oscillator (XT, HS, EC)
#pragma config POSCMOD HS // HS oscillator mode selected
int main(void)
{
...
}
Fast RC Oscillator (FRC/LPFRC)
The FRC Oscillator is a fast (7.37 or 8 MHz nominal), user-trimmable, internal-RC oscillator. The output can drive the PLL or be divided using the programmable RCDIV bits.
Some devices contain an additional 500kHz Low-Power FRC (LPFRC) oscillator which enables lower-power consumption as compared with standard FRC oscillator.
The CLKDIV register RCDIV bits configure a selectable output divider that allows the choice of a lower clock frequency from seven different options plus, the direct FRC/LPFRC frequency output.
The FRC Oscillator Tuning register, OSCTUN, allows the user to fine tune the FRC/LPFRC Oscillator over a range of approximately ±12% (typical). Each bit increment or decrement changes the factory calibrated frequency of the FRC/LPFRC Oscillator by a fixed amount.
Code Example:
The following MPLAB® XC16 compiler code example enables FRCDIV as the default system clock source and sets the RCDIV divider bits to divide-by-16 at run-time for a PIC24FJ128GA010 MCU:
#include <xc.h>
#pragma config FNOSC FRCDIV // Enable FRCDIV as system clock source
// default RCDIV setting sets FRC @ 4 MHz providing 4 MHz sys clk (2 MIPs)
int main(void)
{
CLKDIVbits.RCDIV = 4; // enable divide-by-16 setting
// sets FRC @ 0.5 MHz providing 0.5 MHz sys clk (0.25 MIPs)
while(1);
}
Due to specified FRC accuracy, the FRC Oscillator modes may not meet the minimum frequency accuracy requirements for serial communications (such as UART and USB). Refer to the product family data sheet for more information about the FRC accuracy.
Low Power RC (LPRC) Oscillator
The LPRC Oscillator is separate from the Fast RC Oscillator. It oscillates at a nominal frequency of 31.25 kHz. The LPRC Oscillator is the clock source for the Power-up Timer (PWRT), Watchdog Timer (WDT), Fail-Safe Clock Monitor (FSCM) and Phase-Locked Loop (PLL) reference circuits. It may also be used to provide a low-frequency clock source option for the device in those applications where power consumption is critical and timing accuracy is not required.
Code Example:
The following MPLAB® XC16 code example enables the LPRC as the default system clock for a PIC24FJ128GA010 MCU:
#include <xc.h>
#pragma config FNOSC = LPRC // default System clock = LPRC
int main(void)
{
...
}
Secondary Oscillator (SOSC)
The Secondary Oscillator (SOSC) is designed specifically for low-power operation with an external 32 to 100 KHz crystal. The oscillator is connected to the SOSCO and SOSCI device pins and serves as a secondary crystal clock source for low-power operation. It can also drive Timer1 and/or the Real-Time Clock and Calendar (RTCC) module for Real-Time Clock (RTC) applications.
Code Example:
The following MPLAB® XC16 complier code example enables the SOSC as the default system clock for a PIC24FJ128GA010 MCU:
#include <xc.h>
#pragma config FNOSC = SOSC // default System clock = SOSC
int main(void)
{
...
}
System PLL (PLL Block)
Overview
The system clock for all 16-bit PIC® MCU and dsPIC® MCUs includes a frequency multiplier branch built around a PLL (Phase-Locked Loop). Depending on the device variant, the following PLL types are implemented:
- 4x PLL (32MHz) (PIC24F GA, GC, KA, KL, KM)
- 24x PLL (96MHz) (PIC24F GB, DA)
- 80 MHz PLL (dsPIC33F/PIC24H)
- 140 MHz PLL (dsPIC33E/PIC24E)
The System PLL can use the Fast RC (FRC) or Primary (POSC) Oscillator as the input. The input is indirectly determined by the System Clock setting (FNOSC bits).
For some of these blocks, certain PLL parameters may be set at build-time via configuration bits, as well as at run-time via SFR register modification.
4x PLL (PIC24F GA, GC, KA, KL, KM)
This PLL provides a fixed 4x multiplier, which can be used with XT and EC Primary Oscillators and the FRC Oscillator.
The PLL accepts any frequency input from approximately 3.5 MHz to 8 MHz.
Whenever the clock source of the PLL is changed, the PLL ready timer is reset to allow the PLL to synchronize to the new clock source. After the ready timer has counted the required time, the PLL output is ready for use. Application code can monitor the PLL Lock flag (OSCCON<5>) to determine when the PLL output frequency is locked.
Code Example:
The following MPLAB® XC16 Compiler code example enables the 4x PLL with Fast RC Oscillator source as the default system clock for a PIC24FJ128GA010 MCU. The default RCDIV setting (divide-by-2) sets FRC @ 4 MHz providing a 16 MHz system clock (8 MIPs):
#include <xc.h>
#pragma config FNOSC = FRCPLL // default System clock = Fast RC Osc. with 4x PLL module
// default RCDIV setting sets FRC at 4 MHz providing 16 MHz sys clk (8 MIPs)
int main(void)
{
...
}
24x (96 MHz) PLL (PIC24F GB, DA)
For PIC24F devices with USB features (such as the PIC24FJ256GB110 family) and graphics controller features (such as the PIC24FJ256DA210 family), a 96 MHz PLL block is implemented to generate the stable 48 MHz clock required for full-speed USB operation, a programmable clock output for the graphics controller module and the system clock from the same oscillator source.
The 96 MHz PLL block requires a 4 MHz input signal; it uses this to generate a 96 MHz signal from a fixed, 24 x PLL. This is, in turn, divided into three branches. The first branch generates the USB clock, the second branch generates the system clock and the third branch generates the graphics clock.
The 96 MHz PLL prescaler does not automatically sense the incoming oscillator frequency. The user must manually configure the PLL divider to generate the required 4 MHz output, using the PLLDIV<2:0> Configuration bits (Configuration Word 2 <14:12> in most devices).
Code Example:
The following MPLAB® XC16 code example enables the 96 MHz PLL with Primary OSC (HS) as the default system clock for a PIC24FJ256GB110 USB MCU. The MCU has an external 12 MHz crystal on OSC1/OSC2. With the default CPDIV<1:0> settings, this produces a 32 MHz system clock (16 MIPs operation).
#include <xc.h>
#pragma config FNOSC = PRIPLL // default System clock = Primary OSC with 24x PLL module
#pragma config POSCMOD = HS // configure POSC for 12 MHz crystal input
#pragma config PLLDIV = DIV3 // divide POSC to get 4 MHz input to PLL
#pragma config PLL_96MHZ = ON // enable the 96MHz PLL
int main(void)
{
...
}
80 MHz PLL (dsPIC33F/PIC24H)
dsPIC33F and PIC24H devices contain a programmable PLL module which can be used to provide an FOSC = 80 MHz (max.) system clock, enabling an FCY = 40 MIPs (max.) operation.
The 80 MHz PLL block requires a 0.8-8 MHz input signal; it uses this to generate a 100-200 MHz output signal which is then scaled to provide an 80 MHz (max.) system clock.
For a proper PLL operation, the Phase Frequency Detector (PFD) input frequency, FREF, and Voltage Controlled Oscillator (VCO) output frequency, FVCO, must meet the following requirements at all times:
- FREF must be in the range of 0.8-8 MHz
- FVCO must be in the range of 100-200 MHz
PLL register default settings on POR place certain constraints on application code for oscillator configuration. These are discussed below.
PLL Configuration:
PLL frequency control is achieved via dynamic SFR register modification:
- CLKDIV<PLLPRE4:0> - specify the input frequency divider ratio (N1)
- CLKDIV<PLLPOST1:0> - specify the output frequency divider ratio (N2)
- PLLFBD<PLLDIV8:0> - specify the divider ratio (M)
The following equations define the relations between FIN, FREF, FVCO, FOSC:
(1)Where
N1 = PLLPRE+2
N2 = 2 x (PLLPOST + 1)
M = PLLDIV + 2
Input Clock Limitation at Start-up:
Default POR values of PLLPRE, PLLPOST and PLLDIV, set N1=2, N2=4 and M=50 respectively.
Given these reset values, the following relations are active at POR:
(2)Given the preceding equations, the FIN to the PLL module must be limited to 4 MHz < FIN < 8 MHz to comply with the FVCO requirement (100 MHz < FVCO < 200 MHz), if the default values of PLLPRE, PLLPOST, and PLLDIV are used.
To use a PLL when the input frequency is not within the 4-8 MHz range, you must follow this process:
1. Power-up the device with the Internal FRC Oscillator, or the POSC, without a PLL.
2. Change PLLDIV, PLLPRE, and PLLPOST bit values, based on the input frequency, to meet these PLL requirements:
- FREF must be in the range of 0.8-8.0 MHz
- FVCO must be in the range of 100-200 MHz
3. Switch the clock to a PLL mode in software.
PLL Lock Status:
Whenever the PLL input frequency, the PLL prescaler, or the PLL feedback divisor, is changed, the PLL requires a finite amount of time (TLOCK) to synchronize to the new settings.
TLOCK is applied when the PLL is selected as the clock source at a POR, or during a clock switching operation. The value of TLOCK is relative to the time at which the clock is available to the PLL input. For example, with the POSC, TLOCK starts after the OST delay. Refer to the specific device data sheet for information about typical TLOCK values.
The LOCK bit in the Oscillator Control register (OSCCON<5>) is a read-only Status bit that indicates the lock status of the PLL. The LOCK bit is cleared at a POR, and on a clock switch operation, if the PLL is selected as the destination clock source. The LOCK bit remains clear when any clock source that is not using a PLL is selected. After a clock switch event in which a PLL is enabled, it is a good practice to wait for the LOCK bit to be set before executing other code.
Code Example: Configure dsPIC33F for 40 MIPs Operation with POSC = 8 MHz XTAL
In this configuration, the POSC input frequency (FIN) complies with the default PLL divisor settings to meet the FVCO requirements (4 MHz < FIN < 8 MHz), however, it is unable to meet the user requirements (FCY = FOSC/2 = (6.25 x FIN)/2 = 25 MIPs) with these settings.
We will need to enable a non-PLL oscillator type on POR (ex. 7.37 MHz FRC), perform the correct PLL adjustments in our application code, then initiate a clock switch to the PLL:
#include <xc.h>
#pragma config FNOSC = FRC // select internal FRC at POR
#pragma config FCKSM = CSECMD // enable clock switching
#pragma config POSCMD = XT // configure POSC for XT mode
int main(void)
{
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD=41; // M = 43
CLKDIVbits.PLLPOST = 0; // N2 = 2
CLKDIVbits.PLLPRE = 0; // N1 = 2
// Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0b011)
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC != 0b011);
// Wait for PLL to lock
while(OSCCONbits.LOCK != 1);
...
}
The PLL Prescaler (PLLPRE) and PLL Feedback Divisor (PLLDIV) bits should not be changed when operating in PLL mode. You must clock switch to a non-PLL mode (e.g., Internal FRC) to make the necessary changes and then clock switch back to the PLL mode.
140 MHz PLL (dsPIC33E/PIC24E)
dsPIC33E and PIC24E devices contain a programmable PLL module which can be used to provide an FOSC = 140 MHz (max.) system clock, enabling an FCY = 70 MIPs (max.) operation at 85 degrees C.
The 140 MHz PLL block requires a 0.8-8 MHz input signal; it uses this to generate a 120-340 MHz output signal which is then scaled to provide an 140 MHz (max.) system clock.
For a proper PLL operation, the Phase Frequency Detector (PFD) input frequency, FREF, and Voltage Controlled Oscillator (VCO) output frequency, FVCO, must meet the following requirements at all times:
- FREF must be in the range of 0.8-8 MHz
- FVCO must be in the range of 120-340 MHz
- FOSC must be in the range of 15-140 MHz @ 85 degrees C
PLL register default settings on POR place certain constraints on application code for oscillator configuration. These are discussed below.
PLL Configuration:
PLL frequency control is achieved via dynamic SFR register modification:
- CLKDIV<PLLPRE4:0> - specify the input frequency divider ratio (N1)
- CLKDIV<PLLPOST1:0> - specify the output frequency divider ratio (N2)
- PLLFBD<PLLDIV8:0> - specify the divider ratio (M)
The following equations define the relations between FIN, FREF, FVCO, FOSC:
(3)Where
N1 = PLLPRE+2
N2 = 2 x (PLLPOST + 1)
M = PLLDIV + 2
Input Clock Limitation at Start-up:
Default POR values of PLLPRE, PLLPOST and PLLDIV, set N1=2, N2=4 and M=50 respectively.
Given these reset values, the following relations are active at POR:
(4)Given the preceding equations, the FIN to the PLL module must be limited to 4 MHz < FIN < 8 MHz to comply with the FVCO requirement (100 MHz < FVCO < 200 MHz), if the default values of PLLPRE, PLLPOST, and PLLDIV are used.
To use a PLL when the input frequency is not within the 4-8 MHz range, you must follow this process:
1. Power-up the device with the Internal FRC Oscillator, or the POSC, without a PLL.
2. Change PLLDIV, PLLPRE, and PLLPOST bit values, based on the input frequency, to meet these PLL requirements:
- FREF must be in the range of 0.8-8.0 MHz
- FVCO must be in the range of 100-200 MHz
3. Switch the clock to a PLL mode in software.
PLL Lock Status:
Whenever the PLL input frequency, the PLL prescaler, or the PLL feedback divisor, is changed, the PLL requires a finite amount of time (TLOCK) to synchronize to the new settings.
TLOCK is applied when the PLL is selected as the clock source at a POR, or during a clock switching operation. The value of TLOCK is relative to the time at which the clock is available to the PLL input. For example, with the POSC, TLOCK starts after the OST delay. Refer to the specific device data sheet for information about typical TLOCK values.
The LOCK bit in the Oscillator Control register (OSCCON<5>) is a read-only Status bit that indicates the lock status of the PLL. The LOCK bit is cleared at a POR, and on a clock switch operation, if the PLL is selected as the destination clock source. The LOCK bit remains clear when any clock source that is not using a PLL is selected. After a clock switch event in which a PLL is enabled, it is a good practice to wait for the LOCK bit to be set before executing other code.
Code Example: Configure dsPIC33E for 70 MIPs Operation with POSC = 8 MHz XTAL
In this configuration, the POSC input frequency (FIN) complies with the default PLL divisor settings to meet the FVCO requirements (4.8 MHz < FIN < 13.6 MHz), however, it is unable to meet the user requirements (FCY = FOSC/2 = (6.25 x FIN)/2 = 25 MIPs) with these settings.
We will need to enable a non-PLL oscillator type on POR (ex. 7.37 MHz FRC), perform the correct PLL adjustments in our application code, then initiate a clock switch to the PLL:
#include <xc.h>
#pragma config FNOSC = FRC // select internal FRC at POR
#pragma config FCKSM = CSECMD // enable clock switching
#pragma config POSCMD = XT // configure POSC for XT mode
int main(void)
{
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD=74; // M = 76
CLKDIVbits.PLLPOST = 0; // N2 = 2
CLKDIVbits.PLLPRE = 0; // N1 = 2
// Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0b011)
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC != 0b011);
// Wait for PLL to lock
while(OSCCONbits.LOCK != 1);
...
}
The PLL Prescaler (PLLPRE) and PLL Feedback Divisor (PLLDIV) bits should not be changed when operating in PLL mode. You must clock switch to a non-PLL mode (e.g., Internal FRC) to make the necessary changes and then clock switch back to the PLL mode.
Auxiliary Oscillator & PLL
Overview
The Auxiliary Oscillator and PLL Block (ACLK) is used by the Universal Serial Bus (USB) module, which needs to operate at a frequency unrelated to the system clock.
This oscillator is available on select dsPIC33E/PIC24E devices having a USB module.
Detailed Block Diagram
The Auxiliary Oscillator and PLL Block consists of the following sub-systems:
- Auxiliary Oscillator
- Auxiliary PLL Clock Source Select
- Auxiliary PLL
Auxiliary Oscillator
The ACLK is used by the Universal Serial Bus (USB) module, which needs to operate at a frequency unrelated to the system clock. The auxiliary oscillator can use one of the following as its clock source:
- Crystal (XT): Crystal and ceramic resonators in the range of 3.5 MHz - 10 MHz
- High-Speed Crystal (HS): Crystals in the range of 10 MHz - 40 MHz; the external crystal is connected to the SOSCI and SOSCO pins
- External Clock (EC): External clock signal up to 60 MHz; the external clock signal is directly applied to the SOSCI pin
Enabling the Auxiliary Oscillator:
To enable the Auxiliary Oscillator mode, the Enable Auxiliary PLL bit (ENAPLL) must be set in the Auxiliary Clock control register (ACLKCONx<15>). The Auxiliary Oscillator Mode bits (AOSCMD<1:0>) allow four oscillator mode settings, as listed in the following table:
By default, the USB module is clocked by the primary oscillator (POSC) with PLL.
Auxiliary PLL Clock Source
The desired reference clock source for the auxiliary PLL can be selected by setting the appropriate clock source select bits in the Auxiliary Clock Control Register 1 (ACLKCONx).
Set the Auxiliary Reference Clock Select bit (ASRCSEL) to use the primary oscillator as the clock source or clear this bit to use the auxiliary oscillator as the clock source.
Set the FRC Select bit (FRCSEL) to use the FRC as the clock source, or clear this bit to use the auxiliary or primary oscillator selected by the ASRCSEL bit as the clock source.
Auxiliary PLL
For operation of the APLL, the Auxiliary Phase Frequency Detector (APFD) input frequency and the Auxiliary Voltage Controlled Oscillator (AVCO) output frequency must meet the following requirements:
- The APFD input frequency (AFPLLI) must be in the range of 3 MHz - 5.5 MHz
- The AVCO output frequency (AFSYS) must be in the range of 60 MHz - 120 MHz
The APLL Phase Detector Input Divider bits (APLLPRE<2:0>) in the Auxiliary Clock Control Register 1 (ACLKCONx<2:0>) specify the input divider ratio (N1), which is used to scale down the Auxiliary PLL Input (AFIN) clock to meet the APFD input frequency range of 3 MHz to 5.5 MHz.
The Auxiliary PLL Feedback Divisor bits (APLLDIV<2:0>) in the Auxiliary Clock Control Register 2 (ACLKDOVx<2:0>) specify the divider ratio (M), which scales down the AVCO frequency (AFSYS) for feedback to the APFD. The AVCO frequency (AFSYS) is M times the APFD input frequency (AFPLLI).
The APLL VCO Output Divider Select bits (APLLPOST<2:0>) in the Auxiliary Clock Control Register 1 (ACLKCONx<7:5>) specify the divider ratio (N2).
The correct combination of the APLL Phase Detector Input Divider bits (APLLPRE<2:0>), the Auxiliary PLL Feedback Divisor bits (APLLDIV<2:0>), and the APLL VCO Output Divider bits (APLLPOST<2:0>) will provide the 48 MHz Auxiliary Clock (ACLK) frequency needed by the USB module.
Set the Select Clock Source to Auxiliary Clock Divider bit (SELACLK) in the Auxiliary Clock Control Register 1 (ACLKCONx) to select the auxiliary PLL or oscillators to provide the clock source for the auxiliary clock divider.
Clearing the SELACLK bit will cause the primary PLL output to act as the clock source to the auxiliary clock divider.
AFSYS and ACLK Calculation:
The following equations define the relations between the Auxiliary PLL Input (AFIN) clock frequency and the Auxiliary VCO (AVCO) and Auxiliary Clock (ACLK) frequencies.
(5)Where
N1 = APLLPRE + 1
N2 = APLLPOST + 1
M = APLLDIV + 15
When APLLDIV<2:0> = 111, substitute (APLLDIV + 15) with (APLLDIV + 18) in the above equation.
Code Example: Configure APLL with Auxiliary Oscillator with an 8 MHz XTAL
In this configuration, the 8 MHz XTAL is connected to SOSCI/SOSCO pins. The application firmware must perform the following steps:
- Clear the ASRCSEL bit to choose the auxiliary oscillator as the clock source for the APLL.
- Clear the FRCSEL bit to choose the auxiliary oscillator at the clock source for the APLL.
- Set the SELACLK bit to choose the auxiliary PLL or oscillators to provide the source clock for the auxiliary clock divider.
- Follow these steps to configure the APLL Phase Detector Input Divider bits (APLLPRE<2:0>), the Auxiliary PLL feedback Divisor bits (APLLDIV<2:0>) and the APLL VCO Output Divider bits (APLLPOST<2:0>) to set up the APLL for a 48 MHz ACLK (used by the USB module) using an 8 MHz auxiliary oscillator:
- Select the APLL VCO output divider to meet the AVCO output frequency requirement (60 MHz < AFSYS < 120 MHz).
- Select an APLL VCO output divider ratio of N2 = 2
- Ensure that AFSYS = (ACLK x N2) = 96 MHz
- Select the APLL phase detector input divider to meet the APFD input frequency requirement (3 MHz < AFPLLI < 5.5 MHz).
- Select an APLL phase detector input divider ratio of N1 = 2
- Ensure that AFPLLI = (AFIN ÷ N1) = 4 MHz
- Select the auxiliary PLL feedback divisor to generate the required VCO output frequency based on the APFD input frequency.
- AFSYS = AFPLLI x M
- M = AFSYS ÷ AFPLLI = 24
- Select the APLL VCO output divider to meet the AVCO output frequency requirement (60 MHz < AFSYS < 120 MHz).
- Enable the auxiliary PLL by setting the ENAPLL bit.
#include <xc.h>
// No configuration bit settings are required for the APLL
int main(void)
{
...
// Configure APLL prescaler, APLL postscaler, APLL divisor
ACLKCON3bits.ASRCSEL = 0; // Select Auxiliary Oscillator as the clock source
ACLKCON3bits.FRCSEL = 0; // Select Auxiliary Oscillator as the clock source
ACLKCON3bits.SELACLK = 1; // Select Auxiliary PLL or oscillators to provide
// the source clock for auxiliary clock divider
ACLKDIV3bits.APLLDIV = 0b111; // M = 24
ACLKCON3bits.APLLPRE = 0b001; // N1 = 2
ACLKCON3bits.APLLPOST = 0b111; // N2 = 2
ACLKCON3bits.ENAPLL = 1; // Enable Auxiliary Clock
...
}
Two-Speed Start-up
If an external crystal (Primary Oscillator) is providing a clock source for your device, you will need to wait for the oscillator and PLL to stabilize before executing any code after a Power-on Reset (POR) or exit from sleep. If you want to start executing code before the oscillator has stabilized, you can use the "Two-Speed Start-up" option.
Two-Speed Start-up uses the internal Fast RC Oscillator (FRC) as the system clock source until the Primary Oscillator (POSC) has stabilized. This allows the CPU to begin running code while the oscillator is stabilizing. After it has stabilized, the clock source will automatically be switched to use the Primary Oscillator (POSC).
Application code will need to verify that the switch has completed.
The following MPLAB® XC16 compiler code example enables two-speed start-up (FRC to 8 MHz XTAL POSC) for a PIC24FJ128GA010 MCU:
#include <xc.h>
#pragma config FNOSC = PRI // Primary Oscillator desired
#pragma config POSCMOD = XT // XT Oscillator mode selected
#pragma config IESO = ON // Two-Speed Start-Up enabled
int main(void)
{
// compare the current OSC with new OSC - when these bits match, the clock switch is complete
while(OSCCONbits.COSC != OSCCONbits.NOSC);
...
}
The Watchdog Timer (WDT), if enabled, will continue to count at the same rate regardless of the SYSCLK frequency. Care must be taken to service the WDT during Two-Speed Start-up, taking into account the change in SYSCLK.
Fail-Safe Clock Monitor (FSCM)
The Fail-Safe Clock Monitor (FSCM) monitors the Primary Oscillator (POSC) to ensure it is functional. If the POSC stops working, it will automatically switch the clock source to the internal Fast RC Oscillator (FRC). The switch to the FRC allows continued device operation.
The FSCM function is enabled by programming the FCKSM (Clock Switch and Monitor) bits in the Configuration settings.
The FSCM will generate a clock failure trap and will switch the system clock to the FRC oscillator. You then have the option to either attempt to restart the oscillator or execute a controlled shutdown.
The following MPLAB® XC16 configuration macro enables FSCM for a PIC24FJ128GA010 MCU:
#pragma config FCKSM = CSECME // clock switching enabled and fail-safe clock monitor enabled
For more information about the oscillator failure trap, refer to "Section 8. Interrupts" in the “PIC24F Family Reference Manual”.
Clock Switching
Overview
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, the clock system has 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 for PIC24FJ128GA010:
#pragma config FCKSM = CSECME // clock switching enabled and fail-safe clock monitor enabled
#pragma config FCKSM = CSECMD // clock switching enabled and fail-safe clock monitor disabled
#pragma config FCKSM = CSDCMD // clock switching disabled and fail-safe clock monitor disabled (default)
Primary Oscillator mode has three different submodes (XT, HS and EC), which are determined by the POSCMD Configuration bits. While an application can switch to and from Primary Oscillator mode in software, it cannot switch between the different primary submodes without reprogramming the device.
Switching Sequence
The oscillator switching sequence is as follows:
- If desired, read the COSC bits (OSCCON<14:12>) to determine the current oscillator source.
- Perform the unlock sequence to allow a write to the OSCCON register high-byte.
- Write the appropriate value to the NOSC control bits (OSCCON<10:8>) for the new oscillator source.
- Perform the unlock sequence to allow a write to the OSCCON register low-byte.
- Set the OSWEN bit to initiate the oscillator switch.
The following example code shows how to perform a clock switch from FRC (default) to POSC with PLL for a PIC24FJ128GA010 device, having 8 MHz external crystal. The example uses MPLAB® XC16 compiler __builtin_ functions to perform steps 2-3 and 4-5:
#include <xc.h>
#pragma config FNOSC = FRC // FRC selected as default oscillator
#pragma config POSCMOD = XT // XT Oscillator mode selected for POSC - must be done at build-time
#pragma config FCKSM = CSECMD // Clock switching is enabled. Fail-safe clock monitor is disabled.
int main(void)
{
// Initiate Clock Switch to Primary OSC with PLL (NOSC=0b011)
__builtin_write_OSCCONH(0x03);
// Start clock switching
__builtin_write_OSCCONL(0x01);
// Wait for Clock switch to occur (COSC = 0b011)
while (OSCCONbits.COSC != 0b011);
// Wait for PLL to lock
while(OSCCONbits.LOCK!=1);
...
}
Reference Clock Output Generator
For select 16-bit PIC® MCU and dsPIC® families, the reference clock output generator provides another option: a separate synchronous and programmable clock source to the REFO port pin.
The reference clock output generator receives inputs from both the Primary Oscillator and the currently selected system clock. This allows the user to select an output clock signal with a constant frequency, or an output clock that changes as the system clock changes during run time (e.g., on a change to or from a lower power mode).
A 16-step divider allows for the selection of a wide range of system clock sub-multiples. Reference clock changes due to system clock frequency changes occur in a glitch-less fashion.
This reference clock output is controlled by the REFOCON register.