Electronic – PIC18 USART problem

picuart

Ok, my next PIC18 problem…

USART – I can't get it to transmit anything sensible. All I get is random x's and inverted question marks.

I am using the same BAUD settings as I have used many times on PIC16s quite happily. I have tried re-calculating the baud setting from the formula, I have tried different baud rates and different crystal frequencies to give different baud accuracies, but still all I get is the same two wrong characters.

If I change the baud to something completely wrong it puts more random gibberish than just these two characters.

enter image description here

I have tried this on 2 different PIC18s – both my '4455 and my '14K50 – both do exactly the same.

Here's my program:

void main()
{
    OpenUSART ( USART_TX_INT_OFF &
                USART_RX_INT_OFF &
                USART_ASYNCH_MODE &
                USART_EIGHT_BIT &
                USART_BRGH_HIGH &
                USART_CONT_RX, 103);
    baudUSART(  BAUD_IDLE_CLK_HIGH &
                BAUD_8_BIT_RATE &
                BAUD_WAKEUP_OFF &
                BAUD_AUTO_OFF);
    while(1)
    {

        WriteUSART('F');
        WriteUSART('o');
        WriteUSART('o');
        WriteUSART(13);
        WriteUSART(10);
    }
}

The 103 I caclulated from a 16MHz crystal at 9600 baud according to the formula in the data sheet for the PIC.

So what am I missing?

UPDATE

Timing the data stream with a 'scope I have determined that it is infact running at 2400 baud (setting the computer to 2400 baud confirms it).

I have checked and the crystal is oscillating at 16MHz.

The formula for calculating the BAUD is:

\$\frac{F_{osc}}{(16*(n+1))}\$

where Fosc is the is the oscillator frequency, and n is the number passed to the baud rate generator.

\$\frac{16,000,000}{(16*(103+1))} = \frac{16,000,000}{(16 * 104)} = \frac{16,000,000}{1664} = 9615.384615385\$

So why is it actually running at 2400 baud???

I know it's not my calculations – the table of bauds in the datasheet quotes 119 for a 9600 baud on an 18.432MHz crystal, so 103 for a 16MHz is perfectly reasonable.

Things I have tried:

  • Switch to BRGH=0 – slows the baud down even more
  • Switch to 16-bit timer not 8-bit – slows the baud down to a crawl.

So what is strange about this UART then?

Best Answer

The problem here is that Microchip sneakily defaulted the CPUDIV to /4 meaning the internal clock of the PIC was running at a quarter of the expected frequency - thus the calculations were all wrong.

It took some time to figure this out, but setting

#pragma config CPUDIV = NOCLKDIV

appears to fixed the problem. Also, because I am using a MAX232 linked to the output I have to invert the signals:

baudUSART(BAUD_IDLE_CLK_LOW & 
          BAUD_AUTO_OFF & 
          BAUD_8_BIT_RATE & 
          BAUD_IDLE_RX_PIN_STATE_HIGH);

OpenUSART (USART_TX_INT_OFF &
           USART_RX_INT_OFF &
           USART_ASYNCH_MODE &
           USART_EIGHT_BIT &
           USART_CONT_RX &
           USART_ADDEN_OFF &
           USART_BRGH_HIGH, 103);