The 16550 UART calculates the baud rate using formula 115200 divided by the 16-bit number obtained by concatinating the High and Low DL registers. There are several well-known divisors that get you well known baud rates, and are easy to calculate. A baud rate of 9600 is just 115200/12. 57600 is 115200/2, 300 baud is 115200/384, etc... 115200 has 90 integer divisors.

My question, which I don't /think/ is answered in the datasheet, is that happens when you input a value for the divisor that doesn't come out to an integer like, say, 7. 115200/7 = 16457.142....

I can see any one of the following being potential outcomes:

  • The chip attempts to operate at the baud rate specified including fractional timings
  • The divisor is considered invalid, the change is ignored, and the chip continues to transmit at the previous rate (perhaps raising an error?)
  • The baud rate is rounded to the nearest integer (i.e, '7' would result in a baud rate of 16457)
  • The baud rate is rounded to the nearest integer divisor of 115200 (one of the 90, so '7' would result in 14400 baud)
  • Something else I haven't thought of. I know, for example, some datasheets warn about writing '0' to these registers, as 115200/0 is undefined.

I was going to test this on a Raspberry Pi 3, only to discover the UARTs on there aren't real 16550s. I will attempt to test real hardware as soon as I can lay my hands on some, but that may be a while and my little project is stalled until I know the answer. Any ideas?


closed as too broad by Chris Stratton, Enric Blanco, Dmitry Grigoryev, PeterJ, uint128_t Jul 4 '17 at 21:58

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 3
    \$\begingroup\$ It matters not a bit if the baud rate (ie, the quotient) is an integer, as long as sending and receiving rates match within tolerance. However, your title mismatches your question. It's relatively rare, and quite complex, for a chip to be able to handle a non-integer divisor. \$\endgroup\$ – Chris Stratton Jul 2 '17 at 5:25
  • 3
    \$\begingroup\$ A baud rate physically is a frequency: 1/time. If we would not use "seconds" but another unit for time all "common" baud rates would be non-integer. Why do you think a baud rate must be an integer? \$\endgroup\$ – Martin Rosenau Jul 2 '17 at 13:46
  • \$\begingroup\$ @Chris Stratton: I corrected the title. I shouldn't write questions while tired. \$\endgroup\$ – clemej Jul 2 '17 at 15:22
  • \$\begingroup\$ @Martin, being a cheap digital IC, I assumed that complex things like floating point wouldn't be implemented. So fractional clocks wouldn't make sense. I'm guessing I obviously don't understand how this works internally. \$\endgroup\$ – clemej Jul 2 '17 at 15:26
  • 1
    \$\begingroup\$ @clemej You didn't understand the comment: The baud rate is an analogue value just like the volatage. The exact voltage of a circuit will never be 5.000000V but maybe 5.00123V. The same is true for the baud rate. The IC generates the baud rate by dividing the analogue input frequency by an integer divider. If the input frequency is 100 Hz and the divider is 3 the result will be 33.333... Bauds. If the input frequency is 99.999 Hz and the divider is 1 you'll get 99.999 Bauds although the divider is 1! \$\endgroup\$ – Martin Rosenau Jul 2 '17 at 16:31

It might depend on whose 16550 chip you have (though I would expect they are all the same):

The TI datasheet says this in section 8.5.1

The UART contains a programmable Baud Generator that is capable of taking any clock input from DC to 24 MHz and dividing it by any divisor from 2 to 216–1. The output frequency of the Baud Generator is 16 × the Baud [divisor # = (frequency input) ÷ (baud rate × 16)]. Two 8-bit latches store the divisor in a 16-bit binary format. These Divisor Latches must be loaded during initialization to ensure proper operation of the Baud Generator. Upon loading either of the Divisor Latches, a 16-bit Baud counter is immediately loaded. Table 4 provides decimal divisors to use with crystal frequencies of 1.8432 MHz, 3.072 MHz and 18.432 MHz, respectively. For baud rates of 38400 and below, the error obtained is minimal. The accuracy of the desired baud rate is dependent on the crystal frequency chosen. Using a divisor of zero is not recommended.

So you can use any divisor you want with any clock you want. Non-standard baud rates would of course have to match at each end.

  • \$\begingroup\$ Thank you for the answer. I was hoping it was something different. What I'm trying to do is characterize the number states (theoretically) a 16550 UART can be in at any moment. Ignoring FIFO and interrupts, it can have be set to one of 5 parity settings, on of 4 word length settings, and one of 3 stop bits settings. that's 60 possible states. It can also be in DLAB mode or not. That's 5*4*3*2 = 120 states. However, if the chip really and truly does support fractional baud rates, then the number of states is really 120 * 2^(16-1). I was hoping the answer was something smaller. \$\endgroup\$ – clemej Jul 2 '17 at 15:33
  • \$\begingroup\$ Just for more clarity, I'm doing the above because I'm building an AI-based system that attempts to learn a functional model of a 16550 by bit-banging the registers and observing the output, which means it will be hitting all sorts of strange entries in that state space. So I need to know how a real chip will respond. \$\endgroup\$ – clemej Jul 2 '17 at 15:46
  • 1
    \$\begingroup\$ @clemej your project may well be impractical for anyone but the chip designer's ASIC verification engineers. It will certainly be impractical for someone who hasn't studied the functional block diagram of a textbook UART well enough to understand it. You'd be better served picking a different project. \$\endgroup\$ – Chris Stratton Jul 2 '17 at 18:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.