AUTO BAUD RATE DETECTION
by Eddy Carroll, April 1989
Baud > 9600
Baud > 1200 and Baud <= 9600
Baud < 1200
Analysing a Return character
The binary pattern for a RETURN character (0x0D) as transmitted over the
serial line looks like this:
0 1 0 1 1 0 0 0 0 1
| \_____________/ |
| Data bits |
Start Stop
bit bit
(The least significant data bits are always transferred first.)
The time taken to transmit each bit, T, depends on the baud rate.
T19200 = T9600 / 2 for example. Thus, in the time taken to
transmit a single bit at 9600 baud, two bits could be transmitted at 19200
baud.
Similarly,
If two bits are transmitted at 9600 baud, only a single bit can be
transmitted in the same time at 4800 baud. If the receiver is using a fixed
rate of 9600 baud, it will interpret the RETURN character in a variety of
ways, depending on what speed it was transmitted at. The following
table describes this:
Baud Bit pattern received at 9600 baud Byte
19200 01011000011111111111 0xF?
9600 0 1 0 1 1 0 0 0 0 1 0x0D
4800 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0xE6
2400 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0x78
1800 0 0 0 0 0 x 1 1 1 1 x 0 0 0 0 0 1 1 1 1 0xE0
1800 0 0 0 0 0 x 1 1 1 1 x 0 0 0 0 0 1 1 1 1 0xF0
1200 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0x80
600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0x00
300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x00
150 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x00
110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x00
With the exception of the entries for 19200 and 1800 baud, all these bit
patterns are exact transformations of the pattern for 9600. The first ten
bits of each pattern correspond to a complete byte at 9600 baud, and this byte
is listed in the Byte column in the table above.
The absence of a '1'
stop bit in some of the patterns will cause a Frame Error to occur, but
this can be ignored -- the byte received will still be as shown.
Thus, if RETURN is pressed at 1200 baud, the receiver at 9600 baud will receive
the byte value 0x80. All the bytes are unique, so that it is possible
to uniquely determine the baud rate.
19200 is slightly different, since every two bits sent at 19200 baud are
interpreted as a single bit at 9600 baud. The bit pairs 01 and 10 could
be interpreted as either a 0 or a 1, depending on the serial hardware.
Fortunately,
only bits 0-4 exhibit this problem, with the remainder being set to a 1.
Thus, at 9600 baud, the high nibble of the byte received will always be
0xF. The low nibble could be one of several values, but it will not be a 0,
since there is a pair of adjacent 1 bits which will cause at least one 1 to
appear in the low nibble. So, the entire byte will be of the form 0xF?, where
the low nibble is not 0.
At 1800 baud, things are slightly complicated by the fact that T1800
= T9600 * 16/3. Hence, transitions from 0 to 1 do not take place on
bit boundaries with respect to 9600 baud. The table shows that exactly
one such transition occurs within the first 10 bits, and so by allowing
two possibilities (depending on whether the bit at that position gets
interpreted as a 1 or a 0), one of two bytes will be received when
the transmit speed is 1800 baud.
A similar technique could be applied to speeds of 3600 and 7200 but the
number of 'unstable' bits would increase, and result in more combinations
to check. Since baud rates of 3600 and 7200 are almost never used anyway,
this is not a major problem.
Detecting slower baud rates
We can now uniquely distinguish between all the speeds from 19200 to 1200
baud
on the basis of a single byte received. Speeds below 1200 baud however
all return a byte of 0x00, so while we can detect that the speed is below
1200, nothing more can be determined from the byte value alone.
To get around this problem, we simply wait for the next byte to be
received at 9600 baud. Since each bit transmitted at low speeds corresponds
to at least one complete byte at 9600 baud, each transition from 1 to 0
will cause the serial hardware to appear receive a new byte at 9600 baud.
Let's look at the start of our RETURN character again, for rates less than
1200 baud:
Baud Bit Pattern at 9600 baud Delay Time
600 16 0's 16 1's 16 0's 32 3.33 ms
300 32 0's 32 1's 32 0's 64 6.66 ms
150 64 0's 64 1's 64 0's 128 13.33 ms
110 87 0's 87 1's 87 0's 174 18.13 ms
75 128 0's 128 1's 128 0's 256 26.66 ms
50 192 0's 192 1's 192 0's 384 40.00 ms
At 600 baud, the first transition from 1 to 0 occurs immediately, and this
is what triggers off the initial 0x00 byte we receive. The next transition
occurs exactly (16 + 16) * T9600 seconds after the initial transition,
and this will cause the serial hardware to think another byte is about
to arrive.
The serial hardware tells us the first byte has arrived exactly
10 * T9600
seconds after the first transition, and tells us about the second byte
(16 + 16 + 10) * T9600 after the first transition. Hence, the delay
between the first and second bytes arriving when the transmission
speed is 600 baud is (16 + 16 + 10 - 10) * T9600 seconds, which is
32 * T9600 seconds.
The number of T9600 periods which pass is
shown in the Delay column in the table above. T9600
is actually 104.16 microseconds, so multiplying these together gives us
the actual delay in seconds between the two bytes. This is listed in
the final column.
Armed with this information, we can now easily determine the transmission
baud rate: simply time the delay between the arrival of the first
and second bytes, then scan a table of time constants to see which
baud rate it most closely matches. This approach allows the timing to be
a little off while still producing an accurate estimate of the baud rate.
An algorithm for auto baud rate detection
Now that we know how to detect all the baud rates, we can present a complete
algorithm that combines all the techniques just described:
;
; Pseudo code to determine what baud rate a
; transmitter is at, on the basis of a single
; RETURN (0x0D) character received from it.
;
;
Initialise receive baud rate to 9600
Wait for Byte to be received
IF Byte = 0x00 THEN
Start Timer
REPEAT
UNTIL (Timer > 50 ms OR New Byte Received)
CASE Timer IN
1 ms - 4 ms: --> 600 Baud
5 ms - 10 ms: --> 300 Baud
11 ms - 15 ms: --> 150 Baud
16 ms - 22 ms: --> 110 Baud
23 ms - 32 ms: --> 75 Baud
33 ms - 49 ms: --> 50 Baud
ELSE: --> Timed out; reset
END CASE;
ELSIF Byte >= 0xF1 THEN
--> 19200 Baud
ELSE
CASE Byte IN
0x0D: --> 9600 Baud
0xE6: --> 4800 Baud
0x78: --> 2400 Baud
0xE0,0xF0: --> 1800 Baud
0x80: --> 1200 Baud
ELSE: --> Line noise; reset
END CASE
END IF
文章评论(0条评论)
登录后参与讨论