# How do some microcontrollers implement baud rates even though it uses crystal frequency not scalable to standard baud rates?

I just realized that the 8051 family uses 11.0592 MHz and its multiples so as to generate standard baud rates. But there are SoCs which use 15 MHz. How do they do this then?

• Mostly they use non-power-of-2 divisors to generate rates acceptably close to standard baud rates. – Brian Drummond Nov 20 '16 at 19:33
• what's more, UARTs may oversample the signal (e.g. 16 samples per UART bit), which solves timing (and noise) issues: electronicdesign.com/embedded/… – Florian Castellane Nov 21 '16 at 8:50
• For anyone interested, AVR USART timing error tables are available for common clocks in the datasheet, (in this one on page 168 onwards). – Sebi Nov 21 '16 at 22:32

The UART doesn't care as long as it is reasonably exact.

$\frac{15000000}{230400}\approx65$

$65\cdot230400=14976000$

So your UART is going to be too fast by a factor of $\frac{15000}{14976}\approx1.002204$. It becomes a problem at $1+\frac{1}{2\cdot11}\approx1.045$, when the time shift across 11 bits is more than half a bit.

• Might be worth noting that the transmitter and receiver both have clocks, so if both are in error in the wrong direction.. – Spehro Pefhany Nov 20 '16 at 19:49
• More importantly, the relevant serial protocols (RS-232 etc) use start and stop bits to further synchronize clocks. Even if both sides had perfect 230400 Hz clocks, the two clocks would likely be out of phase. The start bit allows the receiving side to sync its clock to the sender. Since this can happen on the first bit every byte, imperfect clocks just mean more frequent phase adjustments. – MSalters Nov 21 '16 at 12:48
• In practice it is likely to be off by more than this post indicates because the divider system is unlikely to be 100% flexible. – Peter Green Nov 21 '16 at 13:22
• @PeterGreen: That's true; most real UARTs require an input clock that is 16x the baud rate, and the programmable divider must produce the faster clock. In this example, the overall divider would have to be 64 (= 16 x 4), and the error would be $\frac{15 MHz / 64}{230400 baud} = 1.01725$, or +1.7%, which is still an acceptable value. – Dave Tweed Nov 21 '16 at 13:40
• @DaveTweed: But chips serious about async serial tend to allow a supersampling factor of 13 in their serial peripheral, which obtains the nice low error Simon calculated starting with any clock that's a multiple of 3 MHz. Alternatively, some use a fractional divider where the bit time averages out to the correct value even though individual bits might have > 2% timing error. – Ben Voigt Nov 21 '16 at 19:43

Here is the 'big print' features description of a relatively high end ARM MCU.

There are a number of PLLs and dividers with prescalers and postscalers that are capable of creating almost any frequency you might need as an integer ratio. The PLL multiplies its input frequency by some integer, and a divider can divide by some number (not necessarily powers of 2 in each case).

Internal relatively high frequencies (around half a GHz in this case) are not a problem (as they would be if off the chip)- relatively little power is consumed.

The days of division only by powers of 2 ended quite some time ago, and now that PLLs are commonly applied we don't need to worry about the exact crystal frequency nearly as much. On the other hand we may need many different clock frequencies for multiple internal bus clocks, USB, Ethernet, UART etc. peripherals.

If you want to learn more about how these work, you can study some of the dedicated clock synthesis chips which are relatively simple (though still complex enough that some makers supply software to calculate the setup constants).

• (its = possessive, it's = "it is" or "it has". See for example How to Use Its and It's.) – Peter Mortensen Nov 21 '16 at 1:12
• @PeterMortensen Thanks, fixed. For some reason typos like that (and placing incorrect homonyms) are easier to make when in a conversational thinking mode rather than a report writing mode. – Spehro Pefhany Nov 21 '16 at 1:18

This can be achieved using a modulator.

See for example the MSP430x1xx user guide. On page 260 it says:

The USART baud rate generator is capable of producing standard baud rates from non-standard source frequencies. The baud rate generator uses one prescaler/divider and a modulator as shown in Figure 13−7. This combination supports fractional divisors for baud rate generation.

(note the gray area)

The division factor N is often a non-integer value of which the integer portion can be realized by the prescaler/divider. The second stage of the baud rate generator, the modulator, is used to meet the fractional part as closely as possible.

[...]

The BITCLK can be adjusted from bit to bit with the modulator to meet timing requirements when a non-integer divisor is needed. Timing of each bit is expanded by one BRCLK clock cycle if the modulator bit mi is set. Each time a bit is received or transmitted, the next bit in the modulation control register determines the timing for that bit. A set modulation bit increases the division factor by one while a cleared modulation bit maintains the division factor given by UxBR

[...]

A lot of people assume that the UART is actually running on a fixed clock i.e. You take a sample every $T$ seconds. This is not necessarily true. At least not in all the UART modules I've designed.

The way it works is you have an internal sample clock. Say you can sample every 100ns. You know where the middle of each bit is. So, you pick a sampling point that is the closest to the middle. This will give you an error of 50ns at most.

What happens is you receive the start bit. You then determine where the middle of the bit is, that is your referencing point. You then know how long you need to wait to sample the next bit. So, you load up a counter, and when it resets you sample. Now, you will be off by at most 1 clock cycle of your fast internal clock, but that's nano seconds in most cases. Also, you know how much you are off by. For the next bit you load your counter with a different value, so you are as close as possible to the middle, and so on.

In real systems there are a lot of other things that happen too. For example, you don't take one sample, you can take a couple and do some processing on them etc. In effect it is a 1 bit ADC, with all the implications like quantization noise. But you should get the general idea.

Modern SoCs use so-called PLL to generate (almost) any clock that might be needed for interfaces. In simplified terms, the PLL circuit employs a high-frequency VCO (Voltage-controlled oscillator), then uses difital frequency dividers on both VCO and input clock, and generates a voltage feedback based on the frequency ratio. This feedback controls the VCO, such that the entire loop is locked to the desired frequency.

Assuming an 8 bit byte preceeded by a single start bit and followed by a single stop bit and assuming perfect sampling by the receiver that means that after 9.5 bit periods the clock must be off by less than half a bit period.

That means that the maximum tolerable clock difference between transmitter and receiver is about 5%. However there may be error on both ends of the link and the receivers synchronisation may not be perfect. In practice therefore I would generally reccommend that the actual baud rate is kept within 1% of the nominal baud rate.

The microcontrollers i'm most familiar with are the PIC18 devices. The older models of these use a flexible 8 bit counter to scale the baudrate while the newer ones have a flexible 16 bit counter. There are also optional "high" and "low" speed modes which change the baudrate by a factor of four.

With a 20 MHz input clock the 8 bit version of this generation scheme is sufficiant to get within 0.25% of the nominal baud rate for all rates from 1800 to 19200 . The 16 bit version lets you get down to even lower speeds.

http://www.nicksoft.info/el/calc/?ac=spbrg&submitted=1&mcu=+Generic+16bit+BRG&Fosc=20&FoscMul=1000000&FoscAutoSelector=0&MaxBaudRateError=1 (ignore the sync=1 colums, they are for running the USART in synchronous mode)

PLLs, fractional dividers etc are not really needed for UART serial.

To exchange serial data, a controller must output or sample data within a certain window of the "ideal" time. While it is simplest to have a controller which divides a clock by a programmable factor and then again by an additional hard-coded factor, there's no requirement that the bits are read or written at equal intervals. If the far end of a connection outputs bits at precisely uniform intervals matching the baud rate, a receiver can get by with any sampling rate that is greater than twice the baud rate provided it samples things at the right times. For example, suppose data is output at 19,200 and one is sampling at precisely 48,000Hz (2.5x).

When one sees a falling edge, one will know that the stop bit has begun between 0 and 1 sampling times ago. If one labels the first sample where the start bit was observed as time 0, bit 0 will start somewhere between time 1.5 and 2.5; bit 1 will start somewhere between time 4.0 and 5.0, bit 2 will start somewhere between time 6.5 and 7.5, and bit 3 will start somewhere between time 9.0 and 10.0. A sample taken at time 3 will thus be guaranteed to capture bit 0 [which starts between time 1.5 and 2.5, and ends between time 4.0 and 5.0]. Likewise, a sample taken at time 6 will capture bit 1, and a samples taken at time 8, 11, 13, 16, 18, and 20 will capture bits 2-7.

Using a faster sample rate would make the receiver more tolerant of imperfections in the source, but even with a sample rate of just 2.5x the bit rate the margins aren't terrible [about 1/5 of a bit time].