View previous topic :: View next topic |
Author |
Message |
TIMT
Joined: 02 Sep 2005 Posts: 49 Location: Nottingham, UK
|
USART baud rate range |
Posted: Wed Oct 10, 2007 7:27 am |
|
|
CCS version 3.234
PIC 18F452
Hi there,
I've searched the forum and I couldn't quite find the answer to my question so :
I'd like to run the internal USART at several baud rates using one clock frequency. The baud rates I would like are :-
300
600
1200
2400
4800
9600
14400
19200
28800
38400
57600
115200
230400
460800
With a 14.7456MHz xtal setting the CCS compiler compiled ok with all but the 300 and the 600 baud rates. Is it possible, using one xtal frequency to use the internal USART at all of these baud rates ? Or is the range too wide for one xtal. I've tried lots of different xtal frequencies but couldn't find one which would work.
Also, in the "CCS C Compiler reference guide" the maximum rate for the
set_uart_speed() function is 115200. Is this true? I've tried 460800 and the compiler didn't seem to complain.
Thanks
Tim _________________ Tim |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Oct 10, 2007 9:00 am |
|
|
Quote: | Or is the range too wide for one xtal. | The problem is not the xtal but the limited divider range of the PIC baudrate generator.
At 300 baud the highest allowed processor frequency for the hardware UART = 256 * 64 * 300 = 4,915,200MHz
The PIC18F452 is an old PIC model and not recommended for new designs, have a look at the pin compatible PIC18F4520.
These newer PIC models have a wider baudrate selection range but only for the higher baud rates, the maximum clock frequency at 300 baud would still be 4,9MHz. But the first lower clock frequency that would work for all baud rates is 3686400Hz.
My suggestion is to use the hardware UART for the higher frequencies and the software UART for the lower frequencies. Main disadvantage is that the software UART doesn't generate interrupts. |
|
|
Ttelmah Guest
|
|
Posted: Wed Oct 10, 2007 9:25 am |
|
|
As another comment, the '115200' upper figure, is just the highest normal baud rate, that CCS think anyone is likely to use. Remember this is the maximum baud rate developable by a standard PC UART (going beyone this, requires extended divisor bits), and such high rates are also likely to be unreliable over anything but quite short distances.
Best Wishes |
|
|
TIMT
Joined: 02 Sep 2005 Posts: 49 Location: Nottingham, UK
|
|
Posted: Wed Oct 10, 2007 10:18 am |
|
|
Thanks ckielstra and Ttelmah,
I did some calculations and I thought that was the case. I just needed someone more in the know to make sure I wasn't missing something.
I'll look at using the s/w USART though I need the interrupt. Maybe see if the h/w USART will generate an interrupt that i can use to trigger the s/w USART. I'll look at updating to the 18F4520.
Thanks for your help.
Tim _________________ Tim |
|
|
TIMT
Joined: 02 Sep 2005 Posts: 49 Location: Nottingham, UK
|
|
Posted: Thu Oct 11, 2007 2:33 am |
|
|
If I assigned the s/w USART to port b, could I use the interrupt for that port as the interrupt for the s/w USART?
Thanks _________________ Tim |
|
|
TIMT
Joined: 02 Sep 2005 Posts: 49 Location: Nottingham, UK
|
|
Posted: Fri Oct 12, 2007 4:31 am |
|
|
Hi again,
I've changed to a 18F4520 PIC and selected a crystal of 3.686400MHz and CCS is happy with all the baud rates. But, will the PIC be running fast enough to process the data coming out of the USART at the higher baud rates e.g 460800? I turned the H4 PLL on with no complaints from the compiler but I don't think it will physically work with a crystal below 4MHz.
Tim. _________________ Tim |
|
|
Ttelmah Guest
|
|
Posted: Fri Oct 12, 2007 5:24 am |
|
|
Use the 4520. 3.6864MHz crystal. Select H4, and set your 'clock' statement to the 14.7456 MHz that the chip will be running. Even better, go up to 7.3728MHz, on the crystal, and clock the chip at 29.4912MHz.
The 4520, support a 16bit BRG, allowing much slower baud rates to be supported for a given crystal rate, and will happily then support your entire range, and be running fast enough to have a hope of handling the faster data raes. :-)
Best Wishes |
|
|
TIMT
Joined: 02 Sep 2005 Posts: 49 Location: Nottingham, UK
|
|
Posted: Fri Oct 12, 2007 6:16 am |
|
|
Thanks Ttelmah, I'm not sure what you mean by :
"go up to 7.3728MHz, on the crystal, and clock the chip at 29.4912MHz"
though. Do you mean that I use a 7.3728MHz crystal and set the PLL to 29.4912MHz in the delay statement? This is the first time I've used the PLL feature and it's a little confusing. _________________ Tim |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Fri Oct 12, 2007 6:29 am |
|
|
Yes, you use a crystal 1/4 of the final frequency. Enable the PLL to get a clock frequency of 4 * the crystal. And the delay statement uses the final frequency.
Like this:
Code: |
#use delay(clock=29491200)
#FUSES H4 // enable PLL |
|
|
|
TIMT
Joined: 02 Sep 2005 Posts: 49 Location: Nottingham, UK
|
|
Posted: Fri Oct 12, 2007 6:38 am |
|
|
I tried:-
use delay(clock=29491200)
but 1200 baud, 600 and 300 caused the "Baud rate out of range" error
then:-
use delay(clock=7372800)
then only 300 baud wouldn't work.
use delay(clock=3686400) seems to be the only one that works with all the baud rates.
_________________ Tim |
|
|
Ttelmah Guest
|
|
Posted: Fri Oct 12, 2007 6:57 am |
|
|
You should not get a baud rate out of range error on the 4520, with that clock, and those rates.
What compiler version are you using?.
The rates available on this chip, are given by FOSC/(16*n+1), where 'n' is 0 to 65535. For 300 bps, off 29491200Hz, you need a divisor of (29491200/16)/600 = 3072 or n=3071.
Older chips only allowed 'n' to be 0 to 255, which is why you had the problems, but on the 4520, it works fine. I tried compiling with a rate of 300bs, and 2941200Hz clock, on the 4520, and a couple of the latest compilers, and it accepts the rate fine.
Best Wishes |
|
|
TIMT
Joined: 02 Sep 2005 Posts: 49 Location: Nottingham, UK
|
|
Posted: Fri Oct 12, 2007 7:02 am |
|
|
i'm using CCS version 3.234 _________________ Tim |
|
|
Ttelmah Guest
|
|
Posted: Fri Oct 12, 2007 7:19 am |
|
|
I'm afraid that is the problem then. The older compilers, didn't 'know' about the 16bit BRG registers on the latter chips.
Two choices:
1) Upgrade the compiler.
2) Set the baud rate to an acceptable value in the #use RS232 function, and write your own version of the set_uart_speed function, to access the 16bit registers.
Best Wishes |
|
|
TIMT
Joined: 02 Sep 2005 Posts: 49 Location: Nottingham, UK
|
|
Posted: Fri Oct 12, 2007 7:31 am |
|
|
My first bug in two years with CCS!
I thought it only happened to others
Looks like i may need to get my hands dirty and set the registers up myself. I guess the easiest way would be to set the rate using set_speed t to a rate the compiler will accept then set the BAUDCON and SPBRGH and SPBRG registers my self.
Second thought - Will the settings for the baud rates the compiler didn't complain about be correct? or will they have to be all done manually as well?
Will the latest v3 compiler do it - i have the latest one one at home. Or do i need v4?
_________________ Tim |
|
|
Ttelmah Guest
|
|
Posted: Fri Oct 12, 2007 3:34 pm |
|
|
Only the V4 compilers fixed this.
You wouldn't use the internal speed functions at all. Set the baud rate in the #use RS232 statement, to one that is accepted, and use your own replacement for the set_uart_speed function for _all_ speeds (including selecting one when you start).
The problem is that you have to reprogram the BRG, to use 16bit divisors, and since the V3 code doesn't 'know' about this, it will develop the wrong values.
Code: |
#byte BAUDCON=0xFB8
#byte TXSTA=0xFAC
#bit BRGH=TXSTA.2
#bit BRG16=BAUDCON.3
int16 SPBRG;
#locate SPBRG=0xFAF
void set_baud(int32 speed) {
int16 divisor;
//Switch to 16bit mode
BRGH=0;
BRG16=1;
//calculate required divisor - needs 'CLOCK_RATE' defined as
//operating frequency.
divisor=(CLOCK_RATE/(speed*16))-1;
SPBRG=divisor;
}
|
Best Wishes |
|
|
|