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.
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
appears to fixed the problem. Also, because I am using a MAX232 linked to the output I have to invert the signals: