CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

USART with PLL turned on baudrate problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
maria100



Joined: 01 Feb 2012
Posts: 63

View user's profile Send private message

USART with PLL turned on baudrate problem
PostPosted: Mon Apr 23, 2012 7:50 am     Reply with quote

Hello, I`m running a 18f14k50 With the following test program:
Code:

#include <18f14k50.h>
#device adc=16
#FUSES BROWNOUT_NOSL            //Brownout enabled during operation, disabled during SLEEP
#FUSES NOWDT                    //No Watch Dog Timer
#fuses INTRC_IO
#use delay(int=32000000)
#use rs232(baud=57600, BITS=8, PARITY=E, STOP=1, STREAM=CELEROM,xmit=PIN_C3,RCV=PIN_C7)

void main()
{
setup_oscillator(OSC_32MHZ);
while(1)
{
fprintf(celerom,"test");
delay_ms(10);
}
}

I set up the 4x PLL on for running at 32 MHZ
My problem is that when i`m using the PLL the baudrate goes wrong..but kind of random..one time it worked fine...i did the power cycle after programming..notice that i use a software UART. What could be the problem? I have tried different baud-rates with no success..I set up the terminal right ( Parity, stop bits)
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 8:52 am     Reply with quote

If you are having "random" errors that probably means your clockrate is outside the serial specification. You are using internal clock, that is a big source of clock error. Also at higher baudrates the error tends (but is not always) to be higher due to the division ratios not being good.

PIC baud rate calculator V2.1 says that if you are using the hardware UART then at 32MHz processor clock, the best you can get for 57600 with BRGH = 0 is 55555 baud, or -3.55% which is only just about OK with a good clock source such as a crystal. This is a fixed error. The recommended maximum error is +/-4%, best to keep within +/-3%. This is not the only source of baudrate error. The internal clock has a fair bit, something like +/-1% or so over the operating temperure range and the PLL will add some clock jitter of its own. So add in the error of the internal clock source and PLL and it won't work all the time Crying or Very sad

With BRGH = 1 the situation is better, 57124 baud, or -0.79% which is OK, and may work satisfactorily with internal oscillator as long as you don't let your PIC get too hot. The compiler should set BRGH for you for the best result.

With software UARTs the problem is worse Shocked This is becuase the timing is done by inserting delays, which are single processor cycles which are 4 times slower than the clock. This means that the timing is worse ad the errors larger. I don't know for sure, as CCS don't publish any way to calculate actual software UART timing, that you are unlikely to be able to get anything better than the -3.55% figure for the worse of the two hardware timings. It may be worse.

So, for higher UART speeds you must use a hardware UART AND a crystal/crystal oscillator clock source.

I have got a serial link to operate with the sending end working fairly reliably at this sort of speed on internal clock. I did it by selecting a non-standard baudrate that was easy for the PIC to generate wth zero error. So the only error was the internal clock error and the crystal error at the receiving end.

Internal clock is only suitable for the simplest of applications that don't require even reasonably accurate timing. Its not good for anything that sends asynchronous data. SPI is OK, I2C is OK, serial is not USB may or may not be: I don't have enough info on the clock tolerances to be able to comment.

RF Developer
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Apr 23, 2012 12:41 pm     Reply with quote

Quote:

BRGH = 0 is 55555 baud, or -3.55% which is only just about OK

For a medical instrument project, about 2 years ago,
I had to do a baud rate error test using a older PC as the operating host
where I replaced a local 1.8432mhz crystal oscillator with a function generator.

My finding was that with a 16f887 and also 18f4620 hardware uarts,
(PIC HS external xtal at 14.7456mhz ) there was far less sensitivity to baud drift than I BELIEVED before I did the test.

I found I could set the PC 16550 frequency +/- 10 % and then
run for 12 hours in an all character, steady test loop w/o a single character error on either PIC used as the "loop back repeater chip.

It is my understanding that there is much opinion, but no hard testing to back up the notion of baud clock "tightness", and far too much belief that the internal RC oscillator is too loose.

Just not proven by test.

BUT I must also add that RF developer is very correct is speaking about YOUR problem. The software based uart, by its nature is FAR more susceptible to character distortion, even in the generator condition as it is NOT being clocked by a baud register.

My advice AVOID all soft uarts, because they are a curiosity,
NOT a safe way to build a reliable product.
maria100



Joined: 01 Feb 2012
Posts: 63

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 1:00 pm     Reply with quote

I tried even a hardware uart now, and is working the same...did i configure the PLL wrong? ...
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Apr 23, 2012 1:05 pm     Reply with quote

without knowing your list of fuses etc --
it is hard to see precisely where it has gone wrong

but perhaps you can simplify further :

try using 8mhz clock with NO PLL and just 9600 baud

prove first that you can do it properly at a low baud - then
try faster clocks - then the PLL and lastly your highest baud rate

isolate what is wrong through simplifying.

walk slow :: then learn to run

if it still does not work - post your best shot at the simplest
program you can write that still does not work

Very Happy Very Happy
maria100



Joined: 01 Feb 2012
Posts: 63

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 1:14 pm     Reply with quote

the program is here in the thread at the begining ( the fuses that i set also).
The program runs fine with 8, 16 Mhz ( NO PLL) with all baud rates.
Ttelmah



Joined: 11 Mar 2010
Posts: 19348

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 1:37 pm     Reply with quote

Your setup oscillator line is wrong.
You need:

setup_oscillator(OSC_32MHZ | OSC_INTRC);

Otherwise using this line turns off the internal oscillator....

Best Wishes
maria100



Joined: 01 Feb 2012
Posts: 63

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 2:11 pm     Reply with quote

Thanks Ttelmah ..i changed it but is working the same....:(
maria100



Joined: 01 Feb 2012
Posts: 63

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 3:07 pm     Reply with quote

I have "ported" the code to a 18f25k22 for testing and is working fine with the PLL ON.....i just wish PICs were a bit more standard..still..have to make the 14k50 running..:|
Ttelmah



Joined: 11 Mar 2010
Posts: 19348

View user's profile Send private message

PostPosted: Tue Apr 24, 2012 3:26 am     Reply with quote

OK.
I took the time to compile the code, and test it on a chip, with a digital scope testing the timings of the bits.
Code I ran, was:
Code:

#include <18F14K50.h>
#FUSES NOWDT, WDT128, CPUDIV1, INTRC_IO, NOFCMEN, NOIESO, BORV27, NOHFOFST, NOMCLR, NOLVP, NOXINST
#use delay(clock=8000000)
#use rs232(baud=57600, BITS=8, PARITY=E, STOP=1, STREAM=CELEROM,xmit=PIN_C3,RCV=PIN_C7)

void main(void) {
   setup_comparator(NC_NC_NC_NC);

   while(TRUE) {
      fputc(0xAA);
      fputc(0x55);
      delay_ms(10);
   }
}

I timed from the first falling edge of the first bit, and changed the data sent, to 0xAA, and 0x55, so I could get every edge.
Timings (in uSec) were:
Code:

           8MHz     32MHz
           17.5       17.375
           35          34.75
           52.5       52.125
           70          69.5
           87.5       86.875

Then calculated what baud the code was generating

At 8MHz, five bit times = 87.5uSec -> 57142bps
At 32Mhz, five bit times = 86.875uSec -> 57553bps

At 32MHz, error is 0.08%, at 8MHz, error is 0.8%.

Neither should cause any problem, and the 32MHz performance is 10* _better_.....

Obvious question now, is 'what compiler'. My guess is that you have an old version, that is perhaps not setting up the PLL properly.

On my chip at normal room temperature, the RC oscillator was basically 'spot on'. I also tested just doing a long pulse, and it appears to be running about 0.001% slow. Very acceptable. Smile

Best Wishes
maria100



Joined: 01 Feb 2012
Posts: 63

View user's profile Send private message

PostPosted: Tue Apr 24, 2012 3:45 am     Reply with quote

Thank Ttelmah for your time , unfortunately i have a not so old compiler ( Version 4.124) . You have a newer one? Other chip ( 18f25k22 ) runs just fine ..so 14k50 is the problem somehow. Can you please post the .LST file where is shows how the OSC is set up with PLL ACTIVE? Thanksss
Ttelmah



Joined: 11 Mar 2010
Posts: 19348

View user's profile Send private message

PostPosted: Tue Apr 24, 2012 3:52 am     Reply with quote

You had not said what compiler version, so wondered if that might be the problem. Yes on a real 14K50.
Only differences are that I turn off FCMEN, snce this can 'mislead' you, if your oscillator is not working, falling back to a default setting, and then giving the wrong rate, and that I didn't use setup_oscillator, letting the compiler do the settings. Had checked already, and the fuses generated are correct for 32MHz operation.

Best Wishes
maria100



Joined: 01 Feb 2012
Posts: 63

View user's profile Send private message

PostPosted: Tue Apr 24, 2012 3:57 am     Reply with quote

The Compiler is 4.124 , That what is says in "Compiler Version" . I asked for the .LST to check if my compiler does the same thing like yours when it comes to setting up the Internal Oscilator . Thanks
maria100



Joined: 01 Feb 2012
Posts: 63

View user's profile Send private message

PostPosted: Tue Apr 24, 2012 5:20 am     Reply with quote

SOLVED!!!!! Setting the fuses like you did Ttelmah and not setting the setup_oscillator line did the trick..dont know exactly each one ( fuses or setup_oscillator ) was to blame but now is working! Is possible to have something to do with the CPUDIV fuse?
Ttelmah



Joined: 11 Mar 2010
Posts: 19348

View user's profile Send private message

PostPosted: Tue Apr 24, 2012 6:10 am     Reply with quote

Possibly.
It depends what the defaults are.
If you study these chips, when you select the PLL, the clock instead of going straight across through the multiplexer, and feeding to the CPU, goes up and joins the USB settings, where the PLL is selected, to feed the USB/CPU, and this clock is then fed into the CPU divider, and back into the final multiplexer for the CPU. Because I wanted to be sure the divider was set to '1', I selected it. The default on most registers/fuses is for bits to be '1' unless selected, and this would give CPUDIV = 4....
Since this is a fuse setting, I'd guess this was what was going wrong.
A quick compile _without_ selecting the CPUDIV fuse, confirms it does default to /4..

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group