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

Different Baud rates using variable clock

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
aopg64



Joined: 17 Oct 2005
Posts: 28
Location: Hampshire, UK

View user's profile Send private message

Different Baud rates using variable clock
PostPosted: Thu Jul 20, 2006 7:12 am     Reply with quote

Hi Guys!

I am using an 18F series PIC and want to use the internal clock at various speeds to throttle the 'horsepower' as and when needed. I would like to be able to get serial (debug) data via the hardware TX/RX pins, but this must stay at the same Baud rate (for my convenience!) It would also be handy to be able to select the clock rate for testing purposes etc but leaving the Baud rate unchanged.

Perhaps I am being thick and there is an easy way of doing it (please enlighten me!) but as the #use rs232(BAUD=.....) is compiled at build, how do I change the Baud rate for a different speed?

If I do:

Code:
#use delay(clock=500000, RESTART_WDT)
#use RS232(BAUD=300, XMIT=PIN_C6, RCV=PIN_C7, BITS=8, PARITY=N, RESTART_WDT)


Will this mean I get:
300 Baud at 500000Hz internal precision clock
600 Baud at 1MHz internal precision clock
....
4800 at 8MHz clock etc????

The above isn't what I want, but perhaps I need to do my own 'printf' routine which does something like this?:

Code:
void myprintf(char *string)
{
switch(ClockSpeed)
{
case CLOCK_500k:
#use delay(clock=500000, RESTART_WDT)
#use RS232(BAUD=300, XMIT=PIN_C6, RCV=PIN_C7, BITS=8, PARITY=N, RESTART_WDT)
printf("%s",string);
break;

case CLOCK_1M:
#use delay(clock=1000000, RESTART_WDT)
#use RS232(BAUD=300, XMIT=PIN_C6, RCV=PIN_C7, BITS=8, PARITY=N, RESTART_WDT)
printf("%s",string);
break;

etc.....

}


Thanks for any advice,

Nigel
_________________
No comment! (Can't think of anything interesting to say!)
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Jul 20, 2006 7:35 am     Reply with quote

Something like your given example code is a possible solution, but when using the hardware UART it is easier to use the function set_uart_speed().
aopg64



Joined: 17 Oct 2005
Posts: 28
Location: Hampshire, UK

View user's profile Send private message

PostPosted: Thu Jul 20, 2006 10:36 am     Reply with quote

Hi ckielstra!

DOH! Embarassed


Thanks for that!! It's obvious when someone points it out! A colleague mentioned this in passing a few weeks ago in another context, but I'd forgotten about it!

My switch-case solution can't work (as intended) because of the lack of real pointers to strings. I found another workaround which helped me learn a few more things about PICs along the way, so my efforts haven't been entirely wasted and thanks to you, this command should now be ingrained in my memory!
Rolling Eyes

Thanks again!

Nigel
_________________
No comment! (Can't think of anything interesting to say!)
aopg64



Joined: 17 Oct 2005
Posts: 28
Location: Hampshire, UK

View user's profile Send private message

PostPosted: Fri Jul 21, 2006 5:10 am     Reply with quote

Hi again!

One issue (the main one!) that set_uart_speed() doesn't address is the variable clock speed. How do I 'tell' the CPU before it does the calculations for the Baud rate what it's clock speed is?

Presumably this comes back to the 'switch-case' where I 'switch' on the clock speed and put a separate #use delay(clock=....) before each set_uart_speed() line?

Thanks for the help so far,

Nige
_________________
No comment! (Can't think of anything interesting to say!)
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Jul 21, 2006 6:17 am     Reply with quote

Read the datasheet. There you will find the SPBRG register. Load this register with the right value and volia.
aopg64



Joined: 17 Oct 2005
Posts: 28
Location: Hampshire, UK

View user's profile Send private message

PostPosted: Mon Jul 24, 2006 7:27 am     Reply with quote

Hi Mark,

Thanks for that. Though it does often seem that in using the CCS 'C' compiler you end up having to do assembler anyway.....either because the function doesn't exist or the functions that do exist don't do what you want...
Rolling Eyes
Luckily I am on that page of the datasheet (!) as I was tweaking the Baud rate so I could serially modify the clock tune value, but keep the Baud rate at roughly 300 Baud so still be able to TX and RX. So effectively doing what you suggest, but in a small way, whereas you are suggesting doing it in a big way.

Thanks again!

Nige
_________________
No comment! (Can't think of anything interesting to say!)
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Jul 24, 2006 7:44 am     Reply with quote

You don't have to do it in assembler. Its just putting a value in a register so certainly C is capable of that.
Ttelmah
Guest







PostPosted: Mon Jul 24, 2006 8:06 am     Reply with quote

It is very easy to do in CCS. All you need is something like:
Code:

   if (clock_is_slow) {
#use delay(clock=500000)
   set_uart_speed(300);
   }
   else {
#use delay(clock=4000000)
   set_uart_speed(300);
   }

Obviously setup for the baud rate, and clock speeds you require.
The 'critical' thing is that the command setting the baud rate, has to be inside the test, with the 'use delay' code. This way, according to the value of the variable 'clock is slow', the code will route to the arm containing the required baud setup. The code actually generated for this (with 'clock_is_slow', as a bitfield stored in address 5.0, is:
Code:

1C2:  BTFSS  05.0
01C4:  BRA    01D0
.................... #use delay(clock=500000)
....................    set_uart_speed(300);
01C6:  MOVLW  19
01C8:  MOVWF  FAF
01CA:  MOVLW  22
01CC:  MOVWF  FAC
....................    }
....................    else {
01CE:  BRA    01D8
.................... #use delay(clock=4000000)
....................    set_uart_speed(300);
01D0:  MOVLW  CF
01D2:  MOVWF  FAF
01D4:  MOVLW  22
01D6:  MOVWF  FAC

So what happens, is if 'clock_is_slow' is true, it puts '19' in the BRG, while if it is false, it puts 'CF' into the same register, exactly as required.

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
Page 1 of 1

 
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