PIC24 Primary Oscillator XT_PLL frequency is off by 3 percent

I am using a PIC24. After solving the issue with the PLL (PIC24 PLL module is always out of lock) I am struggling with large variation in the system frequency. I wrote a small code that is used to measure the system frequency using internal LPRC timer. The primary oscillator FOSC is 8 MHZ and with PLL its pushed to 32 MHz. The FCY is FOSC/2 (16MHZ). My code is reading an FCY of 15.522 MHz which is 3 percent off the actual expected frequency. As a result I am not able to connect my PC to the UART running at 38400 bps for debugging.

I think my computer's serial port is not able to tolerate such high a drift in the baud rate and hence causing a serial port framing error. Please suggest a way to improve my frequency.

Here is my uartInit function

#define  peripheralPinSelectUnLock() do { OSCCON = 0x46; OSCCON = 0x57; OSCCONbits.IOLOCK = 0; } while(0)
#define  peripheralPinSelectLock()   do { OSCCON = 0x46; OSCCON = 0x57; OSCCONbits.IOLOCK = 1; } while(0)
#define UART1_BAUD_RATE              (38400ul)

uint32_t ui32Fcy=16000000;
unsigned long int baudRateDivider = ((ui32Fcy/(4*UART1_BAUD_RATE))-1);

peripheralPinSelectUnLock();   // PPS Unlock
PPSInput(PPS_U1RX, PPS_RP30);  // RF2/RP30 as U1RX
PPSOutput(PPS_RP16, PPS_U1TX); // RF3/RP16 as U1TX
TRISFbits.TRISF2 = 1;          // RF2/RP30 is set for input (RX)
TRISFbits.TRISF3 = 0;          // RF3/RP16 is set for output (TX)
peripheralPinSelectLock();     // PPS Lock

U1BRG = baudRateDivider; // Divides to UART_BAUD_RATE
U1MODEbits.UARTEN = 1;   // UART2 is Enabled
U1MODEbits.ABAUD = 0;    // auto baud is disabled
U1MODEbits.BRGH = 1;     // Low baud rate ?
U1STAbits.UTXEN = 1;
IFS0bits.U1RXIF = 0;      // clear interrupt flag of rx
IEC0bits.U1RXIE = 1;
IPC2bits.U1RXIP = 7;      // enable rx recieved  data interrupt


The value of U1BRG (watch variable) is 103 for a baudrate of 38400. Thanks for any help.

• Are you using the internal oscillator? If you are then when you get a PIC for the first time you should read out the clock calibration value and then set it after you have programmed the PIC. Or adjust it until the clock is accurate enough. It's in the datasheets. And yes .... every one can have a different calibration value. – Spoon Dec 17 '14 at 8:52
• @Spoon I have an external crystal. I am setting the timer 1 to LPRC and then calculating that count against the external crystal. That reading is showing 3% drift in the main oscillator. – Siddharth Dec 17 '14 at 13:04
• What does "my code is reading an FCY of 15.552 MHz" mean? Please describe all the measurements you are making. Can you toggle a bit on a simple timer-interrupt and make sure everything makes sense? 3% is an awfully big number when you're using a crystal. Even so, in many cases UART should be able to tolerate clock tolerances of >3% -- see element14.com/community/servlet/JiveServlet/downloadBody/…. – Scott Seidman Dec 17 '14 at 14:01
• I agree 3% is just too big a number. Okay here is how the FCY calculation goes, I setup timer 1 to run at LPRC Oscillator and timer 2/3 to run with the XT oscillator. Then for a fixed count in timer 1 I check the count of timer 2/3 with those numbers, I estimate the XT oscillators frequency. This is assuming that the internal LPRC oscillator is working properly. – Siddharth Dec 19 '14 at 5:48

You're using the LPRC to 'measure' your crystal? Usually that's done the other way around.

Have a look at the datasheet for your PIC - section 32.2, table 32-21.
You'll find the LPRC accuracy spec is +-20%, meaning it could be anywhere between 25kHz and 37kHz depending on various factors (temperature, supply voltage, ...).

I think your baud-rate troubles are coming from somewhere else and not from your crystal.

Show us your UART initialisation code as this is most likely where the trouble is.

• thanks for the idea. I have posted my uart initi code. Please have a look at it. But I don't see what could possibly have gone wrong with the initialization. Its pretty straight forward – Siddharth Dec 18 '14 at 17:42
• On second thought, could it be that the LPRC osc is bad and hence counting bad values for the crystal? Even so, the uart baud rate exception cannot be caused by a bad LPRC osc. – Siddharth Dec 18 '14 at 17:45
• @Siddharth I'll add again -- if you think you're having clock issues, scrap EVERYTHING else, toggle a pin on a timer interrupt, and make sure the frequency you get makes sense. There's no reason to be guessing about whether your bug is with your clock or with some other aspect of your code. If you do this, and the frequency makes sense, your clocking is fine, and the issue is elsewhere. – Scott Seidman Dec 18 '14 at 17:51
• Does your UART code work on the development board you referred to in your previous question? – brhans Dec 18 '14 at 18:01
• You need something to see your signals--an oscilloscope or logic analyzer. You're shooting in the dark without the right tools – Scott Seidman Dec 19 '14 at 14:18

I suggest using a crystal. The alternate approach is to fiddle with the uart brgh until you match 38,400.

I have yet to see a reasonable reason not to use a crystal. Perhaps the bean counters require it sometimes..

• I have an external crystal. I am setting the timer 1 to LPRC and then calculating that count against the external crystal. That reading is showing 3% drift in the main oscillator. – Siddharth Dec 17 '14 at 13:05
• "I have yet to see a reasonable reason not to use a crystal" Cost \$ – m.Alin Dec 17 '14 at 13:20
• "reasonable" is subjective perhaps. – Erik Friesen Dec 17 '14 at 13:58
• I 'am' using an external crystal. I just wanted to see how good or bad it was by comparing it against another oscillator. (in this case LPRC) – Siddharth Dec 18 '14 at 17:46