|
|
View previous topic :: View next topic |
Author |
Message |
aopg64
Joined: 17 Oct 2005 Posts: 28 Location: Hampshire, UK
|
Different Baud rates using variable clock |
Posted: Thu Jul 20, 2006 7:12 am |
|
|
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
|
|
Posted: Thu Jul 20, 2006 7:35 am |
|
|
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
|
|
Posted: Thu Jul 20, 2006 10:36 am |
|
|
Hi ckielstra!
DOH!
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!
Thanks again!
Nigel _________________ No comment! (Can't think of anything interesting to say!) |
|
|
aopg64
Joined: 17 Oct 2005 Posts: 28 Location: Hampshire, UK
|
|
Posted: Fri Jul 21, 2006 5:10 am |
|
|
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
|
|
Posted: Fri Jul 21, 2006 6:17 am |
|
|
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
|
|
Posted: Mon Jul 24, 2006 7:27 am |
|
|
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...
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
|
|
Posted: Mon Jul 24, 2006 7:44 am |
|
|
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
|
|
Posted: Mon Jul 24, 2006 8:06 am |
|
|
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 |
|
|
|
|
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
|