8 MHz crystal in XT Mode.
I'm trying to set PRI_OSC to 48 MHz
Will that give the USB Module the requisite 48 MHz?
I always use the APLL for the USB clock and set the main clock to whatever I need --- Usually 80 MIPS--- however it is possible to use the main clock to generate the USB clock.
The 48 MHz USB clock comes out of the APLL block. (See attachment)
To use PRIPLL to generate the USB clock here's a way to do the deed:
Set up the main PLL to give 96 MHz output. Feed that 96 MHz to the APLL output circuit, by seting ACLKCON3bits.SELACLK
to 0, and set APLLPOST
to divide-by-2 to get the 48 MHz USB clock.
Your 96 MHz main clock Fosc will result in an instruction clock of 48 MIPS.
Now, here's a Neat Thing about setting up a number of MIPS using an 8 MHz crystal
With an 8 MHz crystal, if the desired instruction clock is an integer, you can readily set up the clock circuit as follows
Set N1 to divide-by-2
Set N2 to divide-by-2
Set M equal to MIPS
So Fosc = 8e6 / 2 * MIPS / 2 = 2e6*MIPS and the instruction clock frequency in Hz is 1e6*MIPs
I always set configuration bits to start with FRC, then in a function, say init_clock()
I set up the PLL and switch to PRIPLL mode.
#pragma config FNOSC = FRC // Initial Oscillator Source Selection Bits (Internal Fast RC (FRC))
#pragma config FCKSM = CSECME // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are enabled)
#define MIPS 48
// Define FCY and include libpic30.h to be able to use __delay_ms()
// Also, use FCY to set up timer periods, UART Baud settings, etc...
#define FCY (MIPS*1000000UL)
// Initialize main clock. USB setup of APLL is a separate function
CLKDIVbits.PLLPRE = 0; // N1 = Divide-by-2
PLLFBD = MIPS-2; // FOR 48 MIPS, this is 46
CLKDIVbits.PLLPOST = 0; // N2 = Divide-by-2
// Note that you need NOSC equal to 0b011 for PRIPLL
__builtin_write_OSCCONH(0b011); // Other bits of OSCCONH are Read-Only
__builtin_write_OSCCONL(OSCCON | 0x01); // Enable clock switch
while (OSCCONbits.COSC != 0b011)
// TODO: Maybe put timeout here so that it can fall back to FRC in case crystal fails
while (OSCCONbits.LOCK != 1)
} // End of init_clock
I have assumed you want 48 MIPS, but if you really want your primary clock to be 48 MHz (it will be set up for 24 MIPs), you can set APLLPOST to divide the 48 MHz Fosc by 1. I haven't actually done this, but it looks like it should work.
Footnote: "Issues" with your code:
- Initial attempt to write 0x3300 to OSCCON is irrelevant. Needs the unlock sequence
- Your PLLFBD value doesn't take into account prescaler divide-by-2 and postscaler divide-by-2
Also, for future reference, note that PLLFBD value of 5 gives multiplication by 7, not 6 as indicated in your comment
- Writing 0x01 to OSCCONH sets up FRCPLL. To use the 8 MHz crystal, you need PRIPLL, as I showed
post edited by davekw7x - 2019/08/24 08:42:24