Automatic
Baud Rate Detection for the 80C51 AN447
This
note documents a method to automatically establish the correct baud rate
for
serial communications in many 80C51 family applications. The first
character
received after a program is started is used to measure the baud rate
empirically.
This
can eliminate the need to have setup switches whose settings are
difficult
to remember and all of the other headaches associated with
applications
that use multiple baud rates. One might assume that a reliable
method
of accomplishing this might be impossible without severely limiting the
characters
that could be recognized. The problem is in finding a timing
interval
that can be measured in a large number of possible characters under a
wide
variety of conditions.
Measuring
a single bit time would be the obvious way to quickly determine what
baud
rate is being received. However, many ASCII characters don't have an
example
of a single bit time in the RS-232 pattern. For most characters, the
length
of the entire transmission from the start bit to the last "visible"
transition
will fall within certain ranges as long as some reasonable
assumptions
can be made about the possible baud rates (i.e. that they are
standard
baud rates). Moreover, many systems now use 8 data bits and no parity
for
ASCII transmissions. In this format, normal ASCII characters will never
have
the MSB set and since UARTs send data LSB first/MSB last, the program
would
always be able to "see" the beginning of the stop bit.
The
following baud rate detection routine waits for a start bit (falling edge)
on
the serial input pin and then starts timer 0. At every subsequent rising
edge
of the serial data, the timer value is captured and saved. When the timer
overflows,
the last captured value will indicate the duration of the serial
character
from the start bit to the last 0 to 1 transition (hopefully the stop
bit).
The
table CmpTable contains the maximum timer measurement that is accepted for
each
baud rate. These values were picked such that a timed interval of only 4
data
bit times (plus the start bit time) will still produce the correct baud
rate.
There
is an assumption in this method that anyone using it needs to be aware
of.
That is, that this technique depends on only one character being received
during
the sampling window, which has to be at least as long as a typical
character
at the slowest baud rate that can be accepted. Essentially this
means
that the data must normally come from someone typing at a keyboard.
On
our PCs, we were not able to fool the program by typing two characters in
quick
succession. The PC function keys did present a problem because they send
two
characters in a tight sequence, and fooled the program into detecting the
wrong
baud rate. In the example program, which is designed for a 12 MHz clock,
the
total sample interval is about 65 milliseconds, or about twice the
duration
of an RS-232 character sent at 300 baud.
If
parity is used, a possibility of a baud rate determination error happens
when
the four MSBs and the parity bit of the character received are all ones.
This
can happen for the lower case letters "p" through "z", plus
curly
brackets,
vertical bar (|), tilde (~), and "delete", depending on whether the
system
uses odd or even parity. Note that the usual prompt characters that a
user
would type to get a system's attention (e.g. space, carriage return, and
escape)
are NOT subject to this limitation.
Note
that, because of the way this program works, the first input character
that
is used to detect the baud rate is lost since the UART cannot be set to
the
correct baud rate until after the first character has been timed. Also,
most
"real" programs using this technique would want to repeat the baud
rate
detection
process if framing errors are detected at the UART during normal
operation.
To
calculate CmpTable values for other oscillator frequencies and baud rates,
use
the following equation:
Osc (MHz) 5
Table
entry = ----------- * ----
Baud Rate 12
Remember
that the table entry is a two byte value, so the result of the above
must
be split into upper and lower bytes (easy if you have a hexadecimal
calculator).
It may also be possible to get the assembler to do all of the
calculations
for you.
The
above equation was derived as follows:
maximum minimum recognition time
timer
value = --------------------------
(table
entry) machine cycle time
minimum bits-to-recognize
recognition
time =
------------------- * byte time
#-of-bits
Note:
'#-of-bits' (the number of "visible" bits) is 9, and
bits-to-recognize
(the
minimum # of bits to recognize) is 5 for 8-N-1 communication.
1
byte
time =
----------- * #-of-bits
baud rate
machine Osc frequency
cycle
time =
---------------
12