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 CCS Technical Support

Changing Baud rates - SOLVED
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
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

Changing Baud rates - SOLVED
PostPosted: Mon Aug 06, 2012 9:16 pm     Reply with quote

I'm trying to change clock frequencies AND baud rates unsuccessfully.

below is my small and compilable test program:
I'm using 4.135 on a 16F866 with an FTDI chip.

I've check the timings toggling a pin and they match perfectly (i have an O-scope)

when using the internal osc i _believe_ i am waiting for it to stabilize properly...

the problem is with printing at 9600.... 115200 works fine.

my O-scope tells me that when i switch to 9600 the timing is fine and that i am outputting _something_ via the UART....

hyperterminal says: random smilies and ascii chars...


to use the test code just compile and press any key on your terminal program to "switch" modes...

mode 1 print at 9600
mode 2 toggle pin B2 at 50ms
mode 3 print at 115200
mode 4 toggle pin B2 at 25ms...

Code:
#include <16f886.h>
#device adc=10
#device *=16

#fuses HS,NOWDT,NOPROTECT, NOLVP//,INTRC_IO

#use delay(clock=20000000)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#BYTE OSCCON = 0x8F

void TX_9600();
void TX_1152();

#INT_RDA
void SerialInt();
#INT_TIMER0
void Timer0Int();

// --------- SERIAL BUFFER AND MAIN INDEX DECLARATION --------//
char Receive_String[71];
int counter_read = 0x00;


void Main()
{
   ENABLE_INTERRUPTS(GLOBAL);                           // Enable Interrupts
   ENABLE_INTERRUPTS(INT_RDA);                           // Enable Serial Interrupt

    while (1)                                       // Main Loop
   {
      TX_9600();
      counter_read=0;
      TX_1152();
      counter_read=0;
   }
}

void TX_9600()
{
   SETUP_OSCILLATOR(OSC_4MHZ);
   while(!bit_test(OSCCON,2));

   #use delay(clock=4000000)
   #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

   while(counter_read==0)printf("9600: %X \r\n", OSCCON);
   counter_read=0;
   while(counter_read==0)
   {
      delay_ms(50);
      output_toggle(PIN_B2);
   }
}

void TX_1152()
{
   SETUP_OSCILLATOR(OSC_NORMAL);

   #use delay(clock=20000000)
   #use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

   while(counter_read==0)printf("1152: %X \r\n", OSCCON);
   counter_read=0;
   while(counter_read==0)
   {
      delay_ms(25);
      output_toggle(PIN_B2);
   }
}

#INT_RDA
void SerialInt()
{
   Receive_String[counter_read]=getchar();
   counter_read++;
   if(counter_read==70)counter_read=0;
}


your help is greatly appreciated.

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093


Last edited by Gabriel on Tue Sep 18, 2012 9:16 pm; edited 1 time in total
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 9:51 am     Reply with quote

Really? no one?
















Forever Alone
_________________
CCS PCM 5.078 & CCS PCH 5.093
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Tue Aug 07, 2012 9:59 am     Reply with quote

Quote:

#use delay(clock=20000000)

SETUP_OSCILLATOR(OSC_4MHZ);

SETUP_OSCILLATOR(OSC_NORMAL);

#use delay(clock=20000000)



is all pretty awkward

have you REALLY got 20 mhz - accurate freq when you THINK you do ??
i would use this arcane tool called a frequency counter to know for sure. Very Happy Very Happy Very Happy
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 10:14 am     Reply with quote

Hi,

I checked my OSC pins (with 20M crystal) and it was running at 20M when the code that is supposed to run 20M is running...

and also when running at 4M the 20M OSC stopped....

So i am pretty sure frequencies are changing accordingly,

furthermore in my initial post i mention that printing at 115200 IS working...
From the datasheet i don't recall that being possible at 4M.... so yeah... i got 20M ...

Also, i checked my frequencies by toggling a pin and testing the _expected_delays.... it tested OK.


I don't understand exactly what you mean by it looks awkward?
how code looks and feels does not necessarily imply its wrong...

... do you have any suggestions?

thank you

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 11:19 am     Reply with quote

The internal oscillator, is _not_ normally accurate enough for serial on these chips. In some cases, it 'can be', but is borderline. Suggests your chip isnot actually giving 4MHz, accurately enough.

Best Wishes
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 12:04 pm     Reply with quote

i thought of that at first, but if I _do not_ try to change baudrates and stick to 9600 baud @ 4M it works Perfectly...


changing OSC and Baud rates is Absolutley nessesary in my app....

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 12:53 pm     Reply with quote

The erroneous belief involved with your code is, that #use rs232() would change a UART baud rate. But it doesn't, as well as #use delay() doesn't reconfigure the clock on it's own. The UART initialization specified by #use delay() is performed in the begin of main, before the first executable statement.

For UART reconfiguration, CCS provides set_uart_speed () and setup_uart(). It should assume clock settings according to last #use delay() statement before.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Tue Aug 07, 2012 1:00 pm     Reply with quote

Is there some reason you cant just use 20 MHz all the time
and merely change the BAUD ????

That way you get the simplest setup.

Awkward comes from the way you change the delay setting AND baud at the same time - not to mention the internal external osc switch.

I would stay with just the external osc if I was doing this code
and a SINGLE use delay for the whole program.

20 MHz will give BOTH divisors - nicely handled wont it ???
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 1:17 pm     Reply with quote

I simply assumed that Gabriel has reasons to perform clock switching, no matter if they are mentioned in the post, e.g. power saving.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 1:39 pm     Reply with quote

Hi all,

I think you have touched a key point...

I was under the impression that the #USE rs232 statement would configure what i need... ill try the setup_uart functions(completely forgot about that).... i think that will at least take care of part of the problem...

I _have_ to change OSC freq. for power reasons indeed...

I'm reading a sensor at 9600 once an hour... battery operated logger...
when i dump my eeprom (25LC512) it takes 45 minutes at 9600 baud... (date, time, data, +2 bytes for checking and debug)

45 minutes is toooo long so i want to print at 115200 @20M (4:40 minutes).... and by going with the internal 4M OSC... i can drain my batteries lower....


Now... after i do this exercise successfully I'll go with software 9600 uart for the sensor and 115200 HW for data dumping...

How do I set up the "new" delay values?
The #use delay line still works at any point in code right?


Thanks for your help.
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 2:19 pm     Reply with quote

#use RS232, changes the internal configurations used for the UART.
These values are used:
1) When the code starts.
2) When you call setup_uart.

So, 'no', it won't change the settings mid code.

However I'd suggest simplifying.

Work out the differences yourself, and don't change the #use delay, or #use RS232 settings.
Leave these setup for your main clock rate (say the 20MHz position). Then:
Code:

#define 9600bps4MHz (48000)
//Then when you change oscillator down to 4Mhz, just use:

setup_uart(9600bps4MHz);

//Then when you switch back to 20MHz, use

setup_uart(115200);


You have to understand that things like delay statements, won't change anyway. These are _hardcoded_ at compile time, so changing the #use delay settings, won't change the durations of delays already in the code.

Best Wishes
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Aug 07, 2012 2:31 pm     Reply with quote

The droids I was looking for, you´ve found them!


Thank you!
G
_________________
CCS PCM 5.078 & CCS PCH 5.093
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Aug 08, 2012 12:16 am     Reply with quote

Quote:
Work out the differences yourself, and don't change the #use delay, or #use RS232 settings.
Leave these setup for your main clock rate (say the 20MHz position). Then:
Code:

#define 9600bps4MHz (48000)
//Then when you change oscillator down to 4Mhz, just use:

setup_uart(9600bps4MHz);

//Then when you switch back to 20MHz, use

setup_uart(115200);


Multiple #use delay statements are the method intended by CCS to reflect clock switching, e.g. for delay_xx(). They can also work for set_uart_speed(). I don't see a clear indication why we shouldn't have multiple #use delay() statements in the present code, although I can imagine that manual settings may be favorable in some cases.
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Aug 08, 2012 12:49 am     Reply with quote

Sorry I'm late...

I was going to post code I have that does clock switching with maintaining the same baud rates (sort of different, but the idea gets shown)

looks like you have it solved?

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Wed Aug 08, 2012 1:25 am     Reply with quote

FvM wrote:
Quote:
Work out the differences yourself, and don't change the #use delay, or #use RS232 settings.
Leave these setup for your main clock rate (say the 20MHz position). Then:
Code:

#define 9600bps4MHz (48000)
//Then when you change oscillator down to 4Mhz, just use:

setup_uart(9600bps4MHz);

//Then when you switch back to 20MHz, use

setup_uart(115200);


Multiple #use delay statements are the method intended by CCS to reflect clock switching, e.g. for delay_xx(). They can also work for set_uart_speed(). I don't see a clear indication why we shouldn't have multiple #use delay() statements in the present code, although I can imagine that manual settings may be favorable in some cases.


Problem is that with switched #use delay statements, it can first be difficult to know which one is in force for a particular code flow. They do not work quite as you might expect regarding which one is 'in force'. Remember also they do not directly change delays. They change delay timings _as applied at the time of compilation_, not retrospectively. So if you have a delay_ms(100) statement written so that when compiled the compiler last saw a #use delay (clock=20MHz), it'll have the fixed delays inside it, for this clock rate. If you then take a different code route to this point, and have switched clock rates, the delays _won't_ change to reflect the new route.
The same problem used to apply to switching baud rates with #use RS232. A search here will show just how problematic this could be...
If I'm changing clock rates, I use macro based delays, which generate both timings for the two rates, and switch between which one is used depending on a global flag.

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