View previous topic :: View next topic |
Author |
Message |
maria100
Joined: 01 Feb 2012 Posts: 63
|
Using set_uart_speed |
Posted: Mon Feb 13, 2012 2:42 pm |
|
|
Hello, is possible to use set_uart_speed with non standard baud rates that are generated in real time ? And is possible to use a variable to load them? or I need a numerical value? like : set_uart_speed(32323);
OR
I need to do the math myself, resolve the SPBRG equation, and load the registers with the appropriate value? Thank you!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Feb 13, 2012 3:27 pm |
|
|
No.
Read the manual....
"baud is a constant representing the number of bits per second."
Keyword - _constant_.
The UART calculations are done at compile time, including checking that the rate can be generated without too much error.
Remember you can just use a switch statement to select multiple rates (as shown in the manual...
Problem with variable rates, is that depending where they are, relative to your clock rate, the error amount may easily be outside acceptable limits. Also, on latter chips that support more complex clocking options, several registers may be involved, not just SPBRG...
Best Wishes |
|
|
maria100
Joined: 01 Feb 2012 Posts: 63
|
|
Posted: Mon Feb 13, 2012 3:44 pm |
|
|
Hmmm...please take a look at this thread..what I am missing?
http://pic-c.ccsinfo.com/forum/viewtopic.php?p=66801
You really mean that if i load the registers with the proper value in the running program it wont change the baud? |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
A simple test to try |
Posted: Mon Feb 13, 2012 4:40 pm |
|
|
Hi, it's me again.
Write a short test program which includes some RS232 activity.
Tell the compiler that you want say 4800 baud.
Tell your PC to expect 9600.
When the code runs, change the appropriate registers before using the RS232.
The PC will tell you whether or not the baud rate changed.
Mike |
|
|
maria100
Joined: 01 Feb 2012 Posts: 63
|
|
Posted: Mon Feb 13, 2012 4:53 pm |
|
|
Hi Mike , Well I'm trying to change the registers...just that the compiler generates completely other values than the formula from the datasheet does.
I'm using 18f25k22, 16 MHZ, and have tried to calculate SPBRG for 11171 baud. The formula is telling me 15, and the code generated by CCS is 65.
Code: |
.................... set_uart_Speed(11171);
0A86: BSF FB8.3
0A88: MOVLW 65
0A8A: MOVWF FAF
0A8C: MOVLW 01
0A8E: MOVWF FB0
0A90: MOVLW E6
0A92: MOVWF FAC
|
what's wrong?
SOLVED the register problem , i was using the formula with BRGH=0 , and needed the one with BRGH =1 , now trying to load the registers and test..thanks |
|
|
maria100
Joined: 01 Feb 2012 Posts: 63
|
|
Posted: Tue Feb 14, 2012 10:31 am |
|
|
I have a little problem..how the compiler determines if a specific baud rate is BRGH=0 or BRGH=1 , on what formula? calculating for both and choosing the one with the lowest error? |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
BRGH & SPBRG etc |
Posted: Tue Feb 14, 2012 12:21 pm |
|
|
The data sheet for your selected device shows you how to work it out. If you do the work you can get your code to make the decisions.
It's not just error rate. The BRGH is effectively a prescaler for the baud rate generator when working with RS232. So for some rates you can use either BRGH = 0 or BRGH = 1. Or the error is too high with one setting and SPBRG is >255 for yet other rates. You have to work it out for yourself. It's all there in the data sheet. Some rates are not possible with certain crystals, you have to make a choice.
Mike |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Feb 14, 2012 1:53 pm |
|
|
Quote: |
like : set_uart_speed(32323);
|
But WHY on earth do you need a wildly non standard RS-232 baud rate ??
And what kind of run-time test would be determining that baud rate ??
I've done a LOT of RS-232 related stuff over the past 25 years - but your request is puzzling in the first degree. You want some odd baud rates - YES ok - but auto-baud at some NON 300 baud multiple??????
What device are you going to communicate with that is NOT set up for standard baud rates???
huh ???
The request is not making a lot (read ANY) sense to this fellow at all. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
Baud Rate Calculation |
Posted: Tue Feb 14, 2012 2:40 pm |
|
|
Quote: |
I need to do the math myself, resolve the SPBRG equation, and load the registers with the appropriate value? Thank you!!
|
This is lifted from the 18F458 data sheet (others are similar). There are two formulae
If BRGH == 0
Baud rate = Fosc / ( 64 * ( SPBRG + 1 ) )
If BRGH == 1
Baud rate = Fosc / ( 16 * ( SPBRG + 1 ) )
The range for SPBRG is 0 - 255
If the difference between the actual baud rate and the one required is too large then you start again.
What more do you need?
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Tue Feb 14, 2012 4:15 pm |
|
|
OK.
From your comments, you are using one of the standard parts that just has a single 'multiplier' bit and SPBRG. Relatively simpler. A lot of the newer chips have much more complex multipliers available with larger baud rate generators.
Yes, you can just change the BRG, and change speed. However you need to consider the implications when you change. You will get odd behaviour, if the internal counter is already _past_ the new BRG value loaded. On some chips this is the subject of an erratum, that can lockup the UART. Also, changing the other way, can cause framing errors at both ends if data is in transit (again depends on the chip).
So really the 'safe' way is to verify that the transmit buffer is empty, and that the RX line is high. Then turn off the UART, load the new values, then turn the UART back on.
Then your calculation sequence needs to be:
DIV = Fosc/(Required baud *16)
If DIV>(size of BRG) then switch to BRGH=1, and try
DIV=Fosc/(required baud * 64)
If DIV is still>(size of BRG) then 'impossible' baud rate - error.
Then take (Required baud * 16 * (BRGH*4) * DIV). Compare this result with required Baud. If the two values differ by more than perhaps 2.5%, then you are getting outside the acceptable range of error for reliable async serial.
Best Wishes |
|
|
|