I'm trying to configure Timer1 of a pic24h to 1ms per timer tick but don't seem to be able to get the math to match my results.
I have a 20MHz external oscillator (with a 1M resistor in parallel for stability) and think I have it enabled with the following configuration bits set in code:
#pragma config FNOSC = PRIPLL // Oscillator Mode (Primary Oscillator (XT, HS, EC) w/ PLL)
#pragma config IESO = ON // Internal External Switch Over Mode (Start-up device with FRC, then automatically switch to user-selected oscillator source when ready)
I'm toggling a pin and watching it on the scope to check my math. I thought the calculation is as follows:
// ms_per_tick = ((F_OSC / 2)/prescaler)^-1 * PR1
// = ((20MHz / 2) / 8)^-1 * 4200
// NO= 1ms
bit a value of PR1 = 4200 is about the closest I can get to a tick of 1ms.
What am I missing? Does the PLL change the value of what I think is F_OSC. Is there a way to validate F_OSC?
The ISR just increments a variable and clears the interrupt flag. Here is the initialization code:
T1CONbits.TCKPS = 0b01; // configure the timer prescaler to divide-by-8
T1CONbits.TCS = 0; // do NOT use the external clock
PR1 = 4200; // configure the timer period
// configure the Timer1 interrupt
_T1IF = 0; // begin with the interrupt flag cleared
_T1IE = 1; // enable the interrupt
T1CONbits.TON = 1; // turn on timer1
I'm starting to learn more about the PLL via some SFR's:
CLKDIV is: 0x3040 (PLLPOST = 1, PLLPRE = 0)
PLLFBD is: 0x0030 (PLLDIV = 48)
I also just found this on p.16 of the datasheet:
"If the PLL of the target device is enabled and configured for the device start-up oscillator, the maximum oscillator source frequency must be limited to ≤8 MHz for start-up with the PLL enabled to comply with device PLL start-up conditions. This means that if the external oscillator frequency is outside this range, the application must start-up in the FRC mode first. The default PLL settings after a POR with an oscillator frequency outside this range will violate the device operating speed. Once the device powers up, the application firmware can initialize the PLL SFRs, CLKDIV and PLLDBF to a suitable value, and then perform a clock switch to the Oscillator + PLL clock source. Note that clock switching must be enabled in the device Configuration word."
Now, the first thing I run after main is this example code:
void ConfigureOscillator(void) {
// Disable the Watch Dog Timer
RCONbits.SWDTEN = 0;
// When clock switch occurs switch to Prim Osc (HS, XT, EC)with PLL
__builtin_write_OSCCONH(0x03); // Set OSCCONH for clock switch
__builtin_write_OSCCONL(0x01); // Start clock switching
// Wait for Clock switch to occur
while(OSCCONbits.COSC != 0b011);
// Wait for PLL to lock, if PLL is used
while (OSCCONbits.LOCK != 1);
}