0
\$\begingroup\$

I'm using a PIC24FJ1024GA606 and I'm using the internal Fast RC Oscillator.

Here is my config:

// FOSCSEL
#pragma config FNOSC = FRCPLL        // Oscillator Source Selection (FRC with PLL module)
#pragma config PLLMODE = PLL96DIV2   // PLL Mode Selection (96 MHz PLL. (8 MHz input))
#pragma config IESO = OFF            // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)

// FOSC
#pragma config POSCMD = NONE         // Primary Oscillator Mode Select bits (None)
#pragma config OSCIOFCN = OFF        // OSC2 Pin Function bit (OSC2 is clock output)
#pragma config SOSCSEL = OFF         // SOSC Power Selection Configuration bits (SOSC is not used)
#pragma config PLLSS = PLL_FRC       // PLL Secondary Selection Configuration bit (PLL is fed by the FRC)
#pragma config IOL1WAY = ON          // Peripheral pin select configuration bit (Allow many reconfigurations)
#pragma config FCKSM = CSDCMD        // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are disabled)

The issue I'm running into is that 115200 baud UART has a high error rate when sending data sequentially (my bootloader flashes firmware via UART at 115200 baud). From what I've read, the Internal Oscillator isn't really up to the task when it comes to low error rates for high speed UART and I need to use an external crystal.

It should be noted that if I set the baud rate to 111000, where my BRG (currently 8) has a low deviation from the baud rate, everything works fine and there are no errors.

First of all, is this diagnosis of my problem correct?

If yes, what kind of oscillator should I use so that I can effectively use 115200 baud?

If it matters: I'm also using a timer with a 1ms interrupt rate and another timer with a 1us interrupt rate. My FCY is 16,000,000.

\$\endgroup\$
  • 1
    \$\begingroup\$ The datasheet does mention how you can calculate baud rate error, Section 19.1. I'm assuming you've looked at that? \$\endgroup\$ – KingDuken Jun 19 at 16:09
  • \$\begingroup\$ @KingDuken - Yup. I'll be updating the post with an answer soon, but essentially I need to use the fast baud rate flag for the UART module. \$\endgroup\$ – t3ddftw Jun 19 at 16:18
0
\$\begingroup\$

The answer is that I should be using the BRGH flag which provides 4 BRG cycles per bit, rather than 16.

This makes the BRG calculation:

BRG = ((16000000/115200)/4) - 1 (33.72, or 34)

The effective baud rate at this BRG is 114286 or 0.8% error rate, which is perfectly acceptable.

\$\endgroup\$
  • 1
    \$\begingroup\$ 16 clocks per bit gives more jitter and freq error margin than 4, for lower rates but if jitter is less than 10% and freq error is less than less than 1% or 10% phase shift after 10 bits then you are good to go. With 5% margin with these assumptions. That being said I hope CRC is checked before flashing and you use Odd parity. \$\endgroup\$ – Sunnyskyguy EE75 Jun 19 at 19:36
  • \$\begingroup\$ @SunnyskyguyEE75 - Thanks! I'm not currently using odd parity, but it's easy enough to implement. The bootloader protocol that I devised implements a CRC for all packets sent \$\endgroup\$ – t3ddftw Jun 20 at 15:16
  • 1
    \$\begingroup\$ If use of CRC has good try algorithms in bootloader, or manual error flag, OK. It's worth verifying. \$\endgroup\$ – Sunnyskyguy EE75 Jun 20 at 16:21
  • \$\begingroup\$ Typo..... retry...... \$\endgroup\$ – Sunnyskyguy EE75 Jun 20 at 19:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.