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